https://dreamhack.io/wargame/challenges/343/
you need login with "admin"s id!
===========================
create table tmitter_user(
idx int auto_increment primary key,
id char(32),
ps char(32)
);
Abstract
SQL의 문자열 자료형인 char
(고정형 문자열)과 varchar
(가변형 문자열)의 차이를 이용하여 중복 검사를 우회하는 문제입니다.
Analysis
문제의 설명으로부터 데이터베이스의 구조를 파악할 수 있습니다. tmitter_user
테이블에 id
과 ps
가 각각 아이디와 패스워드를 저장하고 있는 컬럼일 것입니다. 문제에서 지시하는 대로 아이디가 admin 계정으로 로그인해야 합니다.
서버에 접속해보면 Sign in과 Sign Up의 두 가지 기능이 있습니다. Sign in은 평범한 로그인 기능이고, Sign Up 페이지의 소스 코드에서 힌트를 하나 얻을 수 있습니다.
admin
으로 가입을 해야 된다고 합니다.
Exploit
char vs varchar
이 문제의 핵심은 tmitter_user
의 id
와 ps
컬럼의 자료형이 일반적으로 사용되는 varchar
(가변형 문자열)가 아니라 char
(고정형 문자열)라는 것입니다. char
자료형으로 문자열을 저장하면 미리 설정된 길이(이 문제에서는 32)보다 짧은 문자열의 경우 나머지 공간이 공백으로 채워지고, 긴 문자열의 경우 뒤쪽이 잘리게 됩니다.
char
자료형의 특징을 이용하기 위해서는 아이디와 패스워드에 설정되어 있는 maxlength="32"
속성을 해제해야 합니다.
HTML 코드를 수정하여 아이디의 maxlength
속성을 제거해주면 됩니다.
Join as admin
정상적인 상황에서 admin
으로 가입하려고 하면 이미 존재하는 아이디라는 메시지가 뜨면서 가입이 되지 않습니다.
select * from tmitter_user where id='admin'
등의 쿼리문을 실행하여 이미 존재하는 아이디인지 검사하는 로직이 존재할 것입니다. 아이디의 maxlength
속성을 제거한 뒤, 공백 27개 뒤에 admin
을 붙여서 회원가입을 시도할 경우, 마찬가지로 admin
은 이미 존재하는 아이디라는 메시지를 볼 수 있습니다. 따라서, 아이디가 중복되는지 검사할 때는 입력한 아이디를 32자리에서 자르지 않고 그대로 사용한다는 것을 알 수 있습니다.
아이디에 admin
뒤에 공백 27개, 그리고 아무런 문자(예를 들어 a
)나 하나 추가해서 입력하게 되면, admin a
이라는 아이디는 데이터베이스에 존재하지 않기 때문에 회원가입에 성공할 것입니다. 그러나 데이터베이스에 들어갈 때는 32자리에서 잘려서 admin
으로 들어가게 됩니다.
정리하면 다음의 순서로 익스플로잇이 가능합니다.
- 아이디의
maxlength
속성을 삭제 (최대 길이 제한 해제) - 아이디에
admin a
(admin
+ 공백 27개 +a
) 입력, 패스워드는 임의로 입력하고 회원가입 - 아이디에
admin
, 방금 설정한 패스워드로 로그인 - 플래그 획득