Junior CTF Write-Up 서울대원고등학교 404error[ 현성원 ]

Similar documents
歯9장.PDF

chap7.key

<443A5C4C C4B48555C B3E25C32C7D0B1E25CBCB3B0E8C7C1B7CEC1A7C6AE425CBED0C3E0C7C1B7CEB1D7B7A55C D616E2E637070>

BMP 파일 처리

Microsoft Word - Crackme 15 from Simples 문제 풀이_by JohnGang.docx

Microsoft PowerPoint - chap02-C프로그램시작하기.pptx

Microsoft PowerPoint - chap13-입출력라이브러리.pptx

The Pocket Guide to TCP/IP Sockets: C Version

PowerPoint 프레젠테이션

학습목차 2.1 다차원배열이란 차원배열의주소와값의참조

슬라이드 1

hlogin2

2015 CodeGate 풀이보고서 김성우 1. systemshock strcat(cmd, argv[1]); 에서스택버퍼오버플로우가발생합니다

<4D F736F F F696E74202D20B8AEB4AABDBA20BFC0B7F920C3B3B8AEC7CFB1E22E BC8A3C8AF20B8F0B5E55D>


Microsoft PowerPoint - polling.pptx

Microsoft Word - ntasFrameBuilderInstallGuide2.5.doc

버퍼오버플로우-왕기초편 10. 메모리를 Hex dump 뜨기 앞서우리는버퍼오버플로우로인해리턴어드레스 (return address) 가변조될수있음을알았습니다. 이제곧리턴어드레스를원하는값으로변경하는실습을해볼것인데요, 그전에앞서, 메모리에저장된값들을살펴보는방법에대해배워보겠습

T100MD+

PowerPoint 프레젠테이션

비트와바이트 비트와바이트 비트 (Bit) : 2진수값하나 (0 또는 1) 를저장할수있는최소메모리공간 1비트 2비트 3비트... n비트 2^1 = 2개 2^2 = 4개 2^3 = 8개... 2^n 개 1 바이트는 8 비트 2 2

금오공대 컴퓨터공학전공 강의자료

PowerPoint Presentation

제1장 Unix란 무엇인가?

<443A5C4C C4B48555C B3E25C32C7D0B1E25CBCB3B0E8C7C1B7CEC1A7C6AE425CBED0C3E0C7C1B7CEB1D7B7A55C4C656D70656C2D5A69762E637070>

PowerPoint 프레젠테이션

프로그램을 학교 등지에서 조금이라도 배운 사람들을 위한 프로그래밍 노트 입니다. 저 역시 그 사람들 중 하나 입니다. 중고등학교 시절 학교 도서관, 새로 생긴 시립 도서관 등을 다니며 책을 보 고 정리하며 어느정도 독학으르 공부하긴 했지만, 자주 안하다 보면 금방 잊어

PowerPoint 프레젠테이션

K&R2 Reference Manual 번역본

Microsoft PowerPoint - 3ÀÏ°_º¯¼ö¿Í »ó¼ö.ppt

금오공대 컴퓨터공학전공 강의자료

SRC PLUS 제어기 MANUAL

02.Create a shellcode that executes "/bin/sh" Excuse the ads! We need some help to keep our site up. List Create a shellcode that executes "/bin/sh" C

API 매뉴얼

슬라이드 1

금오공대 컴퓨터공학전공 강의자료

