Everyday 챌린지 Web2

챠챠비둘기·2023년 10월 27일
0

web 챌린지

목록 보기
2/4

Session


일단 문제 파일을 다운받고, 사이트로 들어가 보았다.

일단 특이점은 보이지 않는다. 코드를 보자.

from flask import Flask, request, render_template, make_response, redirect, url_for

app = Flask(__name__)

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

users = {
    'guest': 'guest',
    'user': 'user1234',
    'admin': FLAG
}

session_storage = {
}

@app.route('/')
def index():
    session_id = request.cookies.get('sessionid', None)
    try:
        username = session_storage[session_id]
    except KeyError:
        return render_template('index.html')

    return render_template('index.html', text=f'Hello {username}, {"flag is " + FLAG if username == "admin" else "you are not admin"}')

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'GET':
        return render_template('login.html')
    elif request.method == 'POST':
        username = request.form.get('username')
        password = request.form.get('password')
        try:
            pw = users[username]
        except:
            return '<script>alert("not found user");history.go(-1);</script>'
        if pw == password:
            resp = make_response(redirect(url_for('index')) )
            session_id = os.urandom(4).hex()
            session_storage[session_id] = username
            resp.set_cookie('sessionid', session_id)
            return resp 
        return '<script>alert("wrong password");history.go(-1);</script>'

if __name__ == '__main__':
    import os
    session_storage[os.urandom(1).hex()] = 'admin'
    print(session_storage)
    app.run(host='0.0.0.0', port=8000)

session_id의 값에 따라, session_id와 guest와 매칭될 경우 guest로 인식하고 화면을 보여주고, admin과 매칭될 경우 admin으로 인식하고 보여줄 것이라고 예상할 수 있다.

burp suite를 켜서, session_id 브루트 포스 공격을 해보자. 왜냐하면 os.urandom(1).hex()라는 의미는, id는 총 2자리 정도라고 예측할 수 있고, 이정도면 브루트 포스 공격에 취약하기 때문이다.
16진수로 표현되니, 숫자와 문자가 혼합된 형태일 것이라고 추측할 수 있다.


로그인 요청을 중간에 가로채서 intruder로 보내고,

sessionid에 페이로드를 넣어서 총 256번의 브루트 포스 공격을 수행했다.

length 가 다른 값 하나를 찾았다. 아무래도 admin의 sessionid는 이놈인 모양이다.

sessionid값을 19로 바꾸고, 새로고침 했더니 플래그가 나왔다.

Webhacking.kr 39번

Sql injection 문제였다. 일단 페이지에 들어가 보자.

어떠한 값을 입력해서 푸는 문제인 것 같다.

php 태그 부분을 보면, \\는 필터링하고, '는 ''로 문자열을 바꾸는 것 같다. 그리고 입력받을 값은 15자리라는 것을 확인할 수 있다.

 $result = mysqli_fetch_array(mysqli_query($db,"select 1 from member where length(id)<14 and id='{$_POST['id']}"));

이 구문에서, '{$_POST['id']}")); 이 부분에 적당히 값을 잘 넣으면 solve 함수를 실행시킬 수 있을 것으로 보인다.

' OR '1'='1
이런 구문을 넣어도 안돼서, 인터넷을 조금 찾아봤다. id = admin일 시 함수가 실행된다고 한다.
'는 ''로 대체되고, 15자리를 넘어가면 잘리는 특성을 생각해 보자. admin + 무언가 + ' 이런 조합일 것이라고 예상할 수 있다. 이 '무언가'에 공백을 넣어보자. 아래에 mySQL의 특성에 대해 설명한 글이 있다.
링크텍스트
즉, mySQL에서는 a=b가 있을 때, a와 b의 자릿수를 맞추기 위해 공백으로 이루어진 패딩을 넣기 때문에, a =a여도, 같은 것으로 인식한다는 것이다.
15자리를 채우기 위해, 그 사이에 공백을 넣어도 admin으로 인지한다는 의미이다. admin + 공백 9자리 + ' 이렇게 넣어보자. 여기서 '는 ''로 대체되지만,15자리를 초과하면 자르기 때문에 결과적으로 id='admin + 공백 9자리'이렇게 인식되고, mySQL의 특성으로 인해 'admin'과 동일한 값으로 인식한다.
값을 입력해 보면,

성공

profile
개발 + 보안

0개의 댓글