본문 바로가기
CTF

[CTF] justCTF [*] 2020 writeup

by snwo 2021. 2. 2.

ainsetin님이 또 초대를 해주셔서 주말동안 즐겁게 CTF 를 했다.

reklect 한 문제를 풀었다.

 

reklect

MACH-O 아키텍쳐의 go언어로 된 바이너리였다. 맥북이 있었다면 주소를 쉽게 찾을 수 있었을텐데.. 

실행을 못시켜서 정적분석을 했다.

 

특정 주소에있는 값 여러개와 16진수를 xor 연산한다.

d 에 8바이트 저장하고

d[8] 에 8바이트 저장하고

d[16] 에 8바이트 저장하고 ...

 

길이가 48바이트 정도 됐었다.

xor연산해서 문자열을 만들어보니 base64처럼 보이는 값이 나온다.

 

바로 밑에 그 값들을 base64 디코딩하는 함수가 있었다.

나온 값은 this_is_very_s3cret_file13371337.js 이였다.

 

더 밑에 request 를 보내는 함수가 있었는데,

127.0.0.1/this_is_very_s3cret_file13371337.js

여기다가 리퀘스트를 보내는 것이였다. 문제설명에서 주어지는 링크가 있었는데,

this_is_very_s3cret_file13371337.js 를 붙여 들어가보니 아무것도 주지 않았다.

그래서 파이썬으로 request 를 보내보니, js 코드를 얻을 수 있었다. 

 

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
var _0x38d9 = ['charCodeAt''537865HVvFyd''153402TvesmL''637814tgMjYr''191740qwGPgk''length''21541OOTfbk''2FaFWFo''4DOGutk''21qyUBwr''500024opEyBW''2669431PGatTv'];
var _0x2b2f = function (_0x20b4d4, _0x6e7ec) {
    _0x20b4d4 = _0x20b4d4 - 0x68;
    var _0x38d9ae = _0x38d9[_0x20b4d4];
    return _0x38d9ae;
};
(function (_0x610c0b, _0x118d97) {
    var _0xdf5613 = _0x2b2f;
    while (!![]) {
        try {
            var _0x51bf5f = parseInt(_0xdf5613(0x72)) + parseInt(_0xdf5613(0x6f)) + -parseInt(_0xdf5613(0x6d)) * -parseInt(_0xdf5613(0x73)) + parseInt(_0xdf5613(0x68)) + -parseInt(_0xdf5613(0x6e)) * -parseInt(_0xdf5613(0x6b)) + parseInt(_0xdf5613(0x6c)) * parseInt(_0xdf5613(0x69)) + -parseInt(_0xdf5613(0x70));
            if (_0x51bf5f === _0x118d97) break;
            else _0x610c0b['push'](_0x610c0b['shift']());
        } catch (_0x41e7a9) {
            _0x610c0b['push'](_0x610c0b['shift']());
        }
    }
}(_0x38d9, 0x6f429), text = '{rewJey\x00bnF\x05B_EnEC\x00RZHnSD\x06nCdbEn]\x01\x01ZBnbR\x05CHL');
 
function xyz(_0x4821d8, _0x1e7b78) {
    var _0x3cb5de = _0x2b2f,
        _0x342b88 = '';
    for (var _0x2e0312 = 0x0; _0x2e0312 < _0x4821d8[_0x3cb5de(0x6a)]; _0x2e0312++) {
        _0x342b88 += String['fromCharCode'](_0x4821d8[_0x3cb5de(0x71)](_0x2e0312) ^ _0x1e7b78['charCodeAt'](_0x2e0312 % _0x1e7b78[_0x3cb5de(0x6a)]));
    }
    return _0x342b88;
}
cs

go 언어로 리퀘스트보낼 목적으로 웹을 구축해서 직접 들어갔을때 막혔던 것 같다.

dreamhack funjs 와 유사하다. 수상하다.

xyz 함수는 인자 두 개를 받는데, 첫번째인자 ^ 두번째인자 한 값을 돌려주는데, 

두번째 인자는 길이만큼 반복해서 xor 하는 것 보니, key 역할을 하는 것 같았다.

 

첫번째 인자는 text 값을 넘겨주는 것이고, flag 포맷은 JCTF{} 으로 되어있지만 justCTF{} 으로 인증을 해야한다 했다.

JCTF 과 text 앞 4글자를 xor해보면 키를 알아낼 수 있지만, 

나는 개싱으로 파일이 13371337 으로 끝나니까 xyz(text,'1337') 을 호출해 봤더니

JA@~~~~ 이렇게 이상한 값이 출력되는 것을 목격했다.

그래서 정상적으로 나온 '1' 만 잘라서 xyz(text,'1') 을 호출했더니 flag가 나왔다. 야호