Poison null byte Excuse the ads! We need some help to keep our site up. List 1 Conditions 2 Exploit plan 2.1 chunksize(p)!= prev_size (next_chunk(p) 3

<443A5C4C C4B48555C B3E25C32C7D0B1E25CBCB3B0E8C7C1B7CEC1A7C6AE425CC0E7B0EDB0FCB8AE5C53746F636B5F4D616E D656E74732E637070>

Microsoft PowerPoint - chap03-변수와데이터형.pptx

INTRO Basic architecture of modern computers Basic and most used assembly instructions on x86 Installing an assembly compiler and RE tools Practice co

À©µµ³×Æ®¿÷ÇÁ·Î±×·¡¹Ö4Àå_ÃÖÁ¾

프로그래밍개론및실습 2015 년 2 학기프로그래밍개론및실습과목으로본내용은강의교재인생능출판사, 두근두근 C 언어수업, 천인국지음을발췌수정하였음

Microsoft PowerPoint - 제11강 파일 처리

8 장데이터베이스 8.1 기본개념 - 데이터베이스 : 데이터를조직적으로구조화한집합 (cf. 엑셀파일 ) - 테이블 : 데이터의기록형식 (cf. 엑셀시트의첫줄 ) - 필드 : 같은종류의데이터 (cf. 엑셀시트의각칸 ) - 레코드 : 데이터내용 (cf. 엑셀시트의한줄 )

커알못의 커널 탐방기 이 세상의 모든 커알못을 위해서

< E20C6DFBFFEBEEE20C0DBBCBAC0BB20C0A7C7D12043BEF0BEEE20492E707074>

임베디드시스템설계강의자료 6 system call 2/2 (2014 년도 1 학기 ) 김영진 아주대학교전자공학과

Microsoft PowerPoint - ch07 - 포인터 pm0415

PathEye 공식 블로그 다운로드 받으세요!! 지속적으로 업그래이드 됩니다. 여러분의 의견을 주시면 개발에 반영하겠 습니다.

$ret = ""; $socket = fsockopen(" ", 8888, $errno, $errstr, 100); fgets( $socket, 50); fgets( $socket, 50); $ret.= fgets( $socket, 50); $

Microsoft PowerPoint - chap06-1Array.ppt

Chapter #01 Subject

휠세미나3 ver0.4

The Pocket Guide to TCP/IP Sockets: C Version

4. #include <stdio.h> #include <stdlib.h> int main() { functiona(); } void functiona() { printf("hihi\n"); } warning: conflicting types for functiona

PowerPoint 프레젠테이션

10.

Microsoft PowerPoint - a10.ppt [호환 모드]

JuniorCTF 2013 예선풀이보고서 김성우 ( cd80 )

PowerPoint Template

ISP and CodeVisionAVR C Compiler.hwp

JAVA 프로그래밍실습 실습 1) 실습목표 - 메소드개념이해하기 - 매개변수이해하기 - 새메소드만들기 - Math 클래스의기존메소드이용하기 ( ) 문제 - 직사각형모양의땅이있다. 이땅의둘레, 면적과대각

Microsoft PowerPoint 웹 연동 기술.pptx

1.2 자료형 (data type) 프로그램에서다루는값의형태로변수나함수를정의할때주로사용하며, 컴퓨터는선언된 자료형만큼의메모리를확보하여프로그래머에게제공한다 정수 (integer) 1) int(4 bytes) 연산범위 : (-2 31 ) ~ (2 31 /2)-

C++ Programming

Microsoft PowerPoint - ch09 - 연결형리스트, Stack, Queue와 응용 pm0100

Microsoft PowerPoint Android-SDK설치.HelloAndroid(1.0h).pptx

제 14 장포인터활용 유준범 (JUNBEOM YOO) Ver 본강의자료는생능출판사의 PPT 강의자료 를기반으로제작되었습니다.

untitled

본 강의에 들어가기 전

PowerPoint 프레젠테이션

13 주차문자열의표현과입출력

<4D F736F F F696E74202D20BBB7BBB7C7D15F FBEDFB0A3B1B3C0B05FC1A638C0CFC2F72E BC8A3C8AF20B8F0B5E55D>

<4D F736F F F696E74202D20B8B6C0CCC5A9B7CEC7C1B7CEBCBCBCAD202839C1D6C2F7207E203135C1D6C2F >

PowerPoint Template

chap 5: Trees

