[드림핵] login filtering 풀이
https://dreamhack.io/wargame/challenges/336
[wargame.kr] login filtering
Description text I have accounts. but, it's blocked. can you login bypass filtering?
dreamhack.io
계정이 막혔다고 한다. 막힌 계정을 우회하여 접속을 성공해보자.
첫 화면이다. 평범한 로그인 페이지이다. 소스를 확인해보자.
<?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. //lib.php페이지를 포함시킴
$conn = mysqli_connect("localhost", $DB_username, $DB_password, "login_filtering"); //서버의 호스트이름, DB ID, DB PW, DB 이름으로 접속
mysqli_query($conn, "set names utf8"); //utf-8로 문자 인코딩 설정
$id = mysqli_real_escape_string($conn, trim($_POST['id'])); //trim 함수로 문자열 앞 뒤 공백을 자르고
$ps = mysqli_real_escape_string($conn, trim($_POST['ps'])); //mysqli_real_escape_string으로 특수문자를 이스케이프하여 sql인젝션 방지
$row=mysqli_fetch_array(mysqli_query($conn, "select * from user where id='$id' and ps=md5('$ps')")); //검색
if(isset($row['id'])){ //id로 검색된 값의 첫번째 행이 있을 때
if($id=='guest' || $id=='blueh4g'){ //우리가 입력한 값이 guest이거나 blueh4g일 경우
echo "your account is blocked"; //로그인 실패
}else{
echo "login ok"."<br />"; //아닐 경우 로그인 성공
echo "FLAG : ".$FLAG;
}
}else{
echo "wrong.."; //선택된 계정이 없으면 wrong
}
}
?>
<!--
you have blocked accounts.
guest / guest //막힌 계정의 아이디와 패스워드
blueh4g / blueh4g1234ps
-->
이 문제를 풀기 위해선 필터링 중인 guest를 우회해야한다.
mysql은 기본적으로 대소문자에 sensitive하지 않다. 하지만 php는 대소문자에 sensitive하기 때문에 Guest와 같이 입력하면 mysql에서는 검색이 되면서 php에서 이루어지는 필터링을 우회할 수 있다.
Guest로 검색해도 guest가 검색되는 모습이다.
짜자잔
요약
- php와 mysql의 기본적인 대소문자 처리 정책에 대한 이해를 하여 php에 걸려있는 필터링 우회 문제
공격 방어
php와 mysql 대소문자 처리 차이에 있어서 취약점이 발생하고 있다. 해당 문제에서는 mysql로 검색한 후 php로 입력값 검증을 하고 있다.
따라서 php에서 입력한 값을 모두 소문자로 바꿔주는 코드를 추가하는 방법이 있을 것 같다.
혹은 mysql로 Guest로 검색하면 guest가 리턴되는 것이 보인다. 따라서 반환되는 mysql 값으로 입력값 검증이 이루어진다면 해당 공격을 막을 것이다.