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가 나왔다. 야호