제 1 회청소년화이트해커경진대회 3 위고기완 (SelllSonic)
Level 1 1. 20A9(16 진수 ) 와 1100111111(2 진수 ) 의합을 10 진수로나타내시오 2. 10011000 과 00110101 의 xor 연산을하고 10 진수로나타내시오 3. N e w H e a r t 각각의문자하나를 ascii 코드값의 10 진수합으로나타내면? 1, 2, 3번키를붙여서인증 1. 8361 + 831 = 9192 2. 152 xor 53 = 173 3. 78 + 101 + 119 + 72 + 101 + 97 + 114 + 116 = 798 Key) 9192173798 Level 2 주어진웹페이지에접속하면 핸드폰으로접속하세요 라고적혀있다. 모바일브라우저로의접속을판단할때 User-Agent를체크하므로 User-Agent을 Mobile로수정하여접속하면된다. Key) Well begun is half done.
Level 3 누군가뉴하트홈페이지에있는로고에비밀번호를숨겨놓았다. 비밀번호를알아내라. 주어진비트맵이미지를확대하여살펴보면눈에뜨이는점이몇개가있다. 이미지파일의일부가수정되어있으므로 뉴하트홈페이지에있는원본이미지와바이너리비교하여차이나는부분을수집한다. 6B 65 79 69 73 6E 65 77 68 65 40 72 74 21 21 문자열로변홖 keyisnewhe@rt!! Key) newhe@rt!!
Level 4 <decodebase85~aa$detfs+x&&hj+df#kgl*sfgmldvbzn@d/ ~GiagsAQT#hhsso@tr;TwM$Y(le^ojs^4dawh?&ftzlwrgplY )hoes!d*jgttmr^^zgngfdlxbdb~!!op@cxuatsvf)vmst!z 1ropdtr&*Dity3c)3duaev*cvRtsb&4zt0dnads8hd@lk^jad 1879rwe#d$#ytr./dsudr>m^&ifg?bnBoahcv&(p4jxz#*lkt d@#sda7zxcvb^^8o$af1%7hg*23elj)hjklk,dfbfp>mnb,mo @aytkotz;r((udx&i*dtkqae)0tl%^xr18;wvcvd~jbnzdfg> 주어진문자열의한줄을 7x7 블록이미지에알맞게 7 개로분할한다. <decode base85~ aa$detf s+x&&hj +df#kgl *sfgmld vbzn@d/ 이미지에서색칠된부분에해당하는인덱스의문자열만추출하여모은다. <decode base85~ aa$detf s+x&&hj +df#kgl *sfgmld vbzn@d/ <~E+*g/ 위과정을반복해서이어서 Base85 디코딩하면된다. <~E+*g/GAhM4?YORgBOu!rDdR0d@r#drB4#7^F*),>@;I)1~> password_is_hello_hacking_festival!! Key) hello_hacking_festival!!
Level 5 h4ck.apk 파일의압축을풀어 classes.dex 파일을 dex2jar 를이용해 jar 파일로변홖하고, jd-gui 로디컴파일한다. decript 함수에서 ygbahi?+hih5vrhhsb1r 를인자로받아어떤연산을하고있다.
디컴파일이올바르게수행되지않아소스분석이힘들수도있겠지만젂체적인흐름을보면 인자로젂달받은문자가 abcdefghijklmnopqrstuvwxyz/.1234567890~_:%+=? 의몇번째 인덱스인가찾고, arrayofint 에서그인덱스에해당하는문자를출력하면된다. 그리고디컴파일결과에서 arrayofint[1] 는정의되어있지않은데 0 으로초기화되어있어서 그런것이다. C 언어로비슷하게구현해서답을얻을수있었다. char input[] = "ygbahi?+hih5vrhhsb1r"; char c[] = "abcdefghijklmnopqrstuvwxyz/.1234567890~_:%+=?"; int arrayofint[45]; int i, j, n; arrayofint[0] = 1; arrayofint[1] = 0; arrayofint[2] = 34; arrayofint[3] = 24; arrayofint[4] = 17; arrayofint[5] = 11;... arrayofint[36] = 33; arrayofint[37] = 4; arrayofint[38] = 27; arrayofint[39] = 19; arrayofint[40] = 15; arrayofint[41] = 12; arrayofint[42] = 42; arrayofint[43] = 32; arrayofint[44] = 39; for (i=0; i<(int)strlen(input); i++) { for (j=0; j<(int)strlen(c); j++) { if (input[i] == c[j]) { for (n=0; n<45; n++) { if (arrayofint[n] == j) printf("%c", c[n]); break; Key) diablo3+lol=hellgate
Level 6 nhf3.xap xap 파일은윈도우폰앱형식이다. 압축을풀어 nhf3.dll 를.Net Reflector 로디컴 파일한다. button1 ~ button9 버튺컨트롤은 arr 배열에서자싞의번호에해당하는인덱스를 index 변수값으로찿우고 index 변수를 1 증가시킨다. 다시말해버튺을클릭한순서대로 arr[x] 에해당하는값은 1 ~ 9 가들어가게된다. 그리고 Summit 버튺은 a5b8f53248a781e32e4fac5190dbfabc 은 Password 로, arr 을 Salt 로사용하여 e069836af6c41b560477d80ce8b08a36 를 AES 암호화하고 Base64 인코딩하여화면에출력한다. 여기서버튺의클릭에따라달라지는 arr 의값을알지못하기때문에찾아야한다. 압축푼파일중에서 WMAppManifest.xml 을살펴보면 Description 에버튺의순서가보인다. 버튺의순서를 134628957 로하면된다. 그런데버튺의순서가버튺 Name 이아닌 buttonx_click 이벤트의디컴파일결과에서보이 듯이화면에출력되는 Content 를기준으로해야한다.
nhf3.dll 파일내용을살펴보면아래와같이버튺 Name 에해당하는 Content 가존재한다. Content 가 134628957 가될경우 button 의 Name 은 button6 button1 button4 button3 button7 button5 button9 button2 button8 이된다. 즉 arr[6] = 1, arr[1] = 2, arr[4] = 3, arr[3] = 4, arr[7] = 5, arr[5] = 6, arr[9] = 7, arr[2] = 8, arr[8] = 9 가된다. 해당 arr 배열에대한출력값이답이다. arr[6] = 1; arr[1] = 2; arr[4] = 3; arr[3] = 4; arr[7] = 5; arr[5] = 6; arr[9] = 7; arr[2] = 8; arr[8] = 9; Rfc2898DeriveBytes bytes = new Rfc2898DeriveBytes("a5b8f53248a781e32e4fac5190dbfabc", arr); Aes aes = new AesManaged(); aes.key = bytes.getbytes(aes.keysize / 8); aes.iv = bytes.getbytes(aes.blocksize / 8); using (MemoryStream stream = new MemoryStream()) { ICryptoTransform transform = aes.createencryptor(); using (CryptoStream stream2 = new CryptoStream(stream, transform, CryptoStreamMode.Write)) { byte[] buffer = Encoding.UTF8.GetBytes("e069836af6c41b560477d80ce8b08a36"); stream2.write(buffer, 0, buffer.length); stream2.flushfinalblock(); Console.WriteLine(Convert.ToBase64String(stream.ToArray())); Key) u+vscbgx4hx8onbrk0dh8rxcbdg1fncoh8xn2uy8adkouk4hchvrk/lgpumcqq8n
Level 7 - 대회서버가닫혀있어정확한풀이를쓸수없다. 주어진페이지에접속하면룰렛이벤트페이지가존재하며한아이피마다 30분에한번씩룰렛을돌릴수있고 0 ~ 3점을랜덤으로얻게된다. 포인트를얻으면 50점을사용하여힌트1을열수있고, 100점을사용하여힌트2를얻을수있다. 그리고 1000점을모으면답을얻을수있다. 우선웹페이지소스를분석해보면 dehydrate 자바스크립트함수를이용하여스크립트복호 화를진행한다. 복사해서실행해복호화를하면아래소스가나온다. <script src=./roulette.js></script> <script src=./aes.js></script> roulette.js를열어보면 XMLHttpRequest 함수를이용하여 http://165.246.149.60/quiz/process.php 에 AES 암호화하여요청을보내는부분이존재한다. 소스를그대로복사하여 timestamp에서현재시갂을조작하면 30분제한을우회하여포인트를계속올릴수있다. 그런데아이피당 100 회제한이있으므로최대 300 포인트까지만올릴수있다. 300 포인트로힌트 1 을보면 timestamp 라고나오고, 힌트 2 를보면 UPDATE quiz set timestamp=(value), point=(value), counter=(value) WHERE ip_addr=(ip) 라고나온다. 힌트에서알려준쿼리를바탕으로 SQL Injection 을하면되겠다. timestamp 에다음과같이인젝션하여포인트조작이가능하다. timestamp=999999999999, point=1000, counter=7 WHERE ip_addr='x.x.x.x'# Key) NewHeartBeat
Level 8 wavwav.wav 드라마뉴하트 OST 음악파일이주어진다. GoldWave 로열어서 Control 창의 Spectrogram 을확인해보면이상한숫자들이보인다. 333233423121341231 / 00011100110100000010000101010001100000010101 333233423121341231 을바탕으로이진수들을자리수대로나누면 000 111 001 10 100 000 0100 00 101 0 10 0 011 0000 0 01 010 1 이되고, 0 을. 으로, 1 을 - 으로변경하여모스코드디코딩을하면답이된다.... ---..- -. -......-.... -.-. -...--.....-.-. - Key) soundslikenewheart 대회기갂중에가장많은시갂을소비한문제인데풀이는여백이많이남네 여백여백여백女白여 100
Level 9 Download Date? yyyymmddhhmmss 파일을열어보면파일의앞부분이아래와같이시작된다. Client UrlCache MMF Ver 5.2 검색을해보니 index.dat 파일이라는것을알수있었고, URL Tag + 0x10 부분이 Last Accessed 에해당하는부분이었다. w32tm 을이용해날짜형식을바꾸면답을구할수있다. Key) 20120119105514
Level 10 NewHeart 수사대는어떤사건을수사하던중마약사건에관렦된범인을체포하였다. 범인은마약을밀거래하는사람으로특정일특정장소에서밀거래상과접선할예정이었다는점을자백하였으나수사대는더이상의자세한내용은밝혀내지못했다. 유일한단서는범인이가지고있던스마트폰으로, 암거래상과정보를주고받았을가능성이높다. 암거래상과의접선장소및시갂을찾아라. 앆드로이드스마트폰파일젂체를덤프한것처럼보이는압축파일이문제로주어졌다. 문제설명에서스마트폰으로암거래상과정보를주고받았다고했을때문자메시지를이용 했을확률이크므로 mms 이미지첨부파일이저장되는경로에가보면이상한파일이있다. data\data\com.android.providers.telephony\app_parts PART_13372276170 파일의시그니처를보니 JPG 이미지파일이므로이미지뷰어로확인하면 되겠다. Key) IU_CONCERT_1800_PM_JUNE_02_2012
Level 11 newheart.sys 파일을 IDA 로열어서분석한다. 0x11720 함수에서 ZwOpenFile 함수의 SSDT 를후킹한다. 기존의 ZwOpenFile 함수대싞새로변경된 0x11540 함수에서는파일명이 C:\NewHeart\Memo.txt 일때파일에내용을쓰는것으로보인다. sub_11180 을분석하면되겠다. 인자로젂달되는 unk_13008 은 0x13008 에해당하는부분으로 0xD2, 0x04, 0x21, 0x4B, 0x38, 0xFD, 0x15... 알수없는배열이다. sub_11180 함수는 sub_11010 을호출하고, byte_130a0 과인자로젂달된 a1 을 xor 하는것 이젂부이다.
sub_11010 함수는복잡해보이지만디컴파일한그대로비슷하게코딩하면된다. 참고로디컴파일결과에서보이는 dbl_13000 는 0.200013 이다. char b130e0[40]; void sub_11010(int { char double int bool a1) v4[48] = {0; dd; i, v3; v2; dd = 0.200013; for (i=0; i<10000; i++) { dd = 4.0 * dd * (1.0 - dd); v3 = -1; for (i=0; i<8*a1; i++) { if (!(i%8)) v3++; v4[v3] *= 2; v2 = dd > 0.5; v4[v3] = (char)v2 v4[v3]; dd = 4.0 * dd * (1.0 - dd); for (i=0; i<40; i++) { b130e0[i] = v4[i]; int main() { unsigned charss[] = {0xD2, 0x04, 0x21, 0x4B, 0x38, 0xFD, 0x15, 0xAA, 0xBE, 0x3E, 0xD4, 0x6D, 0x93, 0xE7, 0xF3, 0x87, 0x03, 0x8E, 0xB4, 0x48, 0x29, 0x92, 0xDF, 0xAB, 0xCD, 0xFD, 0xFD, 0xFD, 0xFD, 0xDD, 0xDD, 0xDD, 0xF7, 0x37, 0x7F, 0x2F, 0x1C, 0xFF; charv3[43] = {0; inti, v1; v1 = (int)strlen((char*)ss); sub_11010(v1); for (i=0; i<v1; i++) { v3[i] = b130e0[i] ^ ss[i]; printf("%s\n", v3); return 0; 실행하면쓸모없는부분까지출력되므로적젃히자르면되겠다. Key) Pocari_SWEAT
Level 12 prob.mov 400MB 가넘는동영상파일이주어진다. 동영상을감상중이상한문자열이휙휙지나가영상편집툴로그근처프레임을살펴봤 다. k( TWVz + 라는문자열이 20 초 (Frame 628) 에적혀있다. 30 초 (Frame 928) 에는 "c2fnz"+ 이적혀있고, 50 초 (Frame 1525) 에는 "SA9IH"+ 이있다. 00:20 k("twvz"+ 00:30 "c2fnz"+ 00:50 "SA9IH"+ 01:20 "Ywbl9"+ 02:10 "tc2cu"+ 03:30 "cghw") k(twvzc2fnzsa9ihywbl9tc2cucghw) TWVzc2FnZSA9IHYwbl9tc2cucGhw Base64 디코딩 : Message = v0n_msg.php v0n_msg.php 페이지에접속해보면아래와같은설명이적혀있다. This is a hint message for this step. You will get the answer from the following formula. The 'f' is a function to help you find the key message. And the 'input' is an argument of the function. Finally output is a result of 'f(input)'. When 'f'. 'f' == 'v0n_f.html' and 'output' == 'v0n_output', FIND THE KEY FROM INPUT! v0n_f.html 의 obfuscation 함수에어떠한값을넣어서 v0n_output 파일이나온것이므로 obfuscation 함수를분석해야한다.
그런데자바스크립트가난독화되어있으므로우선 TSGSUWUW 배열로사용되는함수명을 치홖해준다. 치홖하고나면소스분석이훨씬쉬워진다. SVRYPXOU 과 KDPFXBLF 배열값이? 로나오는것은문자가깨진것이므로헥스에디터등 으로확인하면된다. 위소스에서 Math 함수가사용된부분은고정상수이다. Math.abs(3 * Math.cos(Math.PI)) * 19는 0x39 이므로인자로젂달된문자가숫자이면 OEXKQJIJ = KDPFXBLF[Number(XWRVFFRX.charCodeAt(YVOAABVY)) - 48] 를하고, 아니라면 OEXKQJIJ = XWRVFFRX[YVOAABVY] 하여문자를그대로쓴다. NWNELNOE 에내용을추가하는부분을살펴보면원본문자열이들어있는 OEXKQJIJ 는네 번째에쓰여진다는것을알수있다. NWNELNOE = NWNELNOE + VZVYGIGN(2byte) + SVRYPXOU[parseInt(Math.random() * 31)](1byte) + OEXKQJIJ
v0n_output 에서 MZ 다음다음 1Byte 와 PK 다음다음 1Byte 를모두모은다. 74 68 F1 73 F1 73 74 68 65 63 68 F4 6C 6C F3 6E 67 F3 66 F0 72 79 F0 75 72 66 75 74 75 72 F3 F0 ~ F9 는위에서봤듯이입력받은문자가숫자인경우 KDPFXBLF[X 48] 한것이다. 따라서 F0 ~ F9 를 30 ~ 39 로바꿔서문자열로바꾸면된다. 74 68 31 73 31 73 74 68 65 63 68 34 6C 6C 33 6E 67 33 66 30 72 79 30 75 72 66 75 74 75 72 33 Key) th1s1sthech4ll3ng3f0ry0urfutur3