HITCON 2018 One Line PHP Challenge
這是 orange 出的 one line php,每年他都會出一題這樣的題目,這一題主要用到的是 session.upload_progress 的利用
1 |
|
P.S. This is a default installation PHP7.2 + Apache on Ubuntu 18.04
session.upload_progress
- enabled
若是在session.upload_progress.enabled=On
(/etc/php/7.4/apache2/php.ini 中) 的時候,會把上傳檔案時的一些資訊存在 session 裡面 (session 位置 /var/lib/php/sessions),所以就可以在 LFI 的時候派上用場 - cleanup
有個session.upload_progress.cleanup
打開以後,只要文件一上傳完成,就會把這個 session 檔案刪掉 - name、prefix 除此之外,name 是個可以控的東西,只要在 POST 的時候帶上這個東西,就可以成功控制這個 name,而這個 prefix + name 就會是存 session 時的 key 值,在文件裡有詳細說講到
1
2session.upload_progress.name = "PHP_SESSION_UPLOAD_PROGRESS"
session.upload_progress.prefix = "upload_progress_"
session
- auto_start
session.auto_start=On
若開著,那就會自己產生 session,但若是沒有的話就會需要 callsession_start()
,default 是關掉的 :(,但是若是你帶上 PHP_SESSION_UPLOAD_PROGRESS 和 PHPSESSID,那它就會幫你開 session - session.use_strict_mode
如果這個是 Off 的時候 PHPSESSID 是可以自己定義的Experiment
1
2
3
4<?php
$vul = $_GET['file'];
include ($vul);
?>
1 |
|
Problem
回到題目本身,先實驗看看 session 的運作 (先把 clenup 關掉方便觀察)
1 |
|
題目會去讀檔案內的開頭,雖然檔案名稱在 upload_progress_*** 後面的部分已經可以控了,還是有前面的 prefix 需要處理,這裡可以用 base64 多次處裡來去掉,base64 只會處理它能夠處理的字,不能處理的就會被忽略,所以若把一個字串多次 decode 到最後這個字串就會消失。
- 像是以 orange 解裡面的字串為例子,
upload_progress_ZZ
decode 一次剩下 hikY 四個正常字,再 decode 一次就沒有剩下可以 de 的了,所以做三次 decode 就會讓整串字消失要注意每次做完都要是 4 的倍數,不然會吃到我們想要保留的 payload,所以這裡才用 ZZ 這個字串,因為它剛剛好1
2
3
4
5
6decode
"��hi�k��Y"
decode
"�)"
decode
""
最後就可以利用這方式,先把 payload encode 三次,前面加上 ZZ (要注意 payload 裡面不能有 = ,所以需要再做一些 padding),原本想錯了,想成後面 payload 會影響 decode 需要的次數,但其實不用,感謝 splitline 糾正。
1 |
|
還有因為沒開 auto_start 也沒有用 session_start,但剛剛已經提過了不是問題,而它有開 session.upload_progress.cleanup
,所以就會需要 race condition 比快了
最後是 orange 的 exploit
Ref
HITCON 2018 One Line PHP Challenge
https://wiiwu959.github.io/2021/10/22/2021-10-22-HITCON_2018_One_Line_PHP/