Tyojong

[LOS] green_dragon 본문

web/LOS

[LOS] green_dragon

Tyojong 2026. 2. 7. 16:23
<?php
  include "./config.php";
  login_chk();
  $db = dbconnect();
  if(preg_match('/prob|_|\.|\'|\"/i', $_GET[id])) exit("No Hack ~_~");
  if(preg_match('/prob|_|\.|\'|\"/i', $_GET[pw])) exit("No Hack ~_~");
  $query = "select id,pw from prob_green_dragon 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']){
    if(preg_match('/prob|_|\.|\'|\"/i', $result['id'])) exit("No Hack ~_~");
    if(preg_match('/prob|_|\.|\'|\"/i', $result['pw'])) exit("No Hack ~_~");
    $query2 = "select id from prob_green_dragon where id='{$result[id]}' and pw='{$result[pw]}'";
    echo "<hr>query2 : <strong>{$query2}</strong><hr><br>";
    $result = mysqli_fetch_array(mysqli_query($db,$query2));
    if($result['id'] == "admin") solve("green_dragon");
  }
  highlight_file(__FILE__);
?>

 

코드 분석

if(preg_match('/prob|_|\.|\'|\"/i'$_GET[id])) exit("No Hack ~_~");
if(
preg_match('/prob|_|\.|\'|\"/i'$_GET[pw])) exit("No Hack ~_~");

id와 pw파라미터로 들어온 값은 따옴표가 필터링된다.

 

$query "select id,pw from prob_green_dragon where id='{$_GET[id]}' and pw='{$_GET[pw]}'";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(
$result['id']){

입력 받은 파라미터로 id와 pw를 조회하고 id결과가 존재하면

 

if(preg_match('/prob|_|\.|\'|\"/i'$result['id'])) exit("No Hack ~_~");
if(
preg_match('/prob|_|\.|\'|\"/i'$result['pw'])) exit("No Hack ~_~");

출력된 id, pw 결과에 따옴표가 있는지 다시 검사하고

 

$query2 "select id from prob_green_dragon where id='{$result[id]}' and pw='{$result[pw]}'";
$result mysqli_fetch_array(mysqli_query($db,$query2));

결과를 where문에 넣어서 id를 출력시키는 두 번째 쿼리를 실행시킨다.

 

if($result['id'] == "admin"solve("green_dragon");

두 번째 결과에 대한 id값이 admin이면 문제가 해결된다.

 

익스플로잇

?id=\&pw= or 1--+

따옴표가 필터링되기 때문에 역슬래시를 이용해 따옴표를 문자열 처리해 escape한다.

이후 or을 이용해 where구문을 참으로 만들었지만 id값이 존재할 때 나오는 query2의 구문이 보이지 않는다. db에 저장된 계정이 아무것도 없는 것 같다.

 

where 구문이 참이 되어도 출력되는 결과가 없기 때문에 union select 구문을 이용해 결과를 강제로 출력하도록 만들면 된다.

?id=\&pw= union select 1, 2--+

union select로 출력시킨 1과 2가 query2의 where 구문에 들어간 것을 확인할 수 있다.

 

따옴표가 필터링 되기 때문에 union select로 문자를 일반적으로 출력시킬 수 없다.

?id=\&pw= union select char(97), 2--+

char 함수를 사용하면 10진수 값으로 문자를 출력시킬 수 있다.

 

코드를 보면 query2의 where절에 들어가는 값도 동일하게 따옴표가 필터링된다.

때문에 query에서 \를 이용해 우회했던것 처럼 char함수를 이용해 query2에 문자를 넣으면 된다.

 

query2의 pw에 들어가는 부분에  union select char(97,100,109,105,110)-- 를 10진수로 변환해 char()함수로 보내면

 

query2에서는 char(97,100,109,105,110) 이 admin으로 변환되어 union select로 인해 admin이 출력되게 된다.

 

'web > LOS' 카테고리의 다른 글

[LOS] evil_wizard  (0) 2026.02.05
[LOS] hell_fire  (0) 2026.02.05
[LOS] dark_eyes  (1) 2026.02.04
[LOS] iron_golem  (0) 2026.02.03
[LOS] dragon  (0) 2026.01.30