Wargame - 웹

[wargame.kr] strcmp & [wargame.kr] login filtering

김가윤 2023. 3. 28. 01:14

둘 다 간단한 문제이다.

 

1) [wargame.kr] strcmp

 

<?php
    require("./lib.php"); // for FLAG

    $password = sha1(md5(rand().rand().rand()).rand());

    if (isset($_GET['view-source'])) {
        show_source(__FILE__);
        exit();
    }else if(isset($_POST['password'])){
        sleep(1); // do not brute force!
        if (strcmp($_POST['password'], $password) == 0) {
            echo "Congratulations! Flag is <b>" . $FLAG ."</b>";
            exit();
        } else {
            echo "Wrong password..";
        }
    }

?>
<br />
<br />
<form method="POST">
    password : <input type="text" name="password" /> <input type="submit" value="chk">
</form>
<br />
<a href="?view-source">view-source</a>

 

위 소스를 보면

strcmp를 통해

비밀번호에 대한 검사를 진행하는데,

 

PHP strcmp 함수 비교 대상에

배열이 전달되면 있으면 0을 반환한다.

 

따라서

password에 배열을 전달하면

strcmp($_POST['password'], $password)이 부분이

0을 반환하고

 

strcmp($_POST['password'], $password) == 0 이 조건이

항상 참을 반환하기 때문에

FLAG를 출력한다.

 


2) [wargame.kr] login filtering

 

<?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

-->

 

위 소스를 보면

mysqli_escape_string 함수를 통해

쿼리문에 특수 문자 사용을 방지하고,

 

trime 함수를 통해

쿼리문에 존재하는 공백을 모두 제거한다.

 

하지만,

취약한 부분은

if(%id == 'guest || %id == 'blueh4g') 이 부분이다.

 

MySQL은 테이블이나 컬럼명에 대해서는

대소문자를 구분하지만

쿼리애 대해서는

대소문자를 구분하지 않는다.

 

예를 들어,

SELECT a FROM b WHERE id = 'Test'는

SELECT a FROM b WHERE id = 'test'와

동일하다.

 

위 소스코드 맨 아래 부분을 보면

차단 계정 목록이 있다

guest / guest

blueh4g / blueh4g

 

위를 이용해서

Guest / guest를 이용해 로그인을 하면

%id = Guest가 되고

Guest != guest 이기 때문에

else 구문이 실행되어

FLAG를 출력한다.

 

 

'Wargame - 웹' 카테고리의 다른 글

CSRF Advanced  (0) 2023.04.17
CSP Bypass Advanced  (0) 2023.04.14
CSP Bypass  (0) 2023.04.14
XSS Filtering Bypass Advanced  (0) 2023.03.29
Apache htaccess  (0) 2023.03.23