[wargame.kr] md5 password

2019-03-16

md5 password 문제를 보면 다음과 같은 디스크립션을 볼 수 있다.

md5('value', true);

md5에 관련된 문제임을 알 수 있다. 문제로 넘어가면 password를 입력하라고 하며, 소스를 보여준다!
코드를 보면 다음과 같다.

<?php
 if (isset($_GET['view-source'])) {
  show_source(__FILE__);
  exit();
 }

 if(isset($_POST['ps'])){
  sleep(1);
  mysql_connect("localhost","md5_password","md5_password_pz");
  mysql_select_db("md5_password");
  mysql_query("set names utf8");
  /*

  create table admin_password(
   password char(64) unique
  );

  */

  include "../lib.php"; // include for auth_code function.
  $key=auth_code("md5 password");
  $ps = mysql_real_escape_string($_POST['ps']);
  $row=@mysql_fetch_array(mysql_query("select * from admin_password where password='".md5($ps,true)."'"));
  if(isset($row[0])){
   echo "hello admin!"."<br />";
   echo "Password : ".$key;
  }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>

이 중에서 다음 부분을 보면 md5함수를 사용하고 있는 것을 볼 수 있다.

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

일단, php에서 md5함수를 어떻게 사용하는지 먼저 알아보았다.

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

bool $raw_output 값이 true 일 경우 해시의 길이 16인 바이너리 형식으로 반환하고, 이 값을 생략하면 기본값은 false로 우리가 일반적으로 사용하는 md5함수와 같이 해시 값을 출력해준다.

md5함수를 찾아보다가, md5 함수 취약점이 연관 검색어에 있어서 보게되었는데 참고블로그 요기에 내가 원하는 것이 딱 있었다.

md5("string") -> 32자리의 16진수 값 반환
md5("string", true) -> 16자리의 바이너리 형식으로 반환

그리고 이것으로 md5함수를 true로 사용하면 sql injection이 가능하다눈 것을 알았다 호호

그럼 앞에서 보았던 쿼리 문을 보자!

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

여기서 password 값에 'or'이 들어간다면 injection이 가능하게 된다.
이 값을 찾는 과정은 참고블로그 여기에서 자세히 설명해 주고 있는 것 같다.
나는 검색을 통해 찾았다.
129581926211651571912466741651878684928를 입력하면 'or' 형태의 결과값을 얻을 수 있다고 한다.

참고블로그 요기에서 친절하게 python으로 테스트를 해주었는데, 따라해보면 다음과 같다.

ubuntu@ubuntu:~$ python
Python 2.7.12 (default, Nov 12 2018, 14:36:49)
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import hashlib
>>> print hashlib.md5("129581926211651571912466741651878684928").digest()
ٔ0Do#ࠁ'or'8

'or' 형태인 것을 확인할 수 있었다.
따라서 129581926211651571912466741651878684928를 입력하면 flag를 획득할 수 있다.