Microsoft PowerPoint - chap10-함수의활용.pptx

목차 BUG DEQUEUE 의 WAIT TIME 이 1 초미만인경우, 설정한시간만큼대기하지않는문제가있습니다... 3 BUG [qp-select-pvo] group by 표현식에있는컬럼을참조하는집합연산이존재하지않으면결괏값오류가발생할수있습니다... 4

Microsoft Word - src.doc

<B1E2BCFAB9AEBCAD5FB9DABAB4B1D45F F F64746F72732E687770>

PowerPoint Presentation

Microsoft PowerPoint - chap06-2pointer.ppt

강의 개요

Microsoft Word - PLC제어응용-2차시.doc

(Asynchronous Mode) ( 1, 5~8, 1~2) & (Parity) 1 ; * S erial Port (BIOS INT 14H) - 1 -

C 언어 프로그래밊 과제 풀이

Cookie Spoofing.hwp

Microsoft PowerPoint - Chapter_04.pptx

슬라이드 1

C# Programming Guide - Types

PowerPoint Presentation

PowerPoint 프레젠테이션

(SW3704) Gingerbread Source Build & Working Guide

<4D F736F F F696E74202D20B8B6C0CCC5A9B7CEC7C1B7CEBCBCBCAD202834C1D6C2F7207E2038C1D6C2F729>

Install stm32cubemx and st-link utility

본교재는수업용으로제작된게시물입니다. 영리목적으로사용할경우저작권법제 30 조항에의거법적처벌을받을수있습니다. [ 실습 ] 스위치장비초기화 1. NVRAM 에저장되어있는 'startup-config' 파일이있다면, 삭제를실시한다. SWx>enable SWx#erase sta

Adobe Flash 취약점 분석 (CVE )

Microsoft PowerPoint - 제9강 문자열

untitled

Microsoft PowerPoint - 6.pptx

Transcription:

Junior CTF Write-Up 서울대원고등학교 404error[ 현성원 ]

Result 대회종료후 1 ~ 10 위까지의 Score Board.

Level0 문제 : 자, 이제부터해커테스트를시작하겠습니다! 본과정은실제작전인 " 본선 " 을위한사전테스트입니다. 따라서어느정도의실력만갖추고있다면크게어렵진않으실겁니다. 위메뉴들중 " 대회규칙 " 을꼼꼼히 읽어주시고, 특히부정행위는엄격히 금지된다는점을명심해주십시오. 대회규칙을모두확인했다면 아래입력폼에 " 확인 " 을입력하십시오. Flag : 확인

Level 1 자, 그럼첫번째문제입니다. 우선아주간단한문제부터내볼까요? 로봇들은종종암호문을이용하여통신을합니다. 하지만그방식은모두과거에우리인간들이만든알고리즘이죠. 심지어고대의암호방식을그대로사용할때도있습니다. 다음의암호문을한번해석해보십시오. HQGOHVVURERWZDU 고대암호중 Vigenère 가있는데디코딩을해주는페이지가있다. 주소 : http://smurfoncrack.com/pygenere/ Length of codewords to try: 1 로설정해두고복호화시킨다 Flag : ENDLESSROBOTWAR

Level2 다음은리버싱실력을확인하는문제입니다. [ 다운로드 ] 위바이너리를분석하여인증루틴의작동원리를밝혀내보세요. 인증성공에사용되는값이바로정답입니다. 처음윗부분에서입력한값을받고한글자씩 0x99와 xor 하면서비교하고있다. 원본값 xor 0x99 = 암호화된값 이므로 암호화된값 xor 0x99 를하면원본값이나올것이다. 간단한스크립트를작성하여문제풀이를진행했다. #ctf_2.py encrypted = ("\xf1\xfc\xf5\xf5\xf6\xb9\xf3\xec\xf7\xf0" "\xf6\xeb\xb9\xf1\xf8\xfa\xf2\xfc\xeb\xea") plaintext = "" for i in range(len(encrypted)): plaintext += chr(ord(encrypted[i])^0x99) print plaintext C:\Users\sweetchip\Desktop>ctf_2.py hello junior hackers Flag : hello junior hackers

