본문 바로가기

Write Up

2016 CodeGate Final BMP



27명 푼 미스크 문제입니다.

웹사이트와 소스가 주어지는데 웹 사이트를 들어가 보면 

이렇게 생겼습니다. 

글자를 치면 이렇게 bmp파일이 점점 생겨나면서 올라옵니다. 옆에 flag.bmp가 만들어 지는 값을 찾으면 됩니다. 처음에는 편법으로 0~9, A~Z, a~z까지 싹다 어떤 형태의 그림이 만들어지는지 찾은 후에 테이블로 만들어서 비교하려고 했으나 이전 값이 현재의 bmp에 영향을 준다는 것을 깨닫고 포기했습니다. 결국 주어진 js파일을 분석해서 브루트포싱을 하는 파이썬 소스를 짜서 풀었습니다.

처음에는 소스가 한줄로 나열되고 난독화가 약간 되어 있어서 보기 편하게 만들어 준 후에 분석했습니다. 

1
2
3
4
5
/**
IE, Safari Not good.
Chrome good Work.
**/
function create_bmp(){var _0xb2ab=["","\x76\x61\x6C\x75\x65","\x6B\x65\x79","\x67\x65\x74\x45\x6C\x65\x6D\x65\x6E\x74\x42\x79\x49\x64","\x6C\x65\x6E\x67\x74\x68","\x42\x4D\xDE\x00\x00\x00\x00\x00\x00\x00\x3E\x00\x00\x00\x28\x00\x00\x00\x0D\x00\x00\x00\x28\x00\x00\x00\x01\x00\x01\x00\x00\x00\x00\x00\xA0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00","\x63\x68\x61\x72\x43\x6F\x64\x65\x41\x74","\x70\x6F\x77","\x61\x62\x73","\x73\x75\x62\x73\x74\x72","\x5C\x78","\x00\x00","\x22","\x69\x6D\x67","\x63\x72\x65\x61\x74\x65\x45\x6C\x65\x6D\x65\x6E\x74","\x73\x72\x63","\x62\x6D\x70\x5F\x69\x6E\x5F\x69\x6E\x70\x75\x74","\x64\x61\x74\x61\x3A\x69\x6D\x61\x67\x65\x2F\x62\x6D\x70\x3B\x62\x61\x73\x65\x36\x34\x2C"];var header,data,image,maps=_0xb2ab[0],key=_0xb2ab[0];key=document[_0xb2ab[3]](_0xb2ab[2])[_0xb2ab[1]];if(key===null||key[_0xb2ab[4]]==0){return};header=_0xb2ab[5];for(var i=0;i<key[_0xb2ab[4]];++i){var index_key=_0xb2ab[0],v1=0,v2=0,v3=0,data;index_key=key[i];v1=(Math[_0xb2ab[7]](index_key[_0xb2ab[6]](),2)*3)+31337*(i%2?i+1:i+1*2);if(i!==0){v2=~Math[_0xb2ab[7]](key[i-1][_0xb2ab[6]](),2);for(var j=i%2;j<i;j+=2){if(i%2){v3+=key[j][_0xb2ab[6]]()}else {v3-=key[j][_0xb2ab[6]]()}}};data=Math[_0xb2ab[8]]((v1+v2+v3)/3);data=data.toString(16)[_0xb2ab[9]](0,4);data=_0xb2ab[10]+data[_0xb2ab[9]](0,2)+_0xb2ab[10]+data[_0xb2ab[9]](2);maps+=data+_0xb2ab[11]};bmp_data=header+eval(_0xb2ab[12]+maps+_0xb2ab[12]);image=document[_0xb2ab[14]](_0xb2ab[13]);document[_0xb2ab[3]](_0xb2ab[16])[_0xb2ab[15]]=_0xb2ab[17]+btoa(bmp_data)}
cs

