본문 바로가기
Hacking/wargame.kr

[wargame.kr] Question 20. counting query

by 알거음슴 2021. 7. 19.

Question 20. counting query

문제

Error based SQLi challenge.

 

 

 

풀이

문제 접근 시 로그인 폼과 source를 볼 수 있는 링크가 제공된다 ID의 경우 고정 값으로 나의 IP가 입력되어 있으며 PW의 경우 입력이 가능하고 user버튼의 경우 admin으로 변경이 가능하다. 소스코드를 확인해보자.

 

 

<?php
 if (isset($_GET['view-source'])) {
     show_source(__FILE__);
     exit();
 }
 include("./inc.php"); // database connect.
 include("../lib.php"); // include for auth_code function.

 ini_set('display_errors',false);

 function err($str){ die("<script>alert(\"$str\");window.location.href='./';</script>"); }
 function uniq($data){ return md5($data.uniqid());}
 function make_id($id){ return mysql_query("insert into all_user_accounts values (null,'$id','".uniq($id)."','guest@nothing.null',2)");}
 function counting($id){ return mysql_query("insert into login_count values (null,'$id','".time()."')");}
 function pw_change($id) { return mysql_query("update all_user_accounts set ps='".uniq($id)."' where user_id='$id'"); }
 function count_init($id) { return mysql_query("delete from login_count where id='$id'"); }
 function t_table($id) { return mysql_query("create temporary table t_user as select * from all_user_accounts where user_id='$id'"); };

 if(empty($_POST['id']) || empty($_POST['pw']) || empty($_POST['type'])){
  err("Parameter Error :: missing");
 }

 $id=mysql_real_escape_string($_POST['id']);
 $ps=mysql_real_escape_string($_POST['pw']);
 $type=mysql_real_escape_string($_POST['type']);
 $ip=$_SERVER['REMOTE_ADDR'];

 sleep(2); // not Bruteforcing!!

 if($id!=$ip){
  err("SECURITY : u can access with allotted id only");
 }

 $row=mysql_fetch_array(mysql_query("select 1 from all_user_accounts where user_id='$id'"));
 if($row[0]!=1){
  if(false === make_id($id)){
   err("DB Error :: create user error");
  }
 }
 
 $row=mysql_fetch_array(mysql_query("select count(*) from login_count where id='$id'"));
 $log_count = (int)$row[0];
 if($log_count >= 4){
  pw_change($id);
  count_init($id);
  err("SECURITY : bruteforcing detected - password is changed");
 }
 
 t_table($id); // don`t access the other account

 if(preg_match("/all_user_accounts/i",$type)){
  err("SECURITY : don`t access the other account");
 }

 counting($id); // limiting number of query

 if(false === $result=mysql_query("select * from t_user where user_id='$id' and ps='$ps' and type=$type")){
  err("DB Error :: ".mysql_error());
 }

 $row=mysql_fetch_array($result);
 
 if(empty($row['user_id'])){
  err("Login Error :: not found your `user_id` or `password`");
 }

 echo "welcome <b>$id</b> !! (Login count = $log_count)";
 
 $row=mysql_fetch_array(mysql_query("select ps from t_user where user_id='$id' and ps='$ps'"));

 //patched 04.22.2015
 if (empty($ps)) err("DB Error :: data not found..");

 if($row['ps']==$ps){ echo "<h2>wow! auth key is : ".auth_code("counting query")."</h2>"; }

?>

매우 긴 소스코드가 제공된다 해당 코드를 분석하면 다음과 같은 결론을 얻을 수 있다.

 1) 4번 로그인 시도 시 패스워드는 변경된다.

 2) 다른 계정으론 접근 불가능 하고 id, pw, type 모두 값이 들어있어야 한다.

 3) 이중 type 의 부분에 SQL injection 이 가능하다.

파이썬을 통하여 SQL Injection 공격을 시도해본다.

 

 

우선 취약점의 공격가능 유무를 확인하기 위해 type=1 or 1=1 을 공격에 성공하는걸 확인할 수 있다. 검은색 네모박스는 실제 IP 주소가 입력된 부분이다.

 

 

1 or row(1,1)>(select count(*),concat(ps,0x41,floor(rand(0)*2)) as test from information_schema.tables group by test limit 1)

해당 payload 를 통하여 값을 추출 할 수 있으며 Duplicate entry “” 중 마지막 A1을 제외한 값이 PW가 된다.

 

 

PW에 구한값을 넣으면 성공적으로 플래그를 구할 수 있으며 제출 시 문제를 통과 할 수 있다.

'Hacking > wargame.kr' 카테고리의 다른 글

[wargame.kr] Question 19. QnA  (0) 2021.07.19
[wargame.kr] Question 18. dmbs 355  (1) 2021.07.19
[wargame.kr] Question 17. lonely guys  (0) 2021.07.19
[wargame.kr] Question 16. ip log table  (0) 2021.07.19
[wargame.kr] Question 15. Simple Board  (0) 2021.07.19