Level 3 http://115.68.24.145/junior_ctf/policy_chal/ 에 접근하여 ID 와 Password 를획득하세요. * 여러분이시도할수있는 ID는 admin_1000 부터 admin_9999까지존재합니다. ( 자유롭게 1000 부터 9999 중에하나를선택하세요. 예를들어 admin_7777, admin id 1000~9999 중하나만선택해서알아내면됩니다. 모든 id의 password를알필요는없습니다. * 이는여러사람이동시에풀었을때 서로방해받지않도록하기위함입니다. 주어진링크를들어가보면원본 php 소스파일이들어있다 <!--login_ok.phps--> <?php $id = $_GET['id']; $pass = $_GET['pass'];... 생략... $fp = @fopen("./id_pass_db/". $id. "_pass.txt", "r");... 생략...?> if($pass == $real_password) echo "Congrats! You got the password: $pass"; include "../../../key.php"; exit(0);... 생략...

먼저 id와 pw를인자로받고 $fp = @fopen("./id_pass_db/". $id. "_pass.txt", "r"); 이부분에의해인자로넘겨진아이디와합쳐진다. 그리고저파일을열어패스워드를받아오고사용자가입력한패스워드와일치한다면통과시키고 Key를출력한다. 예를들어 id를 admin_1207 로입력한다면./id_pass_db/admin_1207_pass.txt 파일을열어패스워드를받아올것이다. 소스분석이완료되었으니실제로요청을했다. http://115.68.24.145/junior_ctf/policy_chal/id_pass_db/admin_1207_pass.txt 243 243 이라는패스워드를얻었고이제다시로그인페이지로돌아가서아이디와비밀번호를입력하면된다. 하지만대회가끝난후 1207번호는너무많은시도로인해아이디가 block 되어있어서 admin_1208로재시도했다. // id = admin_1208, pw = 904 Congrats! You got the password: 904 The key is 'iamapolicyhacker' Flag : iamapolicyhacker

Level 4 자, 이제부터는쭈욱리눅스로진행됩니다. 리눅스사용경험이많길바랍니다. 이번문제는로컬문제이고바이너리를분석하여풀이를인증하기위한키를획득하세요. [SSH 정보 ] IP: 112.172.160.241 PORT: 2323 ID: guest_chaos Password: fpdkfgenius * 문제바이너리위치 : /home/chaos/chal 처음입력하고바로 Key 가나왔다. 아마 input 값이음수가돼야일정확률로킷값이출력되는것같다. guest_chaos@ubuntu:/home/chaos$./chal ----------------------------------- Let me know what UID you want to be (Except root UID - 0) UID: %s Ok.. you input -1217003520 UID Key: GoGoGoHackers! Flag : GoGoGoHackers!

Level5 역시리눅스로컬문제이고바이너리를분석하여풀이를인증하기위한키를획득하세요! [SSH 정보 ] IP: 112.172.160.241 PORT: 2323 ID: guest_money Password: greathacker 문제바이너리위치 : /home/money/chal void cdecl sub_80485c4(int a1, int a2) FILE *v2; // [sp+24h] [bp-2834h]@1 int v3; // [sp+28h] [bp-2830h]@7 int v4; // [sp+2738h] [bp-120h]@1 int v5; // [sp+2838h] [bp-20h]@1 v5 = 0; memset(&v4, 0, 0x100u); v2 = fopen("./secret_key", "r");.. 생략.. fgets((char *)&v5, 19, v2); fclose(v2); fgets((char *)&v4, 19, stdin); if (!strcmp((const char *)&v5, (const char *)&v4) ) system("echo you got me"); exit(0); while ( 1 ) gets((char *)&v3); // Vuln! memcpy(&v4, &v3, strlen((const char *)&v3)); printf("buf: %s\n", &v4); 서버에서바이너리가주어지고다운로드후 IDA로분석한다. 일단코드에서쓰레기코드부분이나필요없는부분은모두삭제시켰다. 개인적으로푼문제중이문제가가장어려웠던것같다.

