---
description: >-
  Câu chuyện về picoCTF 2021 và dân chơi noob bị lừa :< vô làm web mà có tích
  hợp crypto, re,... :|
---

# \[Web]picoCTF 2021

### GET aHEAD

Link chall: [http://mercury.picoctf.net:34561/](http://mercury.picoctf.net:34561/)

Đề bài cũng nói ra được cách làm.

Mở `burpsuite` mở challenge lên và click chọn màu ĐỎ/XANH và thay đổi method `GET/POST` thành `HEAD` và đọc gói tin gửi về sẽ thấy flag.

> `picoCTF{r3j3ct_th3_du4l1ty_8f878508}`

![flag](https://505951426-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MU2nUAEHNSUPPDjO7Z8%2F-MXlcQBhtEgccpxj18Ex%2F-MXlet_vBOzixG0opicp%2Fimage.png?alt=media\&token=da4e7e66-630f-45e4-b9dc-74b38a9b76a4)

### Cookies

Link chall: [http://mercury.picoctf.net:29649/](http://mercury.picoctf.net:29649/)

Nhập vào 1 loại cookie thì sẽ được redirect đến /check và value của cookie `name` sẽ thay đổi theo thứ tự của mảng cookie đó phía server.

Mình thử sửa giá trị cookie `name` thành 7, 8, 9 gì đó thì sẽ in ra màn hình 1 loại cookie. Vậy nên mình quyết định tăng giá trị đó từ từ. Limit của mình lúc đó là 20, nếu đến 20 vẫn chưa có thì mình sẽ viết script chạy :v Nhưng may mà mới 18 đã thành công.

> `picoCTF{3v3ry1_l0v3s_c00k135_a1f5bdb7}`&#x20;

![thay đổi giá trị cua cookie name](https://505951426-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MU2nUAEHNSUPPDjO7Z8%2F-MXlcQBhtEgccpxj18Ex%2F-MXliIO3k1KNVJGV9YBj%2Fimage.png?alt=media\&token=c689a77f-f4e3-42b3-b716-2c96c36d810d)

### Scavenger Hunt

Link chall: [http://mercury.picoctf.net:39698/](http://mercury.picoctf.net:39698/)

Bài này mình từng gặp lúc practice :v cứ đi theo manh mối có được xem các file html, js, css, robots.txt,...

> `picoCTF{th4ts_4_l0t_0f_pl4c3s_2_lO0k_fa04427c}`

![index.html](https://505951426-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MU2nUAEHNSUPPDjO7Z8%2F-MXlcQBhtEgccpxj18Ex%2F-MXlixIUs2LTCJZcYf4A%2Fimage.png?alt=media\&token=56527009-bb0e-4371-bc40-274b18124fa8)

![mycss.css](https://505951426-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MU2nUAEHNSUPPDjO7Z8%2F-MXlcQBhtEgccpxj18Ex%2F-MXlj3n-gyvz062QYCg5%2Fimage.png?alt=media\&token=2a516026-e51d-4264-bd1e-80fa0682045c)

![robots.txt](https://505951426-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MU2nUAEHNSUPPDjO7Z8%2F-MXlcQBhtEgccpxj18Ex%2F-MXljBnOfcBNydkIWcpu%2Fimage.png?alt=media\&token=cf0cf1b6-3f17-4250-bb55-487e6cee6277)

![.htaccess](https://505951426-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MU2nUAEHNSUPPDjO7Z8%2F-MXlcQBhtEgccpxj18Ex%2F-MXljWsqsFxPDREUBsks%2Fimage.png?alt=media\&token=d2215b28-2192-4521-aedb-2efb094d0e3d)

Tới lúc này mình có hơi khựng vì chưa dùng Mac bao giờ :< may mà nhanh trí đi hỏi 1 anh senpai có kinh nghiệm code Mac lâu năm :v

![.DS\_Store](https://505951426-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MU2nUAEHNSUPPDjO7Z8%2F-MXlcQBhtEgccpxj18Ex%2F-MXljjpfNWgHQ67pkttK%2Fimage.png?alt=media\&token=48f2edeb-97cc-4ce9-bd0a-05c222a7d413)

### Some Assembly Required 1

Link chall: [http://mercury.picoctf.net:36152/index.html](http://mercury.picoctf.net:36152/index.html)

Lúc này mình có hơi dại vì gòi coi source code, decode đoạn js các kiểu thì thấy có 1 file Web Assembly nhưng mà từ đầu dùng dev tool mở tab sources ra thì có lẽ tiết kiệm 1 khoảng thời gian :v

Flag nằm luôn trong file đó đỡ phải đọc code.

> `picoCTF{d88090e679c48f3945fcaa6a7d6d70c5}`

![flag nè](https://505951426-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MU2nUAEHNSUPPDjO7Z8%2F-MXlcQBhtEgccpxj18Ex%2F-MXllD6zci6LhFzMNqhG%2Fimage.png?alt=media\&token=aa83eea3-0c97-4cbc-9b22-798e0b6d6f6e)

### More Cookies (after-en&#x64;**)**

Link chall: [http://mercury.picoctf.net:34962/](http://mercury.picoctf.net:34962/)

Link reference: [https://crypto.stackexchange.com/questions/66085/bit-flipping-attack-on-cbc-mode](https://crypto.stackexchange.com/questions/66085/bit-flipping-attack-on-cbc-mode)

Source code lượm được

{% code title="bitflip.py" %}
```python
from base64 import b64decode
from base64 import b64encode
import requests


def split(word):
    return [char for char in word]


def bitFlip(pos, bit, data):
    raw = b64decode(data).decode("utf-8")

    data = split(raw)
    data[pos] = chr(ord(data[pos]) ^ bit)
    raw = ''.join(data)
    return b64encode(raw.encode())


currentCookie = ""

for i in range(128):
    for j in range(128):
        c = bitFlip(i, j, currentCookie).decode("utf-8")
        cookies = {'auth_name': c}
        r = requests.get("http://mercury.picoctf.net:25992/", cookies=cookies)
        if "picoCTF{" in r.text:
            print(r.text)
            break
        print(c)
        print("no_oke")
```
{% endcode %}



### Super Serial

Link chall: [http://mercury.picoctf.net:2148/](http://mercury.picoctf.net:2148/)

Truy cập vào `robots.txt` thấy chặn truy cập đến `/admin.phps` thì phản xạ mình nghĩ đến việc thêm `s` vào `/index.php` và quả thật nhận được source code tại đây.

![source index.phps](https://505951426-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MU2nUAEHNSUPPDjO7Z8%2F-MYFedEDE4dDnNmo4Z3p%2F-MYFfuA6tNj-C85rHZn7%2Fimage.png?alt=media\&token=592f01bf-8b3b-465c-ad01-1c12895727a0)

Lúc này mình biết sự tồn tại của `/cookie.php` và  `/authentication.php` . Việc của mình là thêm s vào để đọc được source của 2 file.

Mình để ý ngay đến chỗ `unserialize` vì đây là chỗ nhạy cảm dễ có lỗi để khai thác.

![unserialize, decode base64 và decode url cookie login](https://505951426-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MU2nUAEHNSUPPDjO7Z8%2F-MYFedEDE4dDnNmo4Z3p%2F-MYFgz5YWl7wp4PLHqBl%2Fimage.png?alt=media\&token=a0fec235-6308-4270-9b89-745e9cf6fcff)

Đi đọc source 1 hồi thì mình thấy thêm `magic function __toString()` (tự trigger mỗi khi khai báo object) trong file authen. Ở function này mình thấy nó trả về content của bất kì file nào mình truyền vào. Nhớ lại 1 xíu hint là flag đang ở đường dẫn `../flag` .

![đọc file](https://505951426-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MU2nUAEHNSUPPDjO7Z8%2F-MYFedEDE4dDnNmo4Z3p%2F-MYFjG2mIWBo9ZvdIPWA%2Fimage.png?alt=media\&token=539700ce-03d0-48d8-974c-735ce43384a4)

Từ 2 source code trên và từ hint mình tạo một serialize rồi lần lượt đi base64encode, urlencode.

![serialize object và gán biến log\_file là path đên](https://505951426-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MU2nUAEHNSUPPDjO7Z8%2F-MYFedEDE4dDnNmo4Z3p%2F-MYFk-QRo6aRDWpYFPrx%2Fimage.png?alt=media\&token=f611bece-4bd0-4018-8a58-83f9bc2f6c29)

Sau khi encode: `TzoxMDoiYWNjZXNzX2xvZyI6MTp7czo4OiJsb2dfZmlsZSI7czo3OiIuLi9mbGFnIjt9`

Cuối cùng mình có thể gửi 1 request đến `authentication.php` với cookie login là đoạn encoded trên.

> `picoCTF{th15_vu1n_1s_5up3r_53r1ous_y4ll_8db8f85c}`
>
> Giải thích thêm: Request đến authentication.php, trong đây có include cookie.php, đoạn cookie mình vừa gửi cookie.php sẽ xử lý decode và unserialize, vì vốn object của mình là access\_log nên không gọi được method is\_guest thì liền quăng lỗi ra để catch, trong catch error có in object access\_log nên lúc này hàm \_\_toString được gọi trả về giá trị đó chính là nội dung của file ../flag.

![flag](https://505951426-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MU2nUAEHNSUPPDjO7Z8%2F-MYFedEDE4dDnNmo4Z3p%2F-MYFke0zGPWTYOx7GW3F%2Fimage.png?alt=media\&token=1412a9bc-8473-48d3-bd43-e8bd4a3fd2a2)

### Who are you?

Bài này sửa hàng loạt các giá trị của các trường theo pico yêu cầu:

![](https://505951426-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MU2nUAEHNSUPPDjO7Z8%2F-MZSpPu1Rqg0b5D971cp%2F-MZStc1rRduMzBhY3jvs%2Fimage.png?alt=media\&token=08e0da15-eaa4-4191-a615-c6fbbf203c2f)

> User-Agent: PicoBrowser
>
> Referer: http://mercury.picoctf.net/
>
> Date: Wed, 21 Otc 2018
>
> X-Forwarded-For: 2.16.66.0
>
> Accept-Language sv

![](https://505951426-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MU2nUAEHNSUPPDjO7Z8%2F-MZSpPu1Rqg0b5D971cp%2F-MZStz9ckn1LyHAEXK1N%2Fimage.png?alt=media\&token=9b2cba4e-d00c-4191-bae6-5ea7a5b93ac4)

> **`picoCTF{http_h34d3rs_v3ry_c0Ol_much_w0w_8d5d8d77}`**

### It is my Birthday

Lần đầu đọc đề thì liền có suy nghĩ submit 2 file PDF khác nhau nhưng có hash MD5 giống nhau.

Để làm 2 file có cùng hash mình thấy hơi khoai nên suy nghĩ đơn giản hơn xíu là có nội dung hash giống nhau. Lúc này đầu mình liền nhảy số đến **MAGIC HASHES MD5** in PHP.

> Reference: [https://github.com/spaze/hashes/blob/master/md5.md](https://github.com/spaze/hashes/blob/master/md5.md)

Lúc này mình tạo 2 file pdf nhưng nội dung bên trong là 2 chuỗi có hash bằng nhau:

![](https://505951426-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MU2nUAEHNSUPPDjO7Z8%2F-MZSpPu1Rqg0b5D971cp%2F-MZSy4G1Sbxd3Th_C7mf%2Fimage.png?alt=media\&token=7ba94a1f-87f3-4be4-9c8e-9ed4f55a81dd)

Sau khi up thì chúc mừng "trùng khớp với ý pé"

![](https://505951426-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MU2nUAEHNSUPPDjO7Z8%2F-MZSpPu1Rqg0b5D971cp%2F-MZSyCgweKKav_nhla0e%2Fimage.png?alt=media\&token=5dfc4332-473d-402a-ad80-4e28a6fcc7df)

> **`FLAG: picoCTF{c0ngr4ts_u_r_1nv1t3d_aad886b9}`**&#x20;

### Most Cookies

Bài này có cho ta source code, ngồi phân tích 1 xíuuuu

> **Workflow của flask session:**&#x20;
>
> * \<data> + \<secret key> --e-n-c-r-y-p-t-->  server session stored
> * \<client cookie> + \<secret key> --d-e-c-r-y-p-t--> server session compared

Đọc source code thì secret key là 1 chuỗi random của 1 mảng cho sẵn:

![](https://505951426-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MU2nUAEHNSUPPDjO7Z8%2F-MZSpPu1Rqg0b5D971cp%2F-MZT-ngZ2zwalpl-dsCo%2Fimage.png?alt=media\&token=81d69d4b-cecf-4378-b773-db33e23f2a4a)

Đọc thêm xíu thì biết được endpoint mà ta cần để lấy flag:

![/display](https://505951426-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MU2nUAEHNSUPPDjO7Z8%2F-MZSpPu1Rqg0b5D971cp%2F-MZT0Q4nn9XMXQK6d5lI%2Fimage.png?alt=media\&token=4f1e51cf-ecc2-4736-9892-05198c091024)

Khi truy cập vào web thì ta được cấp cho 1 cookie là session có giá trị {very\_auth: blank}

Giờ việc của mình sẽ là tìm ra một secret key để generate cookie có giá trị **{very\_auth: admin}**

Ok bắt tay vào làm mình tìm được một công cụ là **flask-unsign**.

> Reference: [https://pypi.org/project/flask-unsign/](https://pypi.org/project/flask-unsign/)

![(mình decode cookie ban đầu)](https://505951426-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MU2nUAEHNSUPPDjO7Z8%2F-MZSpPu1Rqg0b5D971cp%2F-MZT2Ziv_YQVU84s4p4Q%2Fimage.png?alt=media\&token=86e7089f-f358-4b48-96a3-acd77ebba603)

Công cụ này hộ trợ unsign một cookie và cho mình biết secret key (default sẽ là wordlist của nó, mình có thể bỏ wordlist của mình - mảng cookie trong source)

![](https://505951426-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MU2nUAEHNSUPPDjO7Z8%2F-MZSpPu1Rqg0b5D971cp%2F-MZT4_2jMHK5y1sirg72%2Fimage.png?alt=media\&token=d01f6c60-acac-4f56-9e8b-acfbe10c8ea0)

Mình đã tìm ra secret key giờ mình dùng tool này generate 1 cookie **{very\_auth: admin}**!!!!!!!

![](https://505951426-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MU2nUAEHNSUPPDjO7Z8%2F-MZSpPu1Rqg0b5D971cp%2F-MZT5MgGMebSB9Tz74yb%2Fimage.png?alt=media\&token=eee68ba5-cfcd-48e6-8b5d-e8d7c6a2d4a7)

Okieeeee giờ modify cookie rồi request đến /display.

![](https://505951426-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MU2nUAEHNSUPPDjO7Z8%2F-MZSpPu1Rqg0b5D971cp%2F-MZT5IZaFG86j0_ASPYl%2Fimage.png?alt=media\&token=473d0355-6506-4d0a-90be-1d6ca394ce73)

> **`Flag: picoCTF{pwn_4ll_th3_cook1E5_3646b931}`**&#x20;

### Web Gauntlet 2

Ở bài này ban đầu nhìn vào SQLite và mớ filter của nó thì có làm mình hoang mang và bí ý tưởng 1 thời gian. Nhưng may mình từng gặp 1 dạng bài SQLite trước đây và có sử dụng || để ghép chuỗi nên mình mới kịp thời quan lại cuộc chơi =)))))

![filter](https://505951426-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MU2nUAEHNSUPPDjO7Z8%2F-MZUF9W3rVQsU4kgu_F5%2F-MZVqx7R3EnrC3iQRHK7%2Fimage.png?alt=media\&token=5a42f0ad-eef2-4c78-bcfa-7cd1a8c2a063)

Payload đầu tiên của mình:&#x20;

> **Username:** ad'||'min
>
> **Password:** ad'||'min

![](https://505951426-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MU2nUAEHNSUPPDjO7Z8%2F-MZU1JZUlg2gHA2_qSPy%2F-MZU2aCr_9QASFW1OXj4%2Fimage.png?alt=media\&token=2946e28e-a4c0-4776-a69d-c81eddd8600e)

Pass được filter rồi nè, nhưng phải tìm được password? :< Tính comment đoạn sau mà không được cả!

Sau 1 hồi vắt óc thì trong đầu mình suy nghĩ ra biến tất cả thành 1 chuỗi rồi sau đó sử dụng 1 hàm để chỉ lấy 5 ký tự đầu (admin) và làm cho từ đọan AND... mất đi!

Ban đầu mình đi kiếm hàm left() nhưng có vẻ sqlite không có @@ nên thôi quay sang đi kiếm hàm substring thì ở sqlite có 1 hàm là substr().

Với nhiều lần thử đi thử lại mình đã tìm được payload hợp lý nhất:

> **Username:** `'||substr('ad'||'min'||`
>
> **Password:** `,1,5)||'`&#x20;

![](https://505951426-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MU2nUAEHNSUPPDjO7Z8%2F-MZU1JZUlg2gHA2_qSPy%2F-MZU5hri_hbPI1YU1Rch%2Fimage.png?alt=media\&token=21deb0eb-5ead-46bc-94cd-de71cafd52e1)

Mình mất 10s lag lag không hiểu chuyện gì đã xảy ra? Rõ là đúng mà sao không thấy flag thì sau 10s hết lag mới nhìn ra cái alert success! :> Vào filter.php kiểm tra ngayyy

> **`FLAG: picoCTF{0n3_m0r3_t1m3_e2db86ae880862ad471aa4c93343b2bf}`**

### Web Gauntlet 3

Câu này mình mất khá nhiều thời gian, xem cheat sheet, đọc doc để tìm ra cái-gì-đó-mới-mẻ.

![](https://505951426-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MU2nUAEHNSUPPDjO7Z8%2F-MZUF9W3rVQsU4kgu_F5%2F-MZVvnu617hK6AIP9Ezd%2Fimage.png?alt=media\&token=d90626e4-b1bf-4df5-85cd-86f66e076448)

Vì sự giới hạn độ dài nên mình thất bại ở payload trên và khiến mình có suy nghĩ giờ username chỉ có thể dùng ad'||'min thôi và password phải đoán đúng hoặc cách nào đấy cho password luôn đúng! Và thế ý payload đầu mình nghĩ ra ngay lúc đó:

> **Username:** ad'||'min
>
> **Password:** ' LIKE '%

Tất nhiên là không được! `like` đã bị lọc :< Thế là mình tìm 1 function nào đó tương tự! Và mình mất cả ngày không thu thập được gì :> Ơ tự nhiên trong đầu nghĩ ra 1 cách search:

![sqlite like vs](https://505951426-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MU2nUAEHNSUPPDjO7Z8%2F-MZUF9W3rVQsU4kgu_F5%2F-MZVzKj0G5Qz-UAm_xPY%2Fimage.png?alt=media\&token=d1704060-65af-4ddd-83d5-e43f609596f1)

\=")) lụm phải vàng nên bắt đầu mình tìm hiểu các cách sử dụng operator khác như `=`, `match` và `glob`. Mình cuối cùng cũng tìm được `glob` là phù hợp nhất thay thế `like` và thay vì dùng '%' and '\_' wildcards thì glob dùng UNIX wildcards. PAYLOAD lúc này của mình:

> **Username:** ad'||'min
>
> **Password:** 'GLOB'\*

![](https://505951426-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MU2nUAEHNSUPPDjO7Z8%2F-MZUF9W3rVQsU4kgu_F5%2F-MZW-x2ZrBhovtDLhnHk%2Fimage.png?alt=media\&token=40c3e85d-07ca-41b5-9af9-beab5332594b)

Thành công thì vào /filter.php check flag thôiiii

> **`Flag: picoCTF{k3ep_1t_sh0rt_6fdd78c92c7f26a10acd3ece176dea4d`**

### X marks the spot&#x20;

