개발세발보안중

[wargame.kr] md5 password 본문

CTF

[wargame.kr] md5 password

채영채영 2023. 10. 15. 23:50
<?php
 if (isset($_GET['view-source'])) {
  show_source(__FILE__);
  exit();
 }

 if(isset($_POST['ps'])){
  sleep(1);
  include("./lib.php"); # include for $FLAG, $DB_username, $DB_password.
  $conn = mysqli_connect("localhost", $DB_username, $DB_password, "md5_password");
  /*
  
  create table admin_password(
   password char(64) unique
  );
  
  */

  $ps = mysqli_real_escape_string($conn, $_POST['ps']);
  $row=@mysqli_fetch_array(mysqli_query($conn, "select * from admin_password where password='".md5($ps,true)."'"));
  if(isset($row[0])){
   echo "hello admin!"."<br />";
   echo "FLAG : ".$FLAG;
  }else{
   echo "wrong..";
  }
 }
?>
<style>
 input[type=text] {width:200px;}
</style>
<br />
<br />
<form method="post" action="./index.php">
password : <input type="text" name="ps" /><input type="submit" value="login" />
</form>
<div><a href='?view-source'>get source</a></div>

코드를 보면 if(isset($_POST['ps'])) 블록과 %row배열을 확인해서, 비밀번호를 확인하는 부분이 어떻게 동작하는지 이해해야한다. HTTPS POST 요청에서 'ps'라는 이름의 매개변수가 설정되었을 때 실행된다.

mysqli_real_escape_string 함수를 사용하여 사용자가 입력한 'ps'값을 안전하게 처리한다. 즉, SQL injection은 아닌 셈이다,

$row = @mysqli_fetch_array(mysqli_query($conn, "select * from admin_password where password='".md5($ps,true)."'")); 이 코드에서는 데이터베이스에서 'admin_password' 테이블로부터 `password`열의 값이 `md5($ps, true)`와 일치하는 행을 선택한다. md5($ps, true) 는 사용자가 입력한 비밀번호를 MD5 해시로 변환한 값이다.

자 근데 앞에서 착각한 점이 있다. 바로 MD5의 취약점인 것이다. 

string md5 ( string $str , [ bool $raw_output = false ] )

 

첫 번째 인수로 제공된 문자열은 MD5 해시값으로 변환되고 16진수 형태의 32자 길이의 출력이 반환된다. 'raw_output'의 기본값은 'false'이 되며, 이 경우 제공된 문자열이 16바이트 이진 값으로 반환된다.

그러므로 만약 우리의 출력 MD5 비밀번호에 'OR' 또는 '='이 포함되도록 한다면, SQL injection으로 쿼리를 우회할 수 있다는 것이다!

그러면

(mysql_query("select * from admin_password where password='".md5($ps,true)."'");

이게

(mysql_query("select * from admin_password where password=''OR''");

이렇게 될테니까 말이다..

그러면 '틀린 값1' OR '1=1' 이므로 FALSE = TRUE 이므로 TRUE 가 된다.

또 다른 예로는 

(mysql_query("select * from admin_password where password=''=''");

에서는 

'틀린 값1' = '틀린 값2' 이므로 FALSE = FALSE 이므로 TRUE이다. 

 

'CTF' 카테고리의 다른 글

Broken Password  (0) 2023.10.04
login -1  (0) 2023.10.04
baby-sqlite  (0) 2023.10.04
file-special-bit  (0) 2023.09.27
welcome  (0) 2023.09.27
Comments