🕰️ 풀이 시간 : 7분 (SQL 문법을 알고 있어서, 접근이 다소 쉬웠음)
DATABASE = "database.db"
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()
users
는 길이가 char형 userid
, userpassword
및 integer형의 userlevel
을 열로 사용한다.userid
, userpassword
, userlevel
이 각각 ("guest"
, "guest"
, 0
)과 ("admin"
, (난수), 0
)인 값을 각각의 행으로 삽입한다.@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
을 입력할 수 있는 form이 있다.userid
가 "admin"
이어야 하고, userlevel
이 0이어야 한다.userlevel
을 하나 밖에 입력하지 못한다.userlevel
이라는 변수에 저장됨을 알 수 있다.SELECT * FROM users WHERE userlevel = '{userlevel}'
로 하고,0' AND userid = 'admin
을 채운다.SELECT * FROM users WHERE userlevel = '0' AND userid = 'admin'
이 된다.users
테이블에 있는 행들 중, userlevel
의 값이 '0'
이고, userid
의 값이 'admin'
인 값을 찾아(WHERE
) 출력(SELECT
)한다." 라는 의미이다)🕰️ 풀이 시간 : 3분 (1번 문제와 비슷한 문제였음)
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()
users
는 길이가 char형 userid
, userpassword
을 열로 사용한다.userid
, userpassword
가 각각 ("guest"
, "guest"
)과 ("admin"
, (난수))인 값을 각각의 행으로 삽입한다.@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>'
userid
및 userpassword
를 입력할 수 있는 form이 있다.userid
가 "admin"
이면 된다.admin
계정의 userpassword
를 알지못한다.userid
, userpassword
라는 변수에 저장된다.admin" --
을 채운다.SELECT * FROM users WHERE userid = "admin"
이 된다.userpassword
부분은 생략되냐 생각할 수 있는데, SQL 문법에서 --
표현은 주석을 뜻한다. 즉, 해당 표현 뒤에 있는 문장은 모두 무시된다.users
테이블에 있는 행들 중, userid
의 값이 'admin'
인 값을 찾아(WHERE
) 출력(SELECT
)한다." 라는 의미이다)아직 해결하지 못한 문제. (VM 코인 제한)
아직 해결하지 못한 문제. (VM 코인 제한)
이번에는 기존에 배운 지식을 바탕으로 웹사이트의 취약점을 찾는 실습을 진행하였다. 사실 SQL injection 문제는 유튜브에서 개념을 한 번 본적이 있기도하고, 특히 SQL 문법을 알았던지라 풀기 쉬웠다. 풀면서 느낀점은 최근 채팅 보조 서비스(봇) 운영과 DB를 한 번에 관리한 것과 연관짓자면, form 하나로 모든 DB에 접근 가능하다는 것을 보고, '개발을 할 때에는 이런 취약점도 고려해야겠구나'하고 생각하기도 했다. 다행히도 봇을 서비스 하는 플랫폼에서는 이러한 SQL 인젝션 공격에 대비하기위해 셀렉트 메뉴를 선택한다는 점에서 참 다행이라고 생각된다. 하마타면 모든 DB가 공개될 뻔한 것이니까. 반면에, XSS 문제는 (아직 풀지는 못했지만) 뭔가 JavaScript를 사용하는 문제 같은데, 어떻게 접근해야할 지 감이 안온다. 문제 파일도 보면 cookie를 어떻게 하는 것 같아보인다. 이 문제에 대해서는 동아리 시간에 알아보거나, 따로 공부를 직접 해야할 듯 하다. 그래도, 취약점을 찾아서 정답(플래그)를 찾는 것도 수수께끼를 푸는 것 같아 재미있었다. 그리고, 허점(취약점)을 찾아 정답을 발견하면서 생각해본 점이라면 개발을 할 때에 보안에 대해 신경쓰게 되는 계기가 된 것 같아서 좋았다.