2016. 11. 6. 23:24 :: 문제풀이/WebHacking,kr

안녕하세요. Message입니다.

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

 

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

1. 문제분석

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

 

문제 메인에 접속하면 아래와 같은 문구가 뜹니다.

새로고침을 누르니 카운트가 늘어납니다.

최대치인 70번까지가 시도할 수 있는 횟수인걸까요?

 

 

소스코드를 살펴보니 "<!-- index.phps -->" 힌트가 있습니다.

 

해당 페이지에 접속하면 아래와 같은 소스코드가 나타납니다.

 

 

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

2. 문제풀이

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

 

1) 문제 의도파악

소스코드를 살펴보면 아래부분에

"select id from lv0 where agent='$_SERVEr[HTTP_USER_AGENT]'" 쿼리문의 결과로

"admin" 값이 얻어지면 $solve() 함수가 호출됨을 알 수 있습니다.

 

 

2) 장애물

우리가 원하는 "admin" 값이 나오려면 여러가지 방법이 있습니다.

가장 빨리 생각난건 지난 문제의 해결방법이었던 union을 이용하는 방법입니다.

하지만 이번 문제에서는 preg_match() 함수를 이용하여

"union"을 비롯한 "char, ascii" 등의 문자는 물론, 여러가지 특수문자를 모두 필터링하고 있습니다.

 

3) 이용할것

처음에는 DB를 검색하는 Select 문을 조작해서 어딘가에 있을 "admin" 값을 찾아와야 하나? 싶었습니다.

하지만 그런 방법은 맨땅에 헤딩하는 느낌이 들더군요. "admin"값이 없을수도 있죠.

결국 직접 "admin" 값을 입력해야 한다는 생각이 들었고 union, char 등을 이용한 공격을 시도해보았지만,

시도하면 할수록 필터링이 잘되있다는 깨달음만 얻었지요.

이런 방법이 아닌가 싶다가 PHP 소스 아랫부분을 살펴보니, INSERT문이 보입니다.

위의 쿼리문에 대한 결과가 "admin"이 아닐경우, guest의 접속 여부를 기록하기 위한 쿼리로 보입니다.

 

$ip 변수를 조작하기 보다는, 버프를 이용하여 $agent 값을 변경해야겠다는 생각이 듭니다.

또한 결정적으로 따옴표가 치환되는 부분은 $agent 변수가 아니라 $_SERVER[HTTP_USER_AGENT] 기 때문에

$agent를 변경해도 문제를 클리어할 수 있습니다.

 

4) 공격시도

지난 문제에서 연습한대로 APMSETUP에서 테스트를 수행합니다.

수행하기에 앞서 아래와 같은 절차대로 간단히 필드2개 짜리 테이블을 생성하고 쿼리문을 날려봅니다.

 ① DB

      - DB선택 :  use db이름;

     - 테이블생성 :  create table test(name varchar(20) NOT NULL, passwd varchar(20) NOT NULL);

     - 래코드삽입 :  insert into table이름(필드명1, 필드명2) values(data1, data2); 

 ② PHP

     - DB연결 :  $conn = mysql_connect('localhost', 'root', 'apmsetup');

     - DB선택 :  $db_id = mysql_select_db("mysql", $conn);

     - 질의 :  $query = @mysql_query("insert into test2(name, passwd) values('message', 'admin')";#','guest')");

     - 실행 :  mysql_query($q, $conn);

 

처음에는 PHP 소스코드 형식에 맞추기 위해 다음과 같이 쿼리문을 날렸습니다 message', 'admin')";#

나름대로 아래의 PHP소스상에서 주석처리와 쌍따옴표까지 고려를 한것이죠.

 

하지만 아래와 같이 쿼리문 에러와 함께 DB에서도 오류가 나더군요. 형식이 맞지 않습니다.

쌍따옴표는 PHP소스코드 상에서 문자열을 표시하기 위해 사용된 부분이군요.

이래서 직접 DB에 테스트 하지 않으면, 어떤 오류가 나는지도 모르고 헤메는 경우가 많은듯 합니다.

 

따라서 다음과 같이 수정하여 쿼리문을 날립니다(쌍따옴표 제거) → message', 'admin');#

APM 환경에서는 성공적으로 질의문이 수행됩니다.

 

실제 문제풀이 사이트에 접속합니다.

버프슈트를 이용하여 User-Agent에 테스트 완료된 문자열을 입력해줍니다.

인자수를 맞추어 줘야 하기 때문에, 의미없는 루프백 주소를 추가해서 총 3개의 인자를 넣어줍니다.

message','127.0.0.1','admin');#

이후에 User-Agent를 message 로 조정해서 쿼리를 날리면

"admin" 값을 가져오면서 성공입니다!

 

 

By Red_Message.

posted by Red_Message