Summry
|
Challenge 02는 다음과 같습니다.
가장 난해하고 어려웠던 문제인 만큼 가장 마지막으로 풀게 되었습니다.
먼저 많은 페이지들 속에서 다음과 같이 Board 게시판과 Admin 페이지를 찾을 수 있습니다.
Board 게시판에서 "No"라는 파라미터를 GET 방식으로 전송하고 있기 때문에 처음에는 이 곳을 Injection Vector로 지정하고 공격하였지만 실패하였습니다. 공격을 소모시키기 위한 함정인 것 같습니다.
메인 페이지의 HTTP Request Header를 보면 Cookie에 다음과 같이 "time"이라는 값이 들어가 있는 것을 확인 할 수 있습니다.
이 값은 시간에 따라 변하는 것이 아니라 고정되어 있습니다. 그리고 메인 페이지의 소스에도 다음과 같이 주석으로 날짜 관련된 값이 적혀 있는 것을 확인 할 수 있습니다.
그러나 둘 사이의 상관 관계가 조금 다릅니다. 년, 월, 일, 분, 초는 다 일치하지만 시간이 조금 다릅니다. 이 Cookie 값을 변경하면 주석의 시간도 바뀌는 것을 확인 할 수 있습니다.
해당 Cookie값에 " time=1451463119'(싱글쿼터) " 처럼 마지막에 싱글쿼터를 삽입하고 Response를 받으면 날짜 관련 주석문이 출력되지 않는 것을 확인 할 수 있습니다. Cookie에 SQL Injection Vector가 있을리는 없는데... 검색을 해보니 Cookie-Based SQL Injection이라는 용어가 있었습니다.
GET이나 POST 방식으로 파라미터를 받을 때 Server Side에서 전역 변수 형태로 받게 되면 GET, POST, COOKIE를 구분하지 않고 받게 됨으로 GET, POST에만 방어를 구축해 놓은 Server는 취약하게 된다는 공격 기법입니다. 자세한 설명은 해당 블로그를 참고하시기 바랍니다. (http://egloos.zum.com/eyestorys/v/2889555)
이런 공격 기법이 있지만, 해당 문제에서는 100% 일치하지는 않는 것 같습니다. 문제가 약간 부자연스럽게? 느껴지지만 어쨌든 Cookie의 time 값이 SQL Query에 들어가고 어떤 방식에 의해서 특정 날짜가 출력되고 있습니다.
이번에는 정말로 SQL 구문이 실행되는지를 확인하기 위해 다음과 같은 Query를 전송합니다.
1 | time=1451463119 and (select 1)=1 | cs |
해당 쿼리를 보내면 소스 코드에서 다음과 같은 주석문을 확인 할 수 있습니다.
이 것으로 실제로 SQL 구문이 실행된다는 것을 확인 할 수 있었고, 이번에는 다음과 같이 강제로 False로 만들어진 Query를 전송합니다.
1 | time=1451463119 and (select 1)=2 | cs |
이번에는 다음과 같은 주석문을 확인 할 수 있습니다.
자세히 보면 초 단위가 다른것을 확인 할 수 있습니다. True일때는 "01초", False일때는 "00초" 입니다. 이 것으로 Blind SQL Injection을 수행할 수 있게 되었습니다.
그러나 테이블명이나 Column명에 대한 힌트나 정보가 아무것도 없기 때문에 데이터베이스의 메타데이터를 제공하는 information_schema를 이용해서 테이블명과 Column명을 찾아야겠다는 생각을 하게 되었습니다. (자세한 설명은 해당 글을 참고 : http://limjunyoung.tistory.com/4)
그러나 위의 글에서 나온 방법으로 모두 공격을 해보지만 실패하였습니다. information_schema를 SELECT할 수 없게 막아놓은 것 같습니다. 아니면 제의 실력이 부족할 수도 있지만...
information_schema 공격을 시도하다가 다른 분의 글을 조금 참고하니, 예전에는 해당 테이블명과 Column명을 힌트로 주었다고 합니다. Board 게시판의 테이블명은 "FreeB0aRd" (게시판 제일 위에 해당 문구로 힌트를 주었던 것 같습니다.), admin 페이지의 테이블명은 "admin"이고 각 테이블의 패스워드의 Column명은 "password"라고 합니다.
예전에는 힌트를 주었고 지금은 힌트를 안 준것을 보니 테이블명을 구하는 방법이 있을 것 같긴 한데, 잘 모르겠습니다. 혹시 알고 계시는 분은 댓글 남겨주시기 바랍니다.
테이블명과 Column명을 알아 냈으니, 다음과 같이 기존의 문제들과 동일한 방법으로 Blind 공격을 진행하면 됩니다.
1 | time=1451463119 and (select length(password) from FreeB0aRd)=10; | cs |
위와 같은 Query로 Column의 글자 수를 알아내고, 다음과 같은 Query로 password를 한글자 씩 알아냅니다.
1 | time=1451463119 and (substr((select password from FreeB0aRd),1,1))=char(97) | cs |
"FreeB0aRd" 테이블의 패스워드를 알아내면 암호가 걸린 "manual.html" ZIP 파일을 다운로드 받을 수 있고, "admin" 테이블의 패스워드를 알아내면 ZIP 파일의 암호를 알아낼 수 있습니다. 최종적으로 "manual.html" 파일을 열어 보면 최종 인증 코드가 출력됩니다.
테이블명과 Column명을 자력으로 알아낼 수 있다면, 좀더 좋은 문제였겠지만, 그러지 못해 약간 난해한 문제였던것 같습니다.
'WarGame > webhacking.kr' 카테고리의 다른 글
[webhacking.kr] Challenge 13 :: Blind SQL Injection 4 (0) | 2015.12.30 |
---|---|
[webhacking.kr] Challenge 09 :: HTTP Basic Authetication (0) | 2015.12.29 |
[webhacking.kr] Challenge 57 :: Time-Based Blind SQL Injection (2) | 2015.12.29 |
[webhacking.kr] Challenge 30 :: 파일 업로드 취약점 3 (.htaccess) (0) | 2015.12.25 |
[webhacking.kr] Challenge 28 :: 파일 업로드 취약점 2 (.htaccess) (0) | 2015.12.25 |