[Webhacking.kr] old-45

[Webhacking.kr] old-45

old-45는 SQL Injection문제다.

id와 pw를 입력하는 폼이 존재한다.

먼저 필터링과 query를 어떻게 구성했는지 확인해보자.

Challenge 45 SQL INJECTION id : pw : view-source /i",$_GET['id'])) exit(); if(preg_match("/admin|select|limit|pw|=|<|>/i",$_GET['pw'])) exit(); $result = mysqli_fetch_array(mysqli_query($db,"select id from chall45 where id='{$_GET['id']}' and pw=md5('{$_GET['pw']}')")); if($result){ echo "hi {$result['id']}"; if($result['id'] == "admin") solve(45); } else echo("Wrong"); } ?>

id와 pw 파라미터의 값이 모두 존재해야 한다.

id와 pw는 모두 addslashes함수로 인해 싱글쿼터 앞에 \문자가 추가된다.

그리고 mb_convert_encoding함수로 utf-8로 인코딩해주는데 여기서 한 가지 취약점이 발생한다.

이처럼 멀티바이트로 인코딩하는 경우 %a1~%fe 뒤에 \(%5c)가 오면 백슬래시까지 합쳐 하나의 문자로 변환된다.

따라서 싱글쿼터 앞에 %a1~%fe 중 아무거나 넣으면 나중에 추가되는 \로 인해 %a1~%fe+%5c가 하나의 문자가 되고 싱글쿼터가 살아남게 된다.

id와 pw는 admin, select, limit, pw, =, <, > 등이 필터링된다.

admin같은 경우는 hex()나 char() 함수를 사용해서 대체 문자열을 사용하고, =은 like를 사용해서 우회 가능하다.

query는 다음과 같은 구조로 select id from chall45 where id='{$_GET['id']}' and pw=md5('{$_GET['pw']}')

id위치에 새로운 쿼리를 Injection하면 될 것 같다.

위 사항들을 고려하면 다음과 같은 payload를 작성할 수 있다.

?id=%aa' || id like 0x61646d696e%23&pw;=guest

payload를 실행하면 다음과 같이 문제를 해결할 수 있다.

old-45 해결!

from http://pd6156.tistory.com/189 by ccl(A) rewrite - 2021-09-25 01:00:22