분석을해보면시크릿파일을열고변수 v5에값을저장한다음, 사용자입력을받는데, 그입력값과 key가일치하면 you got me를띄워준다. 그뒤로 while문에들어가는데, v3에사용자입력을다시한번받고, memcpy로 v4에복사하고 v4를출력한다. 일단이프로그램의메모리구조는 [Data][v4][v5][Data] 이렇게되는데, fgets로 v3에넣고 memcpy로 v4에복사한다. 그리고 v4와 v5 사이에는초기의 memset으로 null문자가끼워져있으므로기본적으로 print를하면잘라지게된다. 그렇다면 v4에 v5바로직전까지데이터를삽입하면같은 v4로인식해서 Flag를출력할것이다. 간단하게다시설명하면 [Data] [v4 = user input and some nulls ] [v5 = flag] [Data] 의구조에서 [Data] [A*256 (no nulls)] [Flag] [Data] 로입력하면 Flag 도같이출력될것이다. guest_money@ubuntu:/home/money$./chal i dont know passkey bb buf: y bbnt know passke AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAA buf: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAADidYouLikeIt? Flag : DidYouLikeIt?

Level6 와우..! 잘하고계십니다. 다음바이너리역시분석하여풀이를인증하기위한키를획득하세요! [SSH 정보 ] IP: 112.172.160.241 PORT: 2323 ID: guest_monkey Password: awesomeboy 문제바이너리위치 : /home/monkey/chal int cdecl view(int a1) int v1; // eax@1 int result; // eax@6 FILE *stream; // [sp+28h] [bp-150h]@4 char s; // [sp+2ch] [bp-14ch]@6 char filename; // [sp+12ch] [bp-4ch]@1 int v6; // [sp+16ch] [bp-ch]@1 snprintf(&filename, 0x40u, "list/%s.txt", a1); // LOBYTE(v1) = issymbolic((int)&filename); if ( v1 ) puts("no symbolic file."); exit(0); stream = fopen(&filename, "rb"); if (!stream ) exit(0); memset(&s, 0, 0x100u); fgets(&s, 200, stream); printf("%s", &s); return result; Setuid가걸린로컬서버의바이너리를인자를넘겨실행하는방식의프로그램이다. 이문제도역시푸는데많은고민을했었는데, 문제의의도는 list 폴더에있는파일을읽는대신 flag 파일을읽는것으로추정하고코드를살펴봤다. 문제의코드는 snprintf 인데, 0x40바이트만큼읽는것이다. 그렇다면다음과같이생각해볼수있다 list/1.txt 시작점 64byte 제한점

목표는 Flag를봐야하는것인데, 따로필터링을하지않아서../ 도삽입이가능하다. 하지만뒤의.txt 문자열을없애야하는데고민끝에아이디어가생각났다. list////////////////////////////////////////////////////////////../1.txt 시작점 64byte 제한점 snprintf 에서는 64바이트만복사하게되어있으므로 64바이트이후엔잘리게된다. 그것을이용하여.txt를잘리게만들고원하는파일을읽을수있다. 적절하게문자열길이를계산한다음서버에입력한다. guest_monkey@ubuntu:/home/monkey$./../////////////////////////////////////////////////secret guest_monkey@ubuntu:/home/monkey$./..////////////////////////////////////////////////secret real cool secret./chal./chal *63 바이트일때답이나오는이유는끝에 null 문자가붙어서이기때문으로추정됨 Flag : real cool secret

