4주차_Webhacking 과제1: Dreamhack(simple_sqli)

2023. 10. 5. 16:41SWLUG/web hacking

첫번째 문제

 

 

simple_sqli

로그인 서비스입니다. SQL INJECTION 취약점을 통해 플래그를 획득하세요. 플래그는 flag.txt, FLAG 변수에 있습니다. Reference Server-side Basic

dreamhack.io

 

 SQL Injection 취약점이란?
SQL Injection 취약점이란 웹 해킹 기법 중 하나로 웹 애플리케이션의 뒷단에 있는 Database에 질의(쿼리를 보내는 것)하는 과정 사이에 일반적인 값이 아닌 악의적인 의도를 갖는 구문을 삽입하여 공격자가 원하는 SQL 쿼리문을 실행하는 기법이다. 주로 사용자가 입력한 데이터를 제대로 필터링, 이스케이핑 하지 못했을 경우에 발생한다. 거의 모든 데이터베이스 엔진은 유저 입력이 의도치 않은 동작을 하는 것을 방지하기 위해 escape 함수와 prepared statement를 제공한다.

 

우선 웹서버를 위와 같이 생성하고, 파일을 다운받았다.

 

#!/usr/bin/python3
from flask import Flask, request, render_template, g
import sqlite3
import os
import binascii

app = Flask(__name__)
app.secret_key = os.urandom(32)

try:
    FLAG = open('./flag.txt', 'r').read()
except:
    FLAG = '[**FLAG**]'

DATABASE = "database.db"
if os.path.exists(DATABASE) == False:
    db = sqlite3.connect(DATABASE)
    db.execute('create table users(userid char(100), userpassword char(100));')
    db.execute(f'insert into users(userid, userpassword) values ("guest", "guest"), ("admin", "{binascii.hexlify(os.urandom(16)).decode("utf8")}");')
    db.commit()
    db.close()

def get_db():
    db = getattr(g, '_database', None)
    if db is None:
        db = g._database = sqlite3.connect(DATABASE)
    db.row_factory = sqlite3.Row
    return db

def query_db(query, one=True):
    cur = get_db().execute(query)
    rv = cur.fetchall()
    cur.close()
    return (rv[0] if rv else None) if one else rv

@app.teardown_appcontext
def close_connection(exception):
    db = getattr(g, '_database', None)
    if db is not None:
        db.close()

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'GET':
        return render_template('login.html')
    else:
        userid = request.form.get('userid')
        userpassword = request.form.get('userpassword')
        res = query_db(f'select * from users where userid="{userid}" and userpassword="{userpassword}"')
        if res:
            userid = res[0]
            if userid == 'admin':
                return f'hello {userid} flag is {FLAG}'
            return f'<script>alert("hello {userid}");history.go(-1);</script>'
        return '<script>alert("wrong");history.go(-1);</script>'

app.run(host='0.0.0.0', port=8000)

다운받은 파일 내용은 위와같았다.

 

보자마자 로그인을 시도해봐야겠다는 생각이 들었다.

 

역시나 WRONG 오류가 떴다.

 

아까 파일에 쿼리문을 이용해 문제를 풀어야할 것 같다.

userid, userpassword가 두개가 나와있는데 guest,guest와  admin, 그리고 비밀번호는 숨겨져있다.

일단 guest, guest를 통해서 로그인을 시도해보았다.

 

hello guest라고 뜨면서 로그인되었다.

 

여기서 문제를 풀려면 admin을 통해 로그인을 성공해야할 것 같다.

 

 

배운거를 생각했을때 윗 부분을 이용해서 문제를 풀어야될 거같다는 생각이 들었다.

그리고 아까 문제에 힌트로 있었던 플래그는 flag.txt, FLAG변수에 있다는 내용에 대해 고민을 해봤다.

 

N차시도

 

 

뭔가 py파일에서 잘 해보면 flag.txt 파일이 생성될 거 같다는 생각이 들었는데 안되었다.

 

[ 위에 많은 시도들을 했었는데 간단히 얘기해보자면, 파일안에 내용들을 살펴보면서 login .html로도 바꿔보고 , flag.txt도 링크 끝에 적어보고 여러번의 시도를 해봤지만 아무 결과도 없었다. -- 잘못 짚었다.]

 

그래서 다시 해당 파일로 무언가를 시도하기 시작했다.

 

근데 해당 내용을 보면 userid가 admin이라고 다시 한번 알려주는 내용이다.

이렇게도 해봤는데, 흠 아니었다.

재시도를 해보았다.

 

userid admin에 Error based를 이용해서 풀어야할 거같은데 잘 안된다.

 

 

더이상 풀 방법이 없어서 찾아봤다.

 

찾아보니까 py파일에서 시도할 것이 아니고 login을 통해서 주석처리와 같은 작업을 해줘야했다.

select * from users where userid="" and userpassword="" 이 모양이고 생각했던대로 userid에 admin이 들어가면 된다.

간단하게 userid에 admin 값을 넣고 주석으로 뒷부분을 다 없애주면 된다.

 

나는 이렇게 뜬다.

 

뭘 잘못한건지 다시 시도해봐야겠다.

서버 문제인거 같아서 서버를 다시 생성했다.

 

 

이렇게 flag값이 떴다. 

웹해킹을 처음 공부하면서 헛다리를 참 많이 짚는거 같다.

 

이 과정이 헛되지 않을거라 믿으며 첫번째 문제 끄읏

 

 

참고 학습 자료

 

[dreamhack] simple_sqli 문제풀이 (tistory.com)

 

[dreamhack] simple_sqli 문제풀이

[WEB] simple_sqli 문제풀이 SQL Injection 취약점이란 웹 해킹 기법 중 하나로 웹 애플리케이션의 뒷단에 있는 Database에 질의(쿼리를 보내는 것)하는 과정 사이에 일반적인 값이 아닌 악의적인 의도를 갖

mokpo.tistory.com