난독화된 소스

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/**
IE, Safari Not good.
Chrome good Work.
**/
function create_bmp() {
    var header, data, image, maps = "", key = "";
    key = document["getElementById"]("key")["value"];
    if(key === null||key["length"== 0) {
        return
    };
    header="BM\xde\x00\x00\x00\x00\x00\x00\x00>\x00\x00\x00(\x00\x00\x00\r\x00\x00\x00(\x00\x00\x00\x01\x00\x01\x00\x00\x00\x00\x00" + 
           "\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\x00";
    for(var i = 0; i < key["length"]; ++i) {
        var index_key = "", v1 = 0, v2 = 0, v3 = 0, data;
        index_key = key[i];
        v1 = (Math["pow"](index_key["charCodeAt"](), 2* 3+ 31337 * (i % 2 ? i + 1 : i + 1 * 2);
        if(i !== 0) {
            v2 = ~Math["pow"](key[i-1]["charCodeAt"](), 2);
            for(var j = i % 2; j < i; j += 2) {
                if(i % 2) {
                    v3 += key[j]["charCodeAt"]()
                }
                else {
                    v3 -= key[j]["charCodeAt"]()
                }
            }
        };
        data = Math["abs"]((v1 + v2 + v3) / 3);
        data = data.toString(16)["substr"](04);
        data = "\\x" + data["substr"](02+ "\\x" + data["substr"](2);
        maps += data + "\x00\x00"
    };
    bmp_data = header + eval("\"" + maps + "\"");
    image = document["createElement"]("img");
    document["getElementById"]("bmp_in_input")["src"="data:image/bmp;base64,"+btoa(bmp_data)
}
cs

보기 쉽게 한 소스

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
flag = '\x77\x1F\x00\x00\x6A\x9D\x00\x00\xA0\x58\x00\x00\xC8\xB9\x00\x00\xF3\xC5\x00\x00\xFC\x3D\x00\x00\
\x16\x8A\x00\x00\x16\x04\x00\x00\x19\x57\x00\x00\x1B\x9B\x00\x00\x20\x3F\x00\x00\x20\x2B\x00\x00\x23\xA6\
\x00\x00\x24\x42\x00\x00\x29\x11\x00\x00\x2B\x34\x00\x00\x2F\x80\x00\x00\x2D\xD1\x00\x00\x33\x48\x00\x00\
\x33\x83\x00\x00\x38\x92\x00\x00\x3A\x51\x00\x00\x3D\x0E\x00\x00\x3D\x9A\x00\x00\x44\x65\x00\x00\x42\x36\
\x00\x00\x47\xDD\x00\x00\x49\x96\x00\x00\x4D\xFD\x00\x00\x4E\x28\x00\x00\x51\x88\x00\x00\x52\x20\x00\x00\
\x57\x0C\x00\x00\x59\x07\x00\x00\x5B\x9C\x00\x00\x5E\x06\x00\x00\x60\xBC\x00\x00\x61\x87\x00\x00\x68\x19\
\x00\x00\x67\xB5\x00\x00'
Table = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_'
real = ''
 
def abs(a):
    if a > 0:
        return a
    else:
        return ~a
 
def encode(input):
        maps = ''
        for i in range(len(input)):
            v1 = 0
            v2 = 0
            v3 = 0
            data = ''
 
            carry = i % 2
            if carry: carry = i + 1
            else: carry = i + 2
            v1 = ((ord(input[i]) ** 2* 3+ 31337 * carry
 
            if (i != 0):
                v2 = ~(ord(input[i - 1]) ** 2)
                for j in range(i % 2, i, 2):
                    if i % 2: v3 += ord(input[j])
                    else: v3 -= ord(input[j])
            data = abs(v1 + v2 + v3) / 3
            data = str(hex(data))[2:6]
            data = chr(int(data[0:2], 16)) + chr(int(data[2:], 16))
            maps += data + '\x00\x00'
        return maps
 
for i in range(0len(flag), 4):
    for j in Table:
        if flag[0:i + 4== encode(real + j):
            real += j
            break
 
print real
cs

파이썬 브루트포싱 소스

돌리면 키가 나옵니다.


key : bb2f96cc4adb880fe5037c60b27bbb954d6b67dc

'Write Up' 카테고리의 다른 글

2016 CodeGate Final rev  (1) 2016.05.06
2016 CodeGate Final GMPQZ  (0) 2016.05.04
2015 Christmas CTF vsnoted  (0) 2016.04.30
PlaidCTF 2016 quite quixotic quest - 300pt  (0) 2016.04.18
PlaidCTF 2016 quick - 175pt  (0) 2016.04.18