[Wargame.kr] login with crypto! but.. 풀이 (458p)
Wargame/wargame.kr

[Wargame.kr] login with crypto! but.. 풀이 (458p)

login with crypto! but.. view-source code
<?php

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

include("../lib.php"); // include for auth_code function.
/*******************************************************
- DB SCHEMA (initilizing)

create table accounts(
 idx int auto_increment primary key,
 user_id varchar(32) not null unique,
 user_ps varchar(64) not null,
 encrypt_ss text not null
);

********************************************************/

function db_conn(){
 mysql_connect("localhost","login_with_cryp","login_with_crypto_but_pz");
 mysql_select_db("login_with_crypto_but");
}

function init(){
 db_conn();
 $password = crypt(rand().sha1(file_get_contents("/var/lib/dummy_file").rand())).rand();
 mysql_query("insert into accounts values (null,'admin','{$password}','".sucker_enc('881114')."')"); // admin`s password is secret! xD
 mysql_query("insert into accounts values (null,'guest','guest','".sucker_enc('000000')."')");
}
//init(); // create user for initializing

function enc($str){
 $s_key = "L0V3LySH:butsheismyxgf..";
 $s_vector_iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_3DES, MCRYPT_MODE_ECB), MCRYPT_RAND);
 $en_str = mcrypt_encrypt(MCRYPT_3DES, $s_key, $str, MCRYPT_MODE_ECB, $s_vector_iv);
 $en_base64 = base64_encode($en_str);
 $en_hex = bin2hex($en_str);
 return $en_hex;
}

function sucker_enc($str){
 for($i=0;$i<8;$i++) $str = enc($str);
 return $str;
}

function get_password($user,$ssn){
 db_conn();
 $user = mysql_real_escape_string($user);
 $ssn  = mysql_real_escape_string($ssn);
 $result = mysql_query("select user_ps from accounts where user_id='{$user}' and encrypt_ss='".sucker_enc($ssn)."'");
 $row = mysql_fetch_array($result);
 if ($row === false) {
  die("there is not valid account!");
 }
 return $row[0]; 
}

ini_set("display_errors", true);

if( (isset($_POST['user']) && isset($_POST['ssn']) && isset($_POST['pass'])) ){
 
 sleep(2); // do not bruteforce !!!! this challenge is not for bruteforce!!

 if($_POST['pass'] == get_password($_POST['user'],$_POST['ssn'])){

  if($_POST['user'] == "admin"){
   echo "Login Success!!! PASSWORD IS : <b>".auth_code("login with crypto! but..")."</b>";
  }else{
   echo "Login Success. but you r not 'admin'..";
  }
 }else{
  echo "Login Failed";
 }

}

?>

이번 문제는 그냥 시도해보다가 푼 문제여서.. 일단, 코드를 간단하게 설명해보겠다.

1. admin의 password 값은 랜덤이다.

2. enc, sucker_enc라는 암호화 함수가 존재한다.

3. if문을 통과하기 위해서는 user, ssn, pass 쿼리가 존재해야 한다. 값은 없어도 O

4. if($_POST['pass'] == get_password($_POST ['user'],$_POST ['ssn']))이고 user가 admin이어야 flag를 출력한다.

 

일단 3번 if문은 쉽게 통과할 수 있으나, 4번 if문이 문제다.

password를 모르니, 당연히 로그인이 불가능하다.

 

결국, 로그인을 하기 위해서는 get_password에서 넘어온 값을 조작해야 한다는 것인데..

여기서 부터는 앞에서 말했다시피, 시도하다가 푼 문제여서.. 추측성 글이다. 이유를 알면 바로 추가하도록 하겠다.

 

id 값은 admin이여야 정상적으로 쿼리가 들어가니, 가만히 냅뒀고, enc의 값을 파이썬을 이용해 매~우 길게 넣어봤다.

나는 "881114" * 30000 값을 넣었다. 그랬더니..?

???.. 로그인에 성공했다. 일단 SQL 쿼리문에 엄청나게 긴 값을 넣으면 mysql_fetch_array() expects parameter 1 to be resource, boolean given in... 오류가 터진다. 아마도 해당 부분에서 리턴된 오류 값 때문에 row가 조작된 듯하다.

빠른 시일안에 이유를 찾아 다시 업로드하도록 하겠다.