먼저 코드부터 확인해 보자.
간단하게 확인해보면 필터링을 거친 후에 id와 pw에 입력값을 확인한 후 로그인을 시켜준다.
if(preg_match('/prob|_|\.|\(\)/i', $_GET[id])) exit("No Hack ~_~"); // do not try to attack another table, database!
if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~");
preg_match()는 입력된 문자열을 확인한 후, 설정한 옵션 값과 일치하는 패턴이 있는지 확인한다.
위의 코드를 보면 prob이나 일부 특수문자들의 입력을 확인하고 더 이상의 코드 실행을 불가능하게 막는다.
우리는 이 함수를 신경쓰면서 코드 값을 입력하면 될 것으로 보여진다.
$query = "select id from prob_gremlin where id='{$_GET[id]}' and pw='{$_GET[pw]}'";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if($result['id']) solve("gremlin");
필터링을 거친 후, 이상이 없는 경우에는 위와 같은 코드가 실행된다.
해석을 해보면 우리가 입력한 id, pw을 포함한 쿼리문을 페이지에 보여주고난 후에 mysqli_fetch_array
함수를 이용해 쿼리문을 실행시키고 그 값을 result라는 변수에 저장하고
이때 result의 값이 참이라면 풀리는 것 같다.
일단 입력할 수 있는 파라미터 값은 id와 pw가 있다는 것을 알아냈고 또한 result의 값을 참으로 만들 수
있도록 false or ture=true 방식을 이용한 sql injection 구문을 pw의 값에 넣고 실행시켜 보았다.
select id from prob_gremlin where id='{$_GET[id]}' and pw='{$_GET[pw]}' 라는 쿼리문이
1' or '1'='1로 인하여 select id from prob_gremlin where id='hello' and pw='1' or '1'='1' 로
구문이 실행이 되는데 이때 pw의 입력값은 1 또는 1=1이면 or 연산자에 의해 pw의 값은 참이되고 id라는
변수는 입력값만 들어가 있어도 참이 되는 변수이기 때문에 쿼리문은 참이 되어 정상적으로 공격이 성공하게 된다.
나는 그리고 한 가지 더 실험을 해보았는데 id의 값으로도 공격이 가능한지 궁금해서 주석문을 통한 우회도
진행 해보았다.
select id from prob_gremlin where id='{$_GET[id]}' and pw='{$_GET[pw]}'라는 쿼리문이
주석문자인 #에 의해 select id from prob_gremlin where id='admin'#' and pw='{$_GET[pw]}'으로
되는데 이때 데이터베이스는 select id from prob_gremlin where id='admin'만 인식하게된다.
결과적으로 주석문에 의해 id 변수 뒤에 오는 문자열들은 #으로 인해 주석이 되면서 쿼리문이 id만 확인하고
실행시켜주는 모습이 보여졌다.
하지만 데이터베이스에 일치하는 id의 값이 없어서 그런 것인지 admin 외의 id 값은 클리어가 안떴다...
※ 참고
( preg_match 함수 설명 : https://www.php.net/manual/en/function.preg-match.php )
'Web hacking > LOS' 카테고리의 다른 글
[5] WOLFMAN 풀이 (0) | 2022.01.29 |
---|---|
[4] ORC 풀이 (0) | 2022.01.29 |
[3] GOBLIN 풀이 (1) | 2022.01.23 |
[2] COBOLT 풀이 (0) | 2022.01.23 |