2016. 11. 9. 21:00 :: 문제풀이/WebHacking,kr

안녕하세요. Message입니다.

Webhacking.kr Lv9 문제풀이입니다. 

 

------------------------------------------------------------------------------------------------------------------------------------------

1. 문제분석

------------------------------------------------------------------------------------------------------------------------------------------

 

1) 살펴보기

9번 문제에 접속합니다. 점수는 무려 900점...

숫자 1, 2, 3 과 password 쿼리전송 버튼이 존재하는 페이지가 나옵니다.

다른분들의 풀이를 보니, ID/PW 입력 인증창이 별도로 뜨면서 Method를 이용하여 우회해야 볼 수 있는 화면인데

바로 뜨는거 보니...수정되었나봅니다.

 

각 번호를 클릭하면 각 아래의 화면이 나타납니다.

페이지 넘버 3에서 "Secret" 이라는 문구와 함께 hint가 주어졌습니다.

length = 11, 그리고 column명 2개(id, no) 입니다.

  

 

또한 이것저것 특수문자도 넣어보고, 각종 쿼리문을 날려보았더니

아래와 같은 "Access Denied" 문구가 뜹니다. 특정 문자가 필터링되고 있음을 알 수 있습니다.

 

2) 문제 의도파악

처음에는 "Apple", "Banana"가 ID값이라는 표시가 없어서 페이지들의 목적이나 의미에 대해서 헷갈렸습니다.

결국 다른 풀이들을 찾아본 후에야 저 과일이름들이 ID값이라는걸 알게되었죠..

예를들어 no=1 일때의 ID값은 "Apple", no=2 일때의 ID값은 "Banana",

no=3 일때의 ID값은 알려주지 않으므로 우리가 알아내야할 값은 no=3일대의 ID값인듯 합니다.

 

 

 

------------------------------------------------------------------------------------------------------------------------------------------

2. 문제풀이

------------------------------------------------------------------------------------------------------------------------------------------

 

0) 아파치 웹인증 우회

아파치 웹인증이 나오진 않았지만, 공부하는데 초점이 맞춰져 있으므로 간략하게 짚고 넘어갑니다.

만약 정상적으로 인증창이 나왔다면 아래와 비슷한 창이 나타났을겁니다.

 

이러한 인증은 아파치 서버에서 .htaccess 파일을 이용한 인증을 사용할 경우 나타나는 창으로서,

.htaccess 파일을 이용한 인증을 이용하기 위해서는 httpd.conf 파일에 AllowOverride 설정을 해줘야 합니다.

 <Directory "/var/www/html">

...

AllowOverride AuthConfig

...

 </Directory>

 

설정이 완료되면 .htaccess 파일 내부에 Limit 옵션으로 인증에 적용될 메소드를 기재하게 됩니다.

아래와 같이 설정을 하게 된다면, GET과 POST로 요청이 들어올 경우 아파치 웹인증이 동작합니다.

 AuthName  "~~~"

 AuthType   Basic

 AuthUserFile "~~~~/.htpasswd"

 <Limit GET POST>

requre valid-user

 </Limit>

 

하지만, 만약 관리자가 옵션을 적는 방법을 헷갈리거나, 단순히 GET과 POST 등 일부 메소드만 설정한다면

다른 메소드로 접근하여 인증이 우회되는 상황이 발생합니다.

테스트는 못해봤지만, 아래와 같이 OPTIONS 등의 메소드로 패킷을 보내면 해당 인증창은 무시되고 다음 단계로 넘어갑니다.

 

 

1) 이용할것

일단 주어진 힌트를 살펴봅니다. 만약 ID를 구하는것이 맞다면,

힌트가 의미하는바는 ID의 길이가 11자리이며, 테이블의 컬럼은 id, no 이라는 뜻일겁니다.

 

힌트와 쿼리문을 입력하는 칸을 보니 느낌적으로 Blind SQL 공격을 시도하는게 맞는것 같습니다.

그래서 예전 Blind SQL을 사용했던 2번 문제를 살펴보니 

2번 문제는 Time 주석문을 이용하여 Blind SQL의 결과를 알아내는 케이스였습니다. (아래와 같이요)

하지만 이번 문제는 no, pw 변수에 이것저것 넣어봐도 True/False를 체크할만한 수단이 없어보입니다.

