2016. 11. 4. 23:50 :: 문제풀이/WebHacking,kr

안녕하세요. Message입니다.

Webhacking.kr Lv7 문제풀이 달립니다!

! 빠른 문제풀이 보다는 풀이과정 속에서 이것 저것 배우는것을 목표로 합니다.

 

 

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

1. 문제분석

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

 

7번 문제에 접속합니다.

auth 버튼을 누르면 "Access_Denied!" 창이 뜹니다.

 

개발자도구로 소스코드를 살펴보면,

"<!-- admin mode : val=2 -->" 이라는 주석과 "index.phps" 주석을 볼 수 있습니다.

 

해당 주석에 적힌 내용을 바탕으로 val=2 페이지와 index.phps 페이지에 접속하면 아래와 같습니다.

 

 

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

2. 문제풀이

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

 

소스코드를 쭉 살펴보면

 

우리의 최종 목표는 소스코드의 맨 아래에 있는 "$data[0]==2" 조건을 가진 IF문을 충족시켜서

숨겨진 button을 얻어야 한다는 것을 알 수 있습니다.

 

변수 $data에 값을 할당하려면 DB에서 값을 얻어오는 mysql_fetch_array 함수에

인자로 들어가는 변수 $result에 어떤 값이 들어가는지 살펴봐야 합니다.

변수 $result에 들어가는 값은 아래 소스코드에서 알 수 있듯이

웹페이지 방문자가 입력하는 $go 변수에 어떤 값이 들어가느냐에 따라 달라집니다.

 

또한 특수문자 * / 를 사용할 수 없으며, "--" "2150" "\+" 등의 문자를 사용할 수 없는 제약과

rand() 함수로 인해서, 우리가 제대로 입력을 해도 4/5 확률로 die() 함수가 실행될 수 있습니다.

 

주어진 힌트는 아래와 같이 val=2는 존재하지 않는다와 union을 이용하라는 내용입니다.

 

1) 1차시도

일반적인 union select 공격 쿼리를 날려보았습니다.

"select lv from lv1 where lv=( 1) union select lv ...(생략).. )"

하지만 공백 "%20" 테이블명 "lv" 등에서 필터링되어 접근거부되었습니다.

 

2) 2차시도

가장 시급한것은 스페이스 구문을 사용하지 않고 UNION 쿼리를 날리는것입니다.

구글링을 해보니 스페이스를 사용하지 않는 UNION 구문 예시가 있더군요 ex)  union(select("필드")from("테이블명") 

그래서 2번 문제와 동일하게 MYSQL에서 미리 테스트를 해보고 시도 해보기로 했습니다.

 

일단 평범한 SELECT 문에 UNION 쿼리를 날려 차이점을 살펴보았습니다.

기존에 검색되던 내용에서 추가로 2개의 쿼리가 검색되더군요.

 

그리고 제가 원했던 스페이스가 아닌 괄호로 표현된 UNION 쿼리문을 날려보았습니다.

동일한 결과가 나오는것을 확인합니다.

 select user from user user union(select(password)from(user));

 

그리고 이어지는 테스트는 우리가 푸는 문제에서 주어진대로 WHERE 조건이 추가된 부분에서

공백없이 UNION 쿼리를 입력하였을 경우입니다.

 select user from user where user=('root')union(select(password)from(user));

 

하지만 UNION SELECT의 결과는 앞에 있는 SELECT문의 뒤에 이어진다는 단점이 있습니다.

우리가 원하는건 data[0]에 값2가 들어가는것입니다.

따라서 앞에있는 SELECT의 WHERE에 적절한 값을 넣어주면 검색되는 쿼리가 없을것이고

우리가 넣은 UNION SELECT의 값만 나올것입니다.

 

이제 다음 목표는 결과값에 우리가 얻어야할 숫자 2가 나오는것입니다.

여기저기 구글링을 해보니 UNION SELECT에서 필드명에 숫자를 넣는 예제가 보여서

테스트도 할겸 필드명에 숫자를 넣어보았더니, 아래처럼 제가 넣어준 숫자가 나오더군요.

그리고 임의로 여러가지의 숫자를 넣어봤더니, 넣어준 숫자가 그대로 나옴을 알 수 있었습니다.

 

마지막으로 해결해야할 문제는 테이블명입니다. 우리가 넣어야 하는 테이블명 "lv"는 필터링되는

문자이므로, 동일하게 숫자를 넣어 우회해보려 했지만 오류가 나더군요.

그래서 혹시나? 하고 FROM을 아예 지워서 테스트해보았습니다.

OLLEH! 쿼리가 검색이 되네요

 

해당 내용을 바탕으로 아래와 같이 URL을 작성하여 날려보았습니다.

하지만 여지없는 "Access Denied!"

http://webha...(중략)...web-07/index.php?val=999)union(select(2))

 

이유는 숫자 또한 필터링 되어 있기 때문입니다.

2라는 숫자를 못쓰기 대문에 "1+1", "4/2" 등을 시도해보았지만 역시 실패입니다.

하지만 "-" 가 필터링 되어 있지 않은 부분을 발견하여 아래와 같이 마이너스로 넣어보았습니다.

http://webha...(중략)...web-07/index.php?val=999)union(select(3-1)

 

"nice try" 는 rand 함수에 의해 5/4 확률로 발생하는 문구입니다.

일단 필터링 단계는 지나쳤다는 의미죠.

내부 소스코드에서 아래와 같이 적용될때(rand 결과가 1)까지 F5를 눌러줍니다.

계속 URL 쿼리를 날리면 1/5 확률로 원하는 값을 얻어낼 수 있습니다.

 select lv from lv1 where lv=(999)union(select(2))

 

By Red_Message.

 

posted by Red_Message