1000점이라는 높은 점수가 걸려있는 문제이다.
필터링이 많은것을 제외하고는 그리 어렵지 않은 문제였다.
일단 문제페이지에 접속해보면
HINT : select flag from prob13password
라는 힌트가 존재한다. prob13password 테이블에서 flag 를 추출해내는게 우리의 목표이다.
소스도 존재하지 않아 처음에는 감을 잡기 애매했다. 그러다가 Blind SQLi 라는 힌트를 얻게 되었고
공격을 시도하게 됬다.
일단 쿼리를 전송하는 부분이 어떠한 역할을 하는지 알아보기 위하여 아래와 같은 쿼리를 넣어봤다.
?no=1%0din(1) - 1 표시
?no=1%0din(2) - 0 표시
(=가 필터링되므로 in 을 사용하였다.)
예상대로 참/거짓 판별유무를 표시하는듯하다.
처음에는 워게임 이기 때문에 당연히 하나의 값만이 들어있을거라 생각하고 공격을 시도하여
상당히 많은 시간이 소요됐었다. (하나 이상의 값이 들어있었다..)
여러개의 값들 중 가장 긴 값이 key라고 생각을 하고 max 함수를 이용하여 길이를 알아보았다.
?no=length((select%0dmax(flag)%0dfrom%0dprob13password))in(4)
..?가장 긴 값이 4글자이다..뭔가 이상하지만 계속 진행해보자.
ord(substr((select%0dmax(flag)%0dfrom%0dprob13password),1,1))in(숫자)
...
값을 뽑아보니 flag 라는 값이 나왔다. 인증을 시도했지만 인증이 되지 않았다.
MySQL 콘솔창을 열어서 아래와 같은 실험을 해봤다.
(현재 member 테이블에는 admin 이라는 계정과 test라는 계정이 들어있다.)
SELECT max(id) FROM member -> test
SELECT min(id) FROM member -> admin
이상하게 max 값에 길이가 짧은 test 라는 id가 나왔고, min 값에 길이가 긴 admin id 가 나왔다.
(이 부분에 대해서는 추후에 연구를 하여 자세히 포스팅 하도록 하겠다.)
-> 답은 order by 에 있었다! 직접 콘솔창에서 실험해보길 바란다.
이번엔 min 함수를 이용하여 길이를 알아보았다.
?no=length((select%0dmin(flag)%0dfrom%0dprob13password))in(20)
총 20글자라고 한다.
아래의 페이로드를 통하여 공격을 진행하였다.
ord(substr((select%0dmax(flag)%0dfrom%0dprob13password),1,1))in(숫자)
코드는 내가 올려둔 파이썬 코드를 이용하여 공격을 시도했고, 키를 얻어냈다.
'Wargame(CTF)' 카테고리의 다른 글
Challenge 50 (0) | 2014.07.22 |
---|---|
itchy's Funny injection 풀이 (0) | 2014.06.18 |
Challenge 57 (0) | 2014.06.12 |
Challenge 45 (0) | 2014.06.12 |
Challenge 51 (0) | 2014.06.10 |