# baby-union
>로그인 시 계정의 정보가 출력되는 웹 서비스입니다.
SQL INJECTION 취약점을 통해 플래그를 획득하세요. 문제에서 주어진 init.sql 파일의 테이블명과 컬럼명은 실제 이름과 다릅니다.
## Solution:

Cách Backend xử lý request, cụ thể Vì backend không triển khai bất kỳ filter nào và lấy giá trị từ 2 input truyền vào `uid` và `upw` truyền trực tiếp vào câu query.

Cấu trúc database

Hướng giải quyết như sau: đầu tiên mình sẽ dumb table (xác định table chứa flag ) -> dumb colum (xác định các cột chứa nội dung flag ) -> query và lấy flag thông qua `union select`.
**Dumb table chứa flag**
```
apple' UNION SELECT 1,TABLE_NAME,3,4 FROM INFORMATION_SCHEMA.TABLES;#
```
Ta có thể dễ nhận ra table chứa flag là `onlyflag`.

**Dumb column**
```
apple' UNION SELECT 1,COLUMN_NAME,3,4 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'onlyflag';#
```

Giờ chỉ cần dumb data từ các cột `svalue`, `sflag` và `sclose` sau đó concat => flag
Tuy nhiên ta có thể thấy chỉ có giá trị của các cột thứ tự 1,2,4 mới được render.Vì vậy câu query để lấy data sẽ là:
```
apple' UNION SELECT svalue,sflag,3,sclose FROM onlyflag;#
```

# Type c-j
>php로 작성된 페이지입니다.
알맞은 Id과 Password를 입력하여 플래그를 획득하세요.
## Solution:

Gía trị được gửi đến check.php


Hàm `getRandStr` được gọi và tạo ra một chuỗi random 10 ký tự và gán cho biến `$id`.
Sau đó sử dụng thuật toán mã hóa `sha-1` để mã hóa ký tự 1 và gán cho biến `$pw` .
**Hướng giải quyết như sau:**
Vấn đề là mình phải xác định được giá trị của `input_id` được nhập vào sao cho bằng với biến `$id` và đội dài `input_id` phải là 10.
Vấn đề kế tiếp đơn giản hơn, chỉ cần sử dụng thuật toán mã hóa `sha-1` để mã hóa ký tự 1 và lấy 8 ký tự đầu của chuỗi mã hóa gán cho `input_pw`.
Trong PHP, khi một chuỗi được chuyển đổi thành kiểu số nguyên bằng cách dùng (int), PHP sẽ đọc chuỗi từ trái sang phải.
- Nếu mình nhập một chuỗi bắt đầu bằng chữ cái bất kỳ => 0 khi convert sang int
- Nếu bắt đầu bằng một số nguyên => chỉ các số nguyên được đổi sang int.
Tương tự vậy nếu biến `$id` được tạo từ một chuỗi không bắt đầu bằng số ví dụ "abac134678" thì (int)$id cũng sẽ trả về 0.
**Vì vậy**
Sử dụng chuỗi `ababababab` có độ dài 10 ký tự cho Trường `id`.
Gen hash SHA1 với giá trị là 1

vì chỉ cần 8 giá trị đầu => chỉ cần nhập `356a192b` cho trường `pw`

Gửi một vài lần, ngay khi hàm `getRandStr` tạo một chuỗi ngẫu nhiên với chuỗi bắt đầu bằng chữ thì ta sẽ bypass được và render flag thành công.

# Broken Buffalo Wings
## Description:
>Buffalo wings, also known as hot wings or chicken wings...
## Solution:

Khi truy cập tệp nginx.conf, có thể thấy không có bất kỳ hạn chế nào nếu truy cập trực tiệp /flag.txt.

truy cập `http://host3.dreamhack.games:22303/flag.txt` và lấy flag.

# random-test
## Description:

## Solution:
Dưới đây là src code của chall.

Điều kiện đầu tiên là gía trị của biến `locker_num` không được rỗng, tiếp theo `rand_str[0:len(locker_num)]` sẽ lấy các ký tự của rand_str từ vị trí 0 đến vị trí `len(locker_num) - 1`.
# Broken Is SSRF possible?
## Description:
>?? : 퍼벙-(ssrf 터지는 소리)
## Solution:

Đầu tiên để truy cập `/admin` thì ta phải sử dụng ip phải là `127.0.0.1`, và giá trị của tham số `nickname` được SHA256ing sẽ là giá trị biến flag.