2번문제 링크 : http://redscreen.tistory.com/87

 

어떤식으로 Blind SQL의 성공여부를 알 수 있는지 검색해보니 

MYSQL 쿼리문에서 SELECT문에 IF문을 결합하여 사용하는 방법이 있더군요.

아래는 APMSETUP에서 테스트용으로 IF문과 SUBSTR 함수를 결합하여 사용한 예시입니다.

그렇다면 IF문은 이번 문제에서 어떻게 사용해야 하는걸까요?

 

현재 문제를 풀이하고 있는 페이지는 index.php 입니다.

그리고 no 값에 따라서 보여지는 글자가 달라집니다. 즉, 다른 페이지에 넘어가는게 아니라

입력해주는 no에 따라서 DB에서 ID값을 가져오는 메커니즘으로 추측됩니다.

그렇다면 "SELECT id FROM no = OO" 정도가 되지 않을까요?

여기에 IF문을 아래와 같은 방식으로 적용한다면 우리가 원하는 값을 불러올 수 있습니다.

 SELECT id FROM 테이블명 WHERE no = IF(substr(id, 1, 1) = 0x41, 3, 0)

 

이를 검증하기 위해 테이블에 세가지 튜플을 넣고 테스트합니다.

① (1, Apple)  ② (2, Banana)  ③ (3, aaaaaaaaaaa) / 11자리

 

이후에 위와 같은 쿼리를 날리면 아래와 같은 결과를 얻을 수 있습니다.

 ①번 튜플 : (1, apple )

    - 첫번째 문자 'A' 와 0x41 일치 → no=3 반환 

    - 완성쿼리 : SELECT id FROM lv9 WHERE no=3 : ①번 튜플은 no=1 이므로 출력 NO

 ②번 튜플 : (2, Banana)

    - 첫번째 문자 'B' 와 0x41 불일치 → no=0 반환

    - 완성쿼리 : SELECT id FROM lv9 WHERE no=0 : 번 튜플은 no=2 이므로 출력 NO

 ③번 튜플 : (3, AAAAAAAAAAA)

    - 첫번째 문자 'A' 와 0x41 일치 → no=3 반환 

    - 완성쿼리 : SELECT id FROM lv9 WHERE no=3 : ③번 튜플은 no=3 이므로 출력 YES

 

 

2) 필터링 문자 파악

버프슈트의 Intruder 기능을 이용하여 특수문자 필터링을 파악합니다.

엑셀등에서 복사하여 Paste 버튼을 누르면 편리하게 페이로드 추가가 가능합니다.

Length 448 결과값이 "Access Denied" 응답입니다.

위의 쿼리에서 작성한 쿼리에서 "=", "if", "%20" 등이 필터링되고 있습니다.

 

 

 

3) 공격시도

위에서 작성한 쿼리는 아래와 같습니다.

필터링 되는 문자를 파악했으니 뜯어고쳐야 합니다.

 SELECT id FROM 테이블명 WHERE no = IF(substr(id, 1, 1) = 0x41, 3, 0)

 

문자 "=" 을 사용하지 못하므로 strcmp 함수로 대체합니다.

다른분의 풀이를 보니 LIKE로 대체하신분도 계십니다. 저의 경우 strcmp가 더 손에 익어서 선택했습니다.

strcmp 함수는 문자열이 동일한 경우 0을 반환하므로, IF문의 True/False 순서도 바뀌어야 합니다.

 SELECT id FROM 테이블명 WHERE no = IF(strcmp(substr(id, 1, 1), 0x41), 0, 3)

 

또한 %20 이 필터링 되므로, 공백을 제거해야합니다.

 SELECT id FROM 테이블명 WHERE no = IF(strcmp(substr(id,1,1),0x41),0,3)

 

문제에 테스트해봅니다. 결과는 Secret 입니다.

URL : (생략)../web-09/?no=IF(strcmp(substr(id,1,1),0x41),0,3)

 

테스트 완료된 쿼리를 이용한 파이썬 스크립트로 공격을 시도하면 성공입니다.

0x41 부터 시작할 경우 ID값이 대문자로 출력되는데, 아마 8번 문제처럼 자동으로 소문자화 시켜주는 코드가 있을듯 합니다.

하지만 패스워드에 입력할 시에는 소문자로 입력해야합니다.

 

 

 

By Red_Message.

 

posted by Red_Message