목록Lord_of_SQL-Injections_I (27)
뉴비에욤
처음으로 시간 좀 걸렸던 더러운 문제.... 입력할 수 있는 id, pw 모두 싱글 쿼테이션으로 포함되어 있지만, 필터링에서 (') 문자가 막혀 버린다. 이래나 저래나 어떤 값을 입력하던 모두 문자열로 인식되어 버리는 문제가 발생한다. 일단 클리어 조건을 보면 id 값이 존재하기만 하면 된다. 힌트는 문자열 내에서 특수 문자를 사용하는 법이다. 다음의 파이썬 예제를 살펴보자. > print "Hello My name is "succubus"" > 오류 난다. 왜냐하면 문자열의 의미하는 (") 안에 또 (")이 사용되었기 떄문이다. 위 같은 문장을 제대로 출력하려면 특수 문자를 써야한다. > print "Hello my name is \"succubus\"" > Hello my name is "succub..
적절한 필터링과 함께, id와 pw 파라미터에서의 싱글 쿼테이션 사용 또한 제한되고 있다. 그리고 클리어 조건은 쿼리 결과 id 값이 존재만 하면 된다.(admin 이던 guest 이던 상관 없음) 사실 이 문제는 PHP의 버전 취약점도 내포한다. PHP 5.3 버전에서는 ereg 함수를 이용하여 문자열을 비교할 때 앞에 널문자가 포함되어 있으면 비교가 되지 않는다. 즉, " ' " 은 필터링이 되어도 " %00' " 은 필터링이 되지 않는다. http://localhost/zombie_assassin_eac7521e07fe5f298301a44b61ffeec0.php?id=%00%27%20or%20id%20LIKE%20%27%%27%23
필터링 부분이 확 줄은 대신에 쿼리에서 pw를 비교하는데 '=" 대신 "like" 연산자를 사용하고 있다. 그리고 쿼리 결과 내 id 값에 따라 "Hello guest", "Hello admin" 을 출력하고 있다. like 연산자에서 비교할 문자열은 정규식을 사용하여 비교하는 것이 가능하기 때문에 비밀번호 각 자리수마다 문자열을 대입해서 결과가 id='admin' 인 것을 뽑아내면 된다.
shit 파라미터를 입력하지 않으면 기본적으로 쿼리 문법이 "from", "prob_giant" 사이에 공백이 없기 때문에 문법 오류가 발생한다. 그런데 클리어 조건을 보면 쿼리 결과가 '1234'면 되는데 이미 "1234"를 select 하고 있다. 따라서 shit 파라미터에 공백을 넣어주면 되는데, "%20, %0a, (), /**/" 전부 다 안된다. 공백을 의미하는 수 많은 문자열 중에 필터링이 안되는걸 골라 넣으면 된다. http://localhost/giant_18a08c3be1d1753de0cb157703f75a5e.php?shit=%0b
필터링이 꽤 여러개 걸려 있다. ' ', 'or', 'and', 'like', '0x', 'substr', 'ascii', '=' 등등이 걸려있다. 이전 darkknight 문제와 비교해서 걸리는건 필터링에 'like'가 추가되었다는 점이기 때문에, 'like'만 우회하면 페이로드는 이전 문제와동일하다. 참고로 'like' 는 'IN" 연산자로 우회할 수 있다.
"substr*", "ascii", "=" 그리고 싱글 쿼테이션(')이 필터링 되고 있다. 이전 문제에서 싱글 쿼테이션을 사용하던 이유는 입력받는 파라미터 값이 쿼리 내에서 싱글 쿼테이션 내에 포함되어 있기 때문이다. 예를 들어 위 소스 내에서 우리가 입력할 수 있는 pw 파라미터는 싱글 쿼테이션 내에 포함되어 있어서, pw 파라미터를 공격하려면 반드시 싱글 쿼테이션을 입력해서 문자열 처럼 인식되지 않게 해야 한다. 그러나 no 파라미터는 아무것도 없기 때문에, no 파라미터를 공격할 때에는 싱글 쿼테이션을 안 써도 된다. 문제는 "substr", "substring" 함수가 전부 필터링이 된다는 점이다. 그런데 사실 두 함수 모두 문자열을 자르기 위해서 사용하는 함수이기 때문에 한 글자씩 자르기만 한다..
'or', 'and', 'substr', '=', 등 자주 사용하던 것들이 필터링 되어 있다. 필터링만 우회하면 기존의 blind sql injection 문제들과 크게 다른점은 없다. 우회 X 우회 O or || and && substr substring = LIKE
id='guest' 값이 고정으로 들어가고, 입력한 pw 다음에 'and 1=0'이 실행된다. 마지막 'and 1=0' 조건이 거짓이 되고 쿼리 내 존재하는 모든 조건이 'and' 연산자로 묶여 있기 때문에 무조건 거짓이 된다. 따라서 뒤에 있는 조건을 실행되지 않게 하면서 id='admin'을 뽑으면 된다. http://localhost/skeleton_a857a5ab24431d6fb4a00577dac0f39c.php?pw=%27%20or%20id=%27admin%27%23
이전 'troll'과 유사한 문제이다. 'admin'을 str_replace 함수를 통해 필터링을 하고 있지만 역시 대소문자 구분에 따른 필터링은 하지 않는다. http://localhost/vampire_e3f1ef853da067db37f342f3a1881156.php?id=AdMin
실행되는 쿼리 결과값이 id='admin' 일 때 클리어 되는 문제지만, 필터링 부분을 보면 'admin' 문자열 자체를 검사하고 있다. 'admin'을 입력해야 하는데, 'admin'을 필터링하고 있으니 말도 안된다고 생각할 수 있지만, 필터링 하는 함수를 보면 'admin' 만큼은 'ereg' 함수를 사용하고 있다. 해당 함수의 가장 큰 문제점은 대소문자 필터링이 불가능하다는 것이다. 즉, 'admin'은 필터링이 되어도 'AdMiN', 'admiN' 등은 필터링이 되지 않는다. http://localhost/troll_05b5eb65d94daf81c42dd44136cb0063.php?id=AdMiN