Khi truy cập `/flag` giá trị của tham số `nickname` được gửi kèm trong request sẽ được SHA256ing và so sánh với giá trị của biến `flag` ở trên nếu kết quả là `true` => trả về `flag` mà ta cần tìm để solve chall.
```
@app.route('/check-url', methods=['POST'])
def check_url():
global isSafe
data = request.get_json()
if 'url' not in data: #(1)
return jsonify({'error': 'No URL provided'}), 400
url = data['url']
host = re.search(r'(?<=//)[^/]+', url)
print(host.group())
if host is None: #(2)
print("호스트가 감지되지 않았습니다.")
return "Fail"
host = host.group()
if ":" in host:
host = host.split(":")
host = host[0]
if host != "www.google.com": #(3)
isSafe = False
return "Host는 반드시 www.google.com이어야 합니다."
isSafe = True
result = check_ssrf(url,1)
if result != "SUCCESS" or isSafe != True:
return "SSRF를 일으킬 수 있는 URL입니다."
try:
response = requests.get(url)
status_code = response.status_code
return jsonify({'url': url, 'status_code': status_code})
except requests.exceptions.RequestException as e:
return jsonify({'error': 'Request Failed.'}), 500
```
1) Tại `/check-url` có thể thấy để bypass khối if `(1)` ta chỉ cần gửi dữ liệu theo format json với key name là `url`.
2) Để bypass khối if `(2)` giá trị của `url` sau khi được filter bởi chuỗi regex sau `host = re.search(r'(?<=//)[^/]+', url)` không được none.
- nói sơ qua về chuỗi regex trên thì cụ thể nó sẽ filter ra chuỗi ở giữa `//` và `/`, ví dụ nếu ta truyền http://www.google.com/something thì sau khi filter sẽ còn www.google.com và gán cho biến `host`.
3) Sau đó khối if thứ `(3)` sẽ kiểm tra giá trị của host và
"www.google.com" nếu khác sẽ trả về `"Host는 반드시 www.google.com이어야 합니다."`
Nếu vượt qua các khối if trên giá trị `url` sẽ được truyền vào hàm `check_url` để kiểm tra có phải là một payload thực hiện ssrf không.
```
@app.route('/check-url', methods=['POST'])
def check_url():
global isSafe
data = request.get_json()
if 'url' not in data:
return jsonify({'error': 'No URL provided'}), 400
url = data['url']
host = re.search(r'(?<=//)[^/]+', url)
print(host.group())
if host is None:
print("호스트가 감지되지 않았습니다.")
return "Fail"
host = host.group()
if ":" in host:
host = host.split(":")
host = host[0]
if host != "www.google.com":
isSafe = False
return "Host는 반드시 www.google.com이어야 합니다."
isSafe = True
result = check_ssrf(url,1)
if result != "SUCCESS" or isSafe != True:
return "SSRF를 일으킬 수 있는 URL입니다."
try:
response = requests.get(url)
status_code = response.status_code
return jsonify({'url': url, 'status_code': status_code})
except requests.exceptions.RequestException as e:
return jsonify({'error': 'Request Failed.'}), 500
```
Phân tích qua `/check-url` có thể thấy nếu thành công vượt qua các khối if thì `url` ban đầu được truyền vào sẽ được gửi đi thông qua đoạn code sau `response = requests.get(url,allow_redirects=False)` và ta có thể thực hiện ssrf
Nhưng vấn đề là làm sao để ta có thể chèn ip `127.0.0.1` vào yêu cầu mà host phải chứa `www.google.com` để thực hiện ssrf => ta có thể nhúng thông tin xác thực vào URL bằng `@`.
Bây giờ ta đã có giải pháp, và vấn đề cuối cùng là phải vượt qua được các điều kiện trong hàm `check_ssrf`. Giờ thì ta sẽ vào phân tích hàm `check_ssrf`.
1) chỉ cần checked không >= 3 là ok (nghĩa là 1 payload url không được được gửi quá fail 3).
2) protocol trong url chỉ có thể là `http` và `https`.
3) và tương tự như `check_url()` thì host sau khi filter bởi chuỗi regex giống `check_url()` không được none.
4) và giá trị `host` phải tồn tại.
Tổng hợp lại ta có payload như sau:
```
http://www.google.com:pwd@127.0.0.1/admin?nickname=healtheworld
```

giờ ta đã thành công gán giá trị `healtheworld` được SHA256ing cho biến flag.
Sau đó tiếp tục gửi một request đến `/flag` với tham số `nickname="healtheworld"` để lấy flag. => biến flag sẽ so sánh với `healtheworld` từ request `/flag` được SHA256ing và trả về `true`.
```
DH{please_share_your_idea_okay_good}
```