---
# System prepended metadata

title: Hack The System - Bug Bounty CTF | HTB CTF

---

# Hack The System - Bug Bounty CTF | HTB CTF

Đây là loạt bài black-box:

Do không mở giải nữa nên mình sẽ chỉ đề cập hướng giải.

## Speed net

Bài này sẽ thiên hướng về graphQL do việc không phân quyền đầy đủ cho những api gọi đến các mutation và query của grapql -> như thường lệ thì ta sẽ dùng nhưng query để list ra hết các Type, Query, Mutation

https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/GraphQL%20Injection

```
__schema{queryType{name},mutationType{name},types{kind,name,description,fields(includeDeprecated:true){name,description,args{name,description,type{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name}}}}}}}},defaultValue},type{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name}}}}}}}},isDeprecated,deprecationReason},inputFields{name,description,type{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name}}}}}}}},defaultValue},interfaces{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name}}}}}}}},enumValues(includeDeprecated:true){name,description,isDeprecated,deprecationReason,},possibleTypes{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name}}}}}}}}},directives{name,description,locations,args{name,description,type{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name}}}}}}}},defaultValue}}}
```

```
{__schema{queryType{name}mutationType{name}subscriptionType{name}types{...FullType}directives{name description locations args{...InputValue}}}}fragment FullType on __Type{kind name description fields(includeDeprecated:true){name description args{...InputValue}type{...TypeRef}isDeprecated deprecationReason}inputFields{...InputValue}interfaces{...TypeRef}enumValues(includeDeprecated:true){name description isDeprecated deprecationReason}possibleTypes{...TypeRef}}fragment InputValue on __InputValue{name description type{...TypeRef}defaultValue}fragment TypeRef on __Type{kind name ofType{kind name ofType{kind name ofType{kind name ofType{kind name ofType{kind name ofType{kind name ofType{kind name}}}}}}}}
```

Ta nhận được các mutation và query như sau:

