본문 바로가기

드림핵

[드림핵 워게임] simple_sqli_chatgpt

<문제>

 

<풀이>

1. 문제 사이트 및 코드 확인

문제 사이트에 접속하면 처음으로 뜨는 페이지이다.

Login을 클릭해보았다.

 

로그인 폼을 볼 수 있다.

id, password를 입력받지 않고 userlevel만 입력받고 있다.

문제 설명대로 어딘가 이상한 로그인 서비스이다.

 

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'GET':
        return render_template('login.html')
    else:
        userlevel = request.form.get('userlevel')
        res = query_db(f"select * from users where userlevel='{userlevel}'")
        if res:
            userid = res[0]
            userlevel = res[2]
            print(userid, userlevel)
            if userid == 'admin' and userlevel == 0:
                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>'

코드를 확인해보면 로그인 폼에서 입력한 userlevel값을 어떤 쿼리문에 넣어 실행하는지 52행에서 볼 수 있다.

아무런 필터링 없이 단순한 문자열로 구성하고 있으므로 쉽게 sql injection을 시도해볼 수 있을 것 같다.

 

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

19행에서 db에 insert되는 계정들을 살펴볼 수 있다.

우리가 로그인하려는 admin 계정은 userlevel이 0이다.

 

2. 익스플로잇

입력란에 0' and userid='admin 을 입력하여

52행의 쿼리문이 최종적으로 select * from users where userlevel='0' and userid='admin' 으로 완성되도록 했다.

Login 버튼을 클릭하여 요청을 보낸다.

 

 

3. FLAG 획득

플래그가 출력되었다.