level7 리눅스로컬문제이고바이너리를분석하여풀이를인증하기위한키를획득하세요! [SSH 정보 ] IP: 112.172.160.241 PORT: 2323 ID: guest_thepub Password: talentedgirl 문제바이너리위치 : /home/thepub/chal 역시마찬가지로문제서버에바이너리가존재한다. 바이너리를얻은다음분석했다. int cdecl sub_8048564() time_t v0; // ST34_4@4 int result; // eax@9 int v2; // ecx@9 unsigned int i; // [sp+28h] [bp-120h]@4 int v4; // [sp+2ch] [bp-11ch]@4 FILE *v5; // [sp+30h] [bp-118h]@1 int v6; // [sp+38h] [bp-110h]@1 char v7; // [sp+138h] [bp-10h]@4 int v11; // [sp+13ch] [bp-ch]@1 memset(&v6, 0, 0x100u); v5 = fopen("./secret_key.txt", "r"); if (!v5 ) puts("error: secret key file open."); exit(0); fgets((char *)&v6, 100, v5); fclose(v5); v0 = time(0); v7 = v0; v4 = 0; for ( i = 0; i < strlen((const char *)&v6); ++i ) if ( v4 == 4 ) v4 = 0; *((_BYTE *)&v6 + i) ^= *(&v7 + v4++); result = printf("buf = %s\n", &v6); return result;

간단하게바이너리를분석해보면킷값을읽고버퍼에저장한다음, 현재시간을 hex로바꿔서킷값과현재시간을 xor 연산하고출력하는프로그램이다. 그러므로연산당시의서버시간과연산으로나온암호화된값을다시 xor 연산하면원본문자열이나올것이다. 서버에서 netcat이설치되어있어서내서버로바이너리실행결과를보내서 dump하고, 서버시간을알아내서 xor하는스크립트를작성했다. 현재시간은 date를이용해서알아낸다. 오차가있을수잇으므로 1, +1 초도연산해본다. f = open("./a.dmp","rb") #buf dump file a = f.read() f.close() #\x1e\xe0\xb3\x08\x11\xf3\xa6\x06\x11\xfb\xa6\x14\x11\xf3\xa6\x5b b = "\x51\xf2\xb2\x59"[::-1] j=0 c = "" for i in range(0, len(a)): if j == 4: j=0 c += chr(ord(a[i]) ^ ord(b[j])) j = j+1 print "Flag : "+c ################################################################# J:\script>J:\script\1.py Flag : GRAYHATWHITEHAT Flag : GRAYHATWHITEHAT

Level8 리눅스로컬문제이고바이너리를분석하여풀이를인증하기위한키를획득하세요! [SSH 정보 ] IP: 112.172.160.241 PORT: 2323 ID: guest_paper Password: cleverpeople 문제바이너리위치 : /home/paper/chal IDA로파일을열면오류가뜨지만버전에따라서오류로인해죽는버전도있고그대로분석을성공하는버전도있다. 처음대회때사용한버전은그대로분석이되어서루틴을볼수있었는데, 추후에다른버전으로로딩시켜보니에러가났다. 그러므로서버에서 readelf 로살펴봤다 guest_paper@ubuntu:/home/paper$ readelf chal -a more readelf: Error: ELF Header: Out of memory allocating 0xc70804b0 bytes for 32-bit relocation data Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 한눈에봐도뭔가이상한값으로변조가되어있다는것을알고바이너리를받아서 WinHex 로연다음 0x12d0 지점에서 b0 04 08 c7을 b0 00 00 00 으로변경하고 IDA로로딩했더니몇번오류가난다음정상적으로로드되었고분석을시작했다. int cdecl main(int a1, int a2) void *v2; // edx@1 unsigned int v3; // ebx@1 char v4; // sp@1 int v5; // edi@3 int v6; // edx@3 void *v7; // edx@16 unsigned int v8; // ebx@16 char v9; // sp@16 int v10; // edi@18 int v11; // edx@18 int result; // eax@22 int v13; // ecx@22 unsigned int i; // [sp+20h] [bp-128h]@10

