[WebSec] Level 4

https://websec.fr/level04/index.php

Information Gathering

Challenge này có chỗ input là id, nhưng không giống như Level 1 là sẽ ra lỗi khi nhập ký tự đặc biệt.

Với giá trị cookie leet_hax0r: Decode base64 ra thì là một dạng json sau khi serialize.

1
a:1:{s:2:"ip";s:13:"116.96.78.101";}

Ý nghĩa của các thành phần đoạn JSON trên là:

a: array sẽ chứa 1 giá trị duy nhất là ip.
ip có độ dài là 2, và có value dài 13 kí tự.

Cấu trúc của Serialize trong PHP có dạng data-type:data.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
BOOLEAN
b:value (value chỉ có giá trị 1 hoặc 0. 1 là đúng, 0 là sai).

STRING
s:size:value (s:5:"12345")

INTEGER
i:value

NULL
N;

ARRAY
a:size:{key:value; (lặp lại key:value đến khi bằng size))}

OBJECT
O:length_object_name:object_name:object_size:{<property>:<value>}

Challenge cho 2 source code, nhưng chú ý trong source 1 là viết ở dạng OOP, có các Magic Methods được dùng như __construct(), __destruct().

  • __construct(): hàm này được gọi khi khởi tạo một đối tượng.

  • __destruct(): hàm này được gọi khi đối tượng bị xoá đi. Khi nó không tham chiếu đến đối tượng deserialize tồn tại.

Source code 1

Source code 2

Quá trình serialize và deserialize diễn ra như hình bên dưới:

Serialize & Deserialize


Exploit

Để ý dòng code ở source 2. Thì giá trị cookie leet_hax0r được encode base64.

Mình sẽ tạo dòng Code giống class SQL để serialize nó.

1
2
3
4
5
6
7
8
<?php
class SQL{
public $query='select username from users where id = -1 union select sql from sqlite_master';
}

$a = new SQL();
echo serialize($a), PHP_EOL; // PHP_EOL: print new line
echo base64_encode(serialize($a));

Sau khi bulid source xong, run code sẽ ra Object và đoạn base64 như sau:

Serialize SQL Object

Vì sao phải dùng UNION để select sql mà không select ở vế trước luôn?

Vì ta để ý source code 2, trong hàm __destruct() chỉ in ra màn hình $row['username']. Nên bắt buộc trong câu query của mình phải select username.

Hoặc có thể dùng câu query gán tên cột cần select bằng username như sau cho gọn:

select group_concat(sql) as username from ...

Copy đoạn base64 thay thế giá trị cookie leet_hax0r, sau đó gửi reuqest:

Cấu trúc câu query được dùng

Kiểm tra xem còn table nào ngoài users không? Kết quả là không còn table nào khác.

Check another table

Mình đoán là Flag nằm ở password, nên sẽ select password ra.

Payload get flag

Got the flag


[WebSec] Level 4
https://dovankha.github.io/2022/07/19/lv4/
Author
Khado
Posted on
July 19, 2022
Licensed under