KMACTF và nỗi buồn éo làm được gì cả T__T
hế lô ae, lại là mình đây :<
Một lần nữa trong năm mình vẫn ăn hại khi solve rất ít chall trong giải của kma và cũng thx bạn X đã hỗ trợ đề cho mình
Tranh thủ đợi download các bài for các thì bắt đầu với for1 :/
Đề bài như sau
Mình được cho 1 file pcap :v vậy sài "cá mập trắng" để xem gói tin.
chú ý và chỗ mình khoanh vùng
Sắp xếp tăng dần là được,
Mình được cho source như thế này :v
Chúng ta có 2 route cần chú ý là /login và /register
Các giá trị nhận đầu vào đều được tham số hóa nên sẽ không thể inject code được.
Tại route /login nó sẽ kiểm tra user có === 'admin' không :v
cái này thì bypass khá dễ :/ Dễ thấy nếu là Admin sẽ bypass thành công :/
Vậy chỉ còn password thôi :/
khi ta truyền một obj
password={"username":false}
tức là
select * from users from user where password= `username` = false
mysql sẽ tự động so sánh password với giá trị tại column username sau đó so sánh tiếp với false :v
mysql sẽ tự động so sánh password với giá trị tại column username sau đó so sánh tiếp với false :v
Payload của mình
{'user':'Admin','pass':{'username':false}}
-> select * from user = 'Admin' and pass = `username` = falseWeb 3: Flag Holder
Mình được tác giải cho source như sau
Điểm đáng chú ý là route /render.
có các biến template và variable nhận giá trị đầu vào của người dùng. If đầu tiên sẽ check length, nếu độ dài một trong hai biến bằng không thì render ra missing parameter .
If thứ 2 sẽ được vượt qua nếu length nhỏ hơn 20 :v
If thứ 3 sẽ đi qua hàm waf để check xem có các kí tự bị filter không.
Việc sử dụng render_template_string() dẫn đến việc bị khai thác lỗi ssti :/
Tại hàm waf mình thấy các kí tự không được phép, ý tưởng đầu tiên là dùng {% aaa%} nhưng payload mình khá dài cộng với đó set đã bị filter T__T
Chú ý đến string.lower()[:MAX_LENGTH], mình nảy ra ý tưởng nếu một kí tự nào đó từ 1 byte khi đi qua hàm lower() lại thành nhiều byte thì sao, nó sẽ bypass được. Yeah đã có :/
Tải trong phía sau sẽ do mình kiểm soát. nhưng payload chỉ có 10 :/
{FLAG} sẽ được replace thành giá trị flag, thêm nó vô phần template :/ vậy là xong.
from flask import Flask, request, Response, render_template_string
app = Flask(__name__)
FLAG="this_is_FLAG"
MAX_LENGTH=20
def waf(string):
blacklist = ["{{", "_", "'", "\"", "[", "]", "|", "eval", "os", "system",
"env", "import", "builtins", "class", "flag", "mro", "base",
"config", "query", "request", "attr", "set", "glob", "py"]
for word in blacklist:
if word in string.lower()[:MAX_LENGTH]:
return False
return True
@app.route("/",methods=['POST','GET'])
def index():
template = request.args.get("template")
variable = request.args.get("variable")
if not waf(template) or not waf(variable):
return "Try harder broooo =)))"
if len(template) == 0 or len(variable) == 0:
return "Missing parameter required"
if len(template) > MAX_LENGTH or len(variable) > MAX_LENGTH:
return "Input too long"
data = template.replace("{FLAG}", FLAG).replace("{variable}", variable)
return render_template_string(f"""
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>cc</title>
</head>
<body>
<p1> {data} </p1>
</body>
</html>
""",data=data)
if __name__=="__main__":
app.run(port=1234)
lmao hehe
Nhận xét
Đăng nhận xét