FILE *v15; // [sp+28h] [bp-120h]@16 int16 v16; // [sp+2eh] [bp-11ah]@1 int v17; // [sp+30h] [bp-118h]@2 signed int v18; // [sp+12eh] [bp-1ah]@1 signed int v19; // [sp+132h] [bp-16h]@1 signed int v20; // [sp+136h] [bp-12h]@1 signed int16 v21; // [sp+13ah] [bp-eh]@1 int v22; // [sp+13ch] [bp-ch]@1 v22 = *MK_FP( GS, 20); v18 = 1936287860; // v18 = 'siht'; v19 = 1601399135; // v19 = '_si_'; v20 = 1819044211; // v20 = 'llis'; v21 = 121; // v21 = 'y'; -> this_is_silly v2 = &v16; v3 = 256; if ( (v4 + 46) & 2 ) v16 = 0; v2 = &v17; v3 = 254; memset(v2, 0, 4 * (v3 >> 2)); v5 = (int)((char *)v2 + 4 * (v3 >> 2)); v6 = (int)((char *)v2 + 4 * (v3 >> 2)); if ( v3 & 2 ) *(_WORD *)v5 = 0; v6 = v5 + 2; if ( v3 & 1 ) *(_BYTE *)v6 = 0; if ( a1!= 2 ) puts("i need an argument."); exit(0); for ( i = 0; i < strlen((const char *)&v18); ++i ) *((_BYTE *)&v16 + i) = *(_BYTE *)(*(_DWORD *)(a2 + 4) + i) ^ 0x30;

if ( strcmp((const char *)&v18, (const char *)&v16) ) puts("don't match."); exit(0); v15 = fopen("./secret", "rb"); v7 = &v16; v8 = 256; if ( (v9 + 46) & 2 ) v16 = 0; v7 = &v17; v8 = 254; memset(v7, 0, 4 * (v8 >> 2)); v10 = (int)((char *)v7 + 4 * (v8 >> 2)); v11 = (int)((char *)v7 + 4 * (v8 >> 2)); if ( v8 & 2 ) *(_WORD *)v10 = 0; v11 = v10 + 2; if ( v8 & 1 ) *(_BYTE *)v11 = 0; fgets((char *)&v16, 100, v15); fclose(v15); result = puts((const char *)&v16); if ( *MK_FP( GS, 20)!= v22 ) stack_chk_fail(v13, *MK_FP( GS, 20) ^ v22); return result; 소스가이전보다많이길어져서그냥수정없이풀이에기록했다. 대충분석해보면실질적으로쓰이는부분은얼마되지않고대부분은분석을어렵게하는쓰레기코드이다. 높은버전의 IDA로분석해보면 strcpy로 this_is_silly를복사하고다른변수에저장한다. [ 아마헤더를정확히맞춰주면 strcpy가나올것이다.] 또밑으로내려가보면사용자가입력한문자열과 0x30으로 xor 연산하는것을볼수있는데, xor 한것과 this_is_silly를비교한뒤맞으면 key를출력하는방식이다. 그러므로 this_is_silly를 0x30과 xor 한다음그문자열을넣으면답이출력될것이다.

위를토대로문자열을 xor 시키는간단한스크립트를작성했다. a = "this_is_silly" b="" for i in range(len(a)): b += chr(ord(a[i]) ^ 0x30) print b C:\Users\sweetchip\Documents\for\script>2.py DXYCoYCoCY\\I ################################################################## guest_paper@ubuntu:/home/paper$./chal DXYCoYCoCY\\\\I wow ultra secret 하지만인증이안돼서 \ 를 \\ 로입력했더니인증이되었다. 아마 \\ 를 \ 로인식하기때문인것같다. Flag : wow ultra secret