![image](https://hackmd.io/_uploads/B1ON-zrBge.png)

Đầu tiên thì ta sẽ call query để có thể biết được mail của user admin -> cái này có thể coi là một bug idor cũng được -> Tiếp theo sau khi biết được mail admin ta sẽ gọi mutation devForgotPassword - yêu cầu đối số là email -> api này sẽ trả ra cho ta một các token để resetPassword cho người dùng -> sau đó ta sẽ set được password lại cho admin, tuy nhiên mọi việc chưa dùng lại ở đó sau khi đăng nhập thì ta được yêu cầu xác thực OTP gửi về email admin - và ta không có nó, ta chỉ có duy nhất 1 email mà chall cũng cấp, sau khi test trên người dùng thì mình nhận ra OTP chỉ chạy từ 0000 đến 9999 do đó hoàn toàn có thể brute-force được -> tuy nhiên tác giả đã ngăn chặn brute-force với nginx chắc sử dụng rare limit, và OTP hết hạn sau 5ph cho nên cũng khá khó trong việc verifyOTP. Lúc này khá stuck cho nên mình đi mò mẫm xem các mutation khác có gì không thì chỉ có updateProfile khá là có hope -> ý tưởng suy nghĩ trong đầu lúc này là update để cho xác thực two-factor bị tắt và không có bước verifyOTP nữa, thứ 2 là update mail của admin thành mail của mình, tuy nhiên những đầu vào truyền vào đã được quy định sẵn một Type và không có trường email để truyền, còn tắt bước 2Factor thì chương trình dùng phiên đăng nhập tức là chỉ được gọi cho người dùng chính chủ.

Quay ra thì thấy ngay hint là trong mutation có thể gọi nhiều lần trong 1 request -> do đó mọi việc trở nên dễ dàng, ban đầu thì cũng có suy nghĩ đó, tuy nhiên chưa dùng đến thì đã gặp ngay hint "thơm ngon".

![image-27](https://hackmd.io/_uploads/S1WKVXHSxl.png)

-> Sau khi verify OTP xong -> vào admin và tìm flag trong đó thôi.

## Criticalops

Trang web cho phép đăng kí đăng nhập -> và đăng kí role mặc định là user, nguyên nhân do lộ secret key jwt trong mã nguồn nextjs -> cho nên thay role và nhận flag.

Mấy hình này mình lấy ở: https://github.com/hackthebox/bug-bounty-ctf/tree/main/web/criticalops :v: 

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

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

## Jinjacare

Từ cái tên thì có thể liên tưởng đến SSTI python rồi

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

SSTI vào name để gen chứng nhận tiêm covid là win.

## Neovault

Chương trình chứa một bug IDOR và một bug old api chưa bị loại bỏ.

Đề bài cho mình một account để login và mặc định nó có 100 đô ban đầu, và có một khoản giao dịch từ một người dùng nào đang cầm flag.

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

Đây là danh sách các api mà chương trình dùng.

Old api ở:

![image](https://hackmd.io/_uploads/HJ-UiMrHlx.png)


Khi chuyển thành version 1 thì nó vẫn hoạt động và yêu cầu phải có `_id` của người dùng truyền vào: id này là định danh của người dùng để trả tra tất cả giao dịch dưới dạng pdf của người dùng có id đó - và nó là id của mongoDB được gen mặc định.

Tìm xung quanh có thể thấy id của người lạ chuyển cho mình tiền bị lộ:

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

-> Lấy id này và gọi api download transaction ở trên để xem được các lần giao dịch của admin kia.

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

Sau đó thì ta thấy hint của tác giả là brute-force weak uuid trong mongodb vì nó sẽ theo một format riêng. Tuy nhiên ở đây mình chuyển tiền trực tiếp cho user_with_flag ở trên (vì mình có 100 đô mà:v):

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

Sau đó lại dùng api để xem các lần giao dịch để lấy được id của user -> download transaction của họ và nhận flag.

## Novaenergy

Bug broken access control(BAC):

ứng dụng web lộ api swagger:

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

Chương trình chỉ cho đăng kí với một domain mail -> tuy không có mail đó thì ta cũng có thể register với test@novaenergy.com

Dir discovery phát hiện `/api/docs` -> /userDetails có thể truy vấn thông tin user với email -> gửi request đến /userDetails với email đã đăng ký (test@novaenergy.com) -> API trả về thông tin user kèm verifyToken -> request đến /api/email-verify -> truyền verifyToken vừa lấy -> Email được xác minh thành công -> sau đó login thì give away flag.

## Sattrack

Đây là một bài khá hay về prototype polution 2 XSS tuy nhiên cũng không quá khó.

Khi thực hiện login thì chương trình sẽ load res từ api config để trả về đường dẫn script của js login -> tuy nhiên thì hàm merge không an toàn gây nên bug pp:

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

Tuy nhiên chương trình có csp nhưng với unsafe inline ta có thể bypass được. Mặc định chương trình sẽ lấy JS_FILES sau đó tạo thẻ script sau đó gán src value là đường dẫn kia -> src self thì nếu ta load 1 file js ở ngoài để xss thì không được.

Chức năng đăng nhập có một phần share -> nơi đó nó luôn trả về một string -> lúc này ta control để src=javascript:alert, thì hoàn toàn gây ra XSS -> gửi req cho bot(admin) -> nhận token với phiên admin -> login và nhận flag(lưu ý là phải escape nháy đôi).

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


## Citismart

Như ở trên mình nói đây là bài mình chưa giải được vì không xác định đúng ip nội bộ hay ip local host để khai thác.

Mình có thấy một vài ip active và brute 65k port cũng không khả thi, ngoài ip localhost:80 là hoạt động thì mình chưa brute ip localhost thêm.

Chương trình có api bị lộ trong các đường dẫn js sau khi next build.

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

Và api này cho phép ta truyền 1 url và sector -> server sẽ gửi requets đến url đó nếu timeout 5s trả ra kết quả thì gắn thêm vào cho sector trong /api/dashboard/metrics

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

Thử truyền url đến host của mình thì server sẽ tự động nối thêm route /metrics vào -> ta có thể dùng fragment để nó không gửi thêm phần thêm vào này đi.

Sau khi scan port phía localhost thì thấy port 5984 mở -> và nó trả ra nội dung như này:

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

Thì ta có thể đọc docs để biết các truy vấn các điểm cuối và dùng loại nosql db là CouchDB này:

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

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

Không khó đúng không chỉ do là black-box nên nếu suy nghĩ sáng tạo thì sẽ rơi vào các rabit hole mà mình cũng không ngờ thôi :v: 

Thank-u for watching.


~~Note: mấy ảnh mình lấy ở đây vì instance tắt hết rồi~~

https://github.com/hackthebox/bug-bounty-ctf