문제
풀이
문제는 ID 와 PW 의 입력을 받는 페이지로 시작한다.
당장 확인할 수 있는 것들이 없으므로, 바로 소스코드를 확인한다.
get source
<?php
if (isset($_GET['view-source'])) {
show_source(__FILE__);
exit();
}
/*
create table user(
idx int auto_increment primary key,
id char(32),
ps char(32)
);
*/
if(isset($_POST['id']) && isset($_POST['ps'])){
include("./lib.php"); # include for $FLAG, $DB_username, $DB_password.
$conn = mysqli_connect("localhost", $DB_username, $DB_password, "login_filtering");
mysqli_query($conn, "set names utf8");
$id = mysqli_real_escape_string($conn, trim($_POST['id']));
$ps = mysqli_real_escape_string($conn, trim($_POST['ps']));
$row=mysqli_fetch_array(mysqli_query($conn, "select * from user where id='$id' and ps=md5('$ps')"));
if(isset($row['id'])){
if($id=='guest' || $id=='blueh4g'){
echo "your account is blocked";
}else{
echo "login ok"."<br />";
echo "FLAG : ".$FLAG;
}
}else{
echo "wrong..";
}
}
?>
<!DOCTYPE html>
<style>
* {margin:0; padding:0;}
body {background-color:#ddd;}
#mdiv {width:200px; text-align:center; margin:50px auto;}
input[type=text],input[type=[password] {width:100px;}
td {text-align:center;}
</style>
<body>
<form method="post" action="./">
<div id="mdiv">
<table>
<tr><td>ID</td><td><input type="text" name="id" /></td></tr>
<tr><td>PW</td><td><input type="password" name="ps" /></td></tr>
<tr><td colspan="2"><input type="submit" value="login" /></td></tr>
</table>
<div><a href='?view-source'>get source</a></div>
</form>
</div>
</body>
<!--
you have blocked accounts.
guest / guest
blueh4g / blueh4g1234ps
-->
소스코드는 위와 같다.
이제 각 소스코드를 나눠서 분석를 시작한다.
if (isset($_GET['view-source'])) {
show_source(__FILE__);
exit();
}
/*
create table user(
idx int auto_increment primary key,
id char(32),
ps char(32)
);
*/
소스코드를 보여주는 부분과 user table 구성을 보여준다.
if(isset($_POST['id']) && isset($_POST['ps'])){
include("./lib.php"); # include for $FLAG, $DB_username, $DB_password.
id 와 ps 라는 파라미터가 존재할 시, ./lib.php를 include 한다. (lib.php 코드를 가져온다.)
$id = mysqli_real_escape_string($conn, trim($_POST['id']));
$ps = mysqli_real_escape_string($conn, trim($_POST['ps']));
$row=mysqli_fetch_array(mysqli_query($conn, "select * from user where id='$id' and ps=md5('$ps')"));
if(isset($row['id'])){
if($id=='guest' || $id=='blueh4g'){
echo "your account is blocked";
}else{
echo "login ok"."<br />";
echo "FLAG : ".$FLAG;
}
}else{
echo "wrong..";
}
}
id와 ps 파라미터를 escape 처리하여 변수 $id, $ps 에 저장한다.
id, ps 를 넣어 mysql 쿼리문을 실행시키며 실행한 결과 값은 $row 배열 변수로 저장한다.
저장한 row 배열에 'id' 키 값으로 guest, blueh4g 가 입력될 경우, your account is blocked 가 출력된다.
guest, blueh4g 이외의 저장된 id 값으로 입력되었다면, FLAG 값이 출력된다.
그이외에 쿼리문을 통해 저장된 $row 값이 없다면 wrong... 이 출력된다.
<!--
you have blocked accounts.
guest / guest
blueh4g / blueh4g1234ps
-->
위는 블록된 계정을 보여준다.
여기서 필자는 mysqli_real_escape_string() 취약점을 생각해, SQL Injection을 진행했다.
하지만, 해당 취약점은 멀티바이트(EUC-KR, EUC-JP 등)을 유니코드(UTF-8)로 변경할 때 발생하는 취약점이다.
해당 문제와는 관련이 없었다.
답을 보니 쉬운문제였다.
mysql의 쿼리에서는 대문자와 소문자의 구분이 없다. 그래서 이를 이용해서 문제를 해결하면 되는 것이였다.
id, pw 에 guest/guest 를 입력하게되면, php 코드에서 id를 통해 검증하여 your account is blocked 가 출력된다.
하지만, GUEST/guest 를 입력하면, php 코드에서는 대문자와 소문자를 구분해 필터링이 되지 않으며, 쿼리에서는 구분을 하지 않으므로, FLAG 값을 노출시킨다.
입력 : id=GUEST / pw=guest
'Dreamhack > Dreamhack(1단계)' 카테고리의 다른 글
session-basic (웹 해킹) (2) | 2024.10.16 |
---|---|
[wargame.kr] tmitter (웹 해킹) (0) | 2024.10.16 |
[wargame.kr] type confusion (웹 해킹) (0) | 2024.10.16 |
[wargame.kr] strcmp (웹 해킹) (0) | 2024.10.16 |
[wargame.kr] fly me to the moon (웹 해킹) (0) | 2024.10.15 |