limit 에서 sql injection이 발생하는 특이한 구조이다. 설명은 아래 글을 참고하길 바란다. SQL Injection in MySQL LIMIT
[MySQL] SQL Injections in LIMIT
·
SQL Injection
mysql limit 함수에서 sql injection 공격 하기 셀 수 없을 정도로 많은 문서들이 SQL Injection(이하 SQLI) 공격 기법을 다루고 있다. 이 글은 굉장이 특이한 상황에서의 SQLI 기법을 다루고 있다. 특정 응용프로그램에서 SQLI를 테스트 할 때 간단한 인터넷 검색만으로 풀 수 없는 경우가 있었다. 바로 MySQL 5.x 버전에서 LIMIT 함수가 SQLI 공격 기법에 취약한 경우였다. 예제 쿼리 “SELECT field FROM table WHERE id > 0 ORDER BY id LIMIT injection_point” 위 쿼리에서 중요한 점은 해당 쿼리에 “ORDER BY”가 사용되었다는 것이다. MySQL 에서는 “UNION” 전에 “ORDER BY”를 사용할 수..
los - dark eyes
·
Lord_of_SQL-Injections_I
이전 iron golem 문제와 비교해봤을 때 크게 달라진 점은 에러 처리 부분과 필터링 부분이다. 이전에는 에러가 나면 에러를 보여주고 종료했으나 이번에는 에러가 나면 그냥 빈 페이지로 돌아간다. 그리고 필터링에 'if', 'when'이 추가되어 조건문은 사용하지 못한다. 공격문은 그냥 조건문 없이 blind sql injection 하듯이 작성하면 되지만, 문제는 쿼리 성공/실패 판단 부분이다. 즉, 쿼리가 실패하면 빈 페이지로 리턴 되고, 성공하면 위 사진에서 해당 쿼리가 보여지게 될 것 이기 때문에 쿼리 성공시 항상 위 페이지에서 보여지는 아무 문자열이나 기준으로 잡아서 판단하면 된다. > 리턴 페이지에서 해당 문자열이 보이면 성공, 안 보이면 실패
los - iron golem
·
Lord_of_SQL-Injections_I
필터링은 신경 쓰지 않아도 되지만 문제는 에러 처리 부분이다. 만약 쿼리 에서 에러가 발생하면 에러를 보여주면서 쿼리가 종료되게 코딩되었다. 즉, error based blind sql injection 기법을 이용해야 한다. 쿼리 내에서 에러를 발생시킬려면 조건문을 사용해야 한다. > if (쿼리문,참일때 값,거짓일 때 값) 위 조건문에서 이용할 형식들은 다음과 같다. - 쿼리문 : substr 함수를 이용하여 pw를 한 글자씩 자르고 비교 - 참일 때 : 한 글자씩 자르고 비교한 값이 맞으면 변수에 저장 - 거짓일 때 : 한글자씩 자르고 비교한 값이 다르면 에러 발생 - 에러 발생을 위한 쿼리문 : ( select 1 union select 2) - 참 거짓 비교 방식은 간단다. 에러가 나면 페이지에..
los - dragon
·
Lord_of_SQL-Injections_I
신경 쓸 만한 필터링은 없지만, 쿼리 내 존재하는 주석 때문에 pw 부분이 실행되지 않는다. 주석은 일반적으로 해당 라인에 위치한 것을 인식하지 않기 때문에, 다음 라인에 공격 코드를 작성하면 된다. 따라서 주석을 우회하기 위하여 개행 문자("%0a")를 입력 후 pw에 공격 코드를 입력하면 다음 라인에 공격 코드가 저장되고 실행되어 문제가 클리어 된다. http://localhost/dragon_51996aa769df79afbf79eb4d66dbcef6.php?pw=%27%0d%0a%20or%20(id%20=%20%22admin%22)%20limit%201,1%23
los - xavis
·
Lord_of_SQL-Injections_I
정규식을 사용하기 못하게 "regex, "like" 을 필터링하고 있다. 클리어 조건을 보면 pw를 체크하는 것으로 보아 blind sql-inecjtions 문제라는 것 또한 확실하다. 얼핏 보면 굉장히 쉬운 레벨이기도 하지만 문제는 db에 저장된 pw(비밀번호)에 있다. 저장된 비밀번호가 무려 한글이다. 즉, 일반적으로 blind sql injection은 pw를 한글자씩 자른 후 비교하는것인데 pw를 한글로 저장하면 맞춰야 하는 가지수가 굉장히 많아진다. 이번 문제는 한글에서 발생할 수 있는 모든 조합을 리스트에 넣어놓고 해당 리스트를 한글자씩 잘라서 비교하는것이다.
los - nightmare
·
Lord_of_SQL-Injections_I
진짜 거지 같았던 문제... 필터링은 둘째 치고 길이 제한이 걸려있다. 그것도 진짜 짧은 6글자... 문제는 '#' 주석도 필터링 되서, 다른 주석으로 바꾸면 5글자가 되고, 괄호가 있으니 괄호 닫으면 4글자, 그리고 싱글 쿼테이션도 닫아야 하니 ' 까지 입력하면 여유분은 딱 3글자 남는다. 이번 문제는 mysql 기본 기능인 auto type cast 를 이용하는 것이다. http://localhost/nightmare_be1285a95aa20e8fa154cb977c37fee5.php?pw=%27=1);%00 ''=1 는 false false는 0 pw=0 ============================== pw가 string이면 int랑 비교하면 string이 0이 됨 'Abc' = 0 '1abc..
los - succubus
·
Lord_of_SQL-Injections_I
처음으로 시간 좀 걸렸던 더러운 문제.... 입력할 수 있는 id, pw 모두 싱글 쿼테이션으로 포함되어 있지만, 필터링에서 (') 문자가 막혀 버린다. 이래나 저래나 어떤 값을 입력하던 모두 문자열로 인식되어 버리는 문제가 발생한다. 일단 클리어 조건을 보면 id 값이 존재하기만 하면 된다. 힌트는 문자열 내에서 특수 문자를 사용하는 법이다. 다음의 파이썬 예제를 살펴보자. > print "Hello My name is "succubus"" > 오류 난다. 왜냐하면 문자열의 의미하는 (") 안에 또 (")이 사용되었기 떄문이다. 위 같은 문장을 제대로 출력하려면 특수 문자를 써야한다. > print "Hello my name is \"succubus\"" > Hello my name is "succub..
los - zombie assassin
·
Lord_of_SQL-Injections_I
적절한 필터링과 함께, 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
los - assassin
·
Lord_of_SQL-Injections_I
필터링 부분이 확 줄은 대신에 쿼리에서 pw를 비교하는데 '=" 대신 "like" 연산자를 사용하고 있다. 그리고 쿼리 결과 내 id 값에 따라 "Hello guest", "Hello admin" 을 출력하고 있다. like 연산자에서 비교할 문자열은 정규식을 사용하여 비교하는 것이 가능하기 때문에 비밀번호 각 자리수마다 문자열을 대입해서 결과가 id='admin' 인 것을 뽑아내면 된다.