메뉴 닫기

X-MAS CTF 2018 Write-up (Only Reversing)

* 팀 블로그에 제가 작성했던 글을 그대로 가져온 것 입니다.

Endless Christmas


이렇게 /tmp 폴더에 파일을 계속 드랍하는 형식입니다.

실행을 시켜주고, 가장 마지막에 드랍된 파일을 가져와, 분석을 해보면 손쉽게 플래그를 얻을 수 있습니다.

 

#include<stdio.h>
int main(void) {
	/* 제목없음1 (2018-12-23 오후 2:42:38)
	StartOffset: 00000000, EndOffset: 00000039, 길이: 0000003A */

	unsigned char rawData[58] = {
		0x55, 0x20, 0x40, 0x4C, 0x5E, 0x76, 0x69, 0x3E, 0x6E, 0x3D, 0x69, 0x3E,
		0x52, 0x39, 0x3B, 0x39, 0x3C, 0x63, 0x52, 0x39, 0x63, 0x69, 0x52, 0x39,
		0x3B, 0x39, 0x3C, 0x63, 0x52, 0x39, 0x63, 0x69, 0x52, 0x39, 0x3B, 0x39,
		0x3C, 0x63, 0x52, 0x39, 0x63, 0x69, 0x52, 0x39, 0x3B, 0x39, 0x3C, 0x63,
		0x52, 0x39, 0x63, 0x69, 0x52, 0x6B, 0x61, 0x39, 0x3B, 0x70
	};

	for(int i=0; i<58; i++)
		rawData[i] ^= 0xD;
	printf("%s",rawData);
}

FLAG : X-MAS{d3c0d3_4641n_4nd_4641n_4nd_4641n_4nd_4641n_4nd_fl46}

 

CatanaGift

이건 제가 바이너리를 분실해서..ㅜㅜ 간단하게 코드만 작성합니다.

 

import angr

def hook_func(s):
    MyList = [1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440, 9694845, 35357670, 129644790, 477638700, 1767263190, 6564120420, 24466267020, 91482563640, 343059613650, 1289904147324, 4861946401452, 18367353072152, 69533550916004, 263747951750360, 1002242216651368, 3814986502092304, 14544636039226909, 55534064877048198, 212336130412243110, 812944042149730764, 3116285494907301262, 11959798385860453492, 45950804324621742364]
    #print((s.regs.eax))
    s.regs.rax = int(MyList[ s.solver.eval(s.regs.eax) ] )
def main():
    p = angr.Project("catana")
    state = p.factory.blank_state()
    simgr = p.factory.simgr(state)

    p.hook(0x40062D,hook_func,length = 5)
    simgr.explore(find = 0x40074A)
    found = simgr.found[0]
    print (found)
    print (found.posix.dumps(1))
main()

중간에 살펴보시면, 카탈랑 수를 구하는 함수가 하나 있는데, 비효율적으로 구현되어 있습니다. angr의 hook기능을 이용하여 해당 함수를 호출하는 부분을 슥삭삭 하면, 플래그를 얻을 수 있습니다.

 

Santa thinks you’re trustworthy

 

이 문제를 열어보시면… 뭔가 복잡하고, 중간중간에 Hex-Rays 를 방지하기 위한 트릭도 몇몇개 적용되어 있습니다. 해당 부분을 Keystone을 이용해서 NOP등등으로 밀고 분석해보면 간단한 틱택토 게임임을 알 수 있습니다. 패킷을 전송할때, 현재 게임 판 앞,뒤로 특정한 값을 달아서 전송하는데, 해당 부분만 구현해서, 플레이어가 이긴 상태인 게임판 상태를 전송해 주면, 플래그를 얻을 수 있습니다.

import socket


BOARD = ['X','X','X',' ',' ',' ',' ',' ',' ']


def recv_until(s,st):  # receive until you encounter a string
    ret = ""
    while st not in ret:
	    ret += s.recv(1)

    return ret

def serialize():
    ret_list = [0xff]
    for i in xrange(0,9):
        ret_list.append(ord(BOARD[i]))
    v4 =0
    for i in xrange(0,10):
        v4 ^= ret_list[i]
    ret_list.append(v4)
    return str(bytearray(ret_list))


s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("199.247.6.180",11000))
s.send(serialize())
print s.recv(1024)

FLAG : X-MAS{cl13n7v4l1d4710n_5uck5___}

Friedrich’s Christmas Hangover

이 문제도 trustworthy 와 거의 같은 Hex-Rays를 방지하기 위한 트릭 몇몇개가 적용되어 있습니다. 역시 같은 방법으로 keystone을 이용하여 nop으로 밀어버리고 분석해보면, 연립방정식이 나옵니다. 전부 형태가 같아서 그냥 numpy로 풀었습니다~

 

# -*- coding: cp949 -*-
import numpy as np

res = np.array([0x606EB, 0x6DCB8, 0x5AC28, 0x62B72, 0x60332, 0x8589F, 0x75F44, 0x5ABC9, 0x5EB6B, 0x4CE54, 0x6E0DB, 0x5FB34, 0x573A5, 0x621F7, 0x5D0BD, 0x4C56B, 0x6AE76, 0x62309, 0x6A537, 0x60389, 0x612D0, 0x50A71, 0x6AE39, 0x5D651, 0x5B857, 0x4E896, 0x7A2EB, 0x641C1, 0x5845E, 0x6C126, 0x66950, 0x6E5D5, 0x4E957, 0x6379D, 0x60298, 0x633A4,])

eqs = np.array([
[ 113 , 9 , 62 , 255 , 168 , 139 , 193 , 15 , 126 , 17 , 112 , 174 , 74 , 87 , 250 , 40 , 251 , 103 , 143 , 223 , 176 , 100 , 33 , 196 , 206 , 168 , 49 , 49 , 75 , 25 , 154 , 82 , 157 , 161 , 27 , 130 , ],
[ 173 , 186 , 213 , 80 , 242 , 178 , 173 , 241 , 225 , 151 , 230 , 56 , 83 , 215 , 3 , 188 , 236 , 237 , 59 , 252 , 55 , 38 , 194 , 170 , 236 , 15 , 141 , 61 , 254 , 47 , 169 , 12 , 160 , 9 , 27 , 237 , ],
[ 71 , 211 , 212 , 104 , 214 , 94 , 80 , 199 , 62 , 224 , 31 , 160 , 113 , 105 , 51 , 148 , 193 , 33 , 112 , 27 , 40 , 36 , 220 , 197 , 78 , 234 , 82 , 58 , 235 , 50 , 39 , 38 , 236 , 227 , 15 , 42 , ],
[ 233 , 202 , 174 , 98 , 89 , 151 , 23 , 46 , 131 , 59 , 98 , 202 , 64 , 136 , 219 , 122 , 249 , 188 , 44 , 180 , 14 , 130 , 66 , 191 , 76 , 142 , 214 , 162 , 192 , 197 , 236 , 113 , 36 , 45 , 183 , 18 , ],
[ 138 , 131 , 139 , 154 , 140 , 32 , 233 , 18 , 126 , 8 , 101 , 17 , 130 , 182 , 75 , 160 , 174 , 184 , 99 , 214 , 133 , 156 , 128 , 188 , 147 , 143 , 170 , 73 , 102 , 28 , 94 , 63 , 196 , 242 , 41 , 157 , ],
[ 7 , 34 , 46 , 228 , 108 , 214 , 27 , 192 , 193 , 254 , 148 , 133 , 181 , 213 , 193 , 181 , 159 , 222 , 245 , 159 , 142 , 207 , 146 , 88 , 180 , 254 , 238 , 103 , 206 , 254 , 219 , 78 , 176 , 235 , 157 , 250 , ],
[ 72 , 213 , 201 , 174 , 240 , 243 , 75 , 197 , 108 , 48 , 32 , 75 , 44 , 249 , 206 , 26 , 135 , 101 , 230 , 71 , 243 , 251 , 204 , 220 , 254 , 168 , 13 , 208 , 54 , 167 , 195 , 138 , 105 , 173 , 135 , 170 , ],
[ 184 , 158 , 169 , 136 , 39 , 31 , 67 , 28 , 72 , 148 , 85 , 140 , 147 , 217 , 213 , 237 , 32 , 181 , 69 , 30 , 85 , 23 , 66 , 216 , 158 , 22 , 1 , 138 , 248 , 213 , 250 , 247 , 11 , 75 , 167 , 37 , ],
[ 254 , 88 , 81 , 232 , 213 , 231 , 155 , 10 , 151 , 31 , 203 , 120 , 85 , 149 , 5 , 55 , 180 , 19 , 34 , 140 , 164 , 22 , 124 , 236 , 108 , 16 , 252 , 255 , 67 , 99 , 47 , 108 , 129 , 86 , 35 , 132 , ],
[ 215 , 156 , 79 , 14 , 156 , 26 , 41 , 118 , 88 , 163 , 198 , 20 , 172 , 179 , 28 , 159 , 144 , 124 , 102 , 213 , 53 , 98 , 231 , 130 , 29 , 93 , 185 , 31 , 124 , 11 , 58 , 62 , 30 , 142 , 6 , 38 , ],
[ 154 , 94 , 115 , 10 , 180 , 243 , 159 , 38 , 151 , 121 , 87 , 162 , 218 , 229 , 78 , 113 , 155 , 188 , 9 , 106 , 157 , 130 , 159 , 180 , 152 , 91 , 199 , 184 , 108 , 237 , 229 , 203 , 139 , 205 , 32 , 18 , ],
[ 32 , 244 , 127 , 64 , 157 , 179 , 61 , 14 , 242 , 2 , 204 , 190 , 177 , 7 , 158 , 142 , 23 , 66 , 56 , 163 , 174 , 117 , 145 , 11 , 105 , 206 , 211 , 9 , 253 , 165 , 123 , 15 , 52 , 6 , 156 , 161 , ],
[ 43 , 116 , 177 , 113 , 61 , 39 , 230 , 70 , 100 , 227 , 6 , 83 , 252 , 56 , 183 , 235 , 66 , 159 , 160 , 155 , 76 , 19 , 33 , 177 , 115 , 199 , 20 , 104 , 217 , 180 , 244 , 105 , 49 , 56 , 64 , 11 , ],
[ 196 , 88 , 189 , 111 , 151 , 137 , 3 , 136 , 121 , 180 , 10 , 24 , 24 , 17 , 189 , 51 , 85 , 42 , 154 , 137 , 125 , 227 , 95 , 247 , 168 , 95 , 193 , 141 , 77 , 199 , 42 , 144 , 51 , 190 , 202 , 254 , ],
[ 154 , 61 , 70 , 20 , 239 , 16 , 2 , 203 , 174 , 218 , 49 , 103 , 169 , 91 , 114 , 110 , 11 , 94 , 207 , 156 , 7 , 189 , 233 , 126 , 251 , 194 , 4 , 176 , 55 , 161 , 96 , 73 , 22 , 160 , 47 , 157 , ],
[ 85 , 111 , 102 , 74 , 182 , 184 , 144 , 162 , 66 , 96 , 127 , 171 , 95 , 3 , 103 , 5 , 48 , 131 , 34 , 176 , 53 , 92 , 37 , 25 , 222 , 80 , 158 , 55 , 60 , 58 , 149 , 33 , 61 , 238 , 65 , 93 , ],
[ 199 , 152 , 139 , 149 , 229 , 218 , 188 , 7 , 199 , 134 , 246 , 143 , 72 , 9 , 97 , 108 , 52 , 10 , 67 , 250 , 207 , 181 , 16 , 68 , 166 , 188 , 224 , 143 , 105 , 192 , 179 , 81 , 184 , 48 , 188 , 57 , ],
[ 15 , 29 , 153 , 145 , 22 , 117 , 154 , 192 , 73 , 64 , 145 , 195 , 227 , 105 , 208 , 9 , 42 , 222 , 211 , 136 , 231 , 216 , 35 , 126 , 177 , 103 , 105 , 202 , 85 , 33 , 92 , 185 , 152 , 100 , 236 , 2 , ],
[ 7 , 78 , 147 , 214 , 88 , 139 , 77 , 240 , 46 , 65 , 245 , 39 , 211 , 82 , 111 , 198 , 37 , 126 , 13 , 157 , 249 , 0 , 96 , 89 , 156 , 97 , 68 , 184 , 218 , 129 , 128 , 149 , 240 , 233 , 239 , 239 , ],
[ 212 , 2 , 231 , 249 , 72 , 90 , 139 , 192 , 10 , 228 , 37 , 147 , 30 , 108 , 206 , 200 , 200 , 124 , 81 , 134 , 107 , 13 , 101 , 154 , 195 , 63 , 233 , 187 , 137 , 190 , 95 , 77 , 7 , 159 , 204 , 68 , ],
[ 23 , 25 , 47 , 227 , 75 , 2 , 96 , 56 , 220 , 149 , 135 , 208 , 80 , 80 , 141 , 248 , 238 , 70 , 220 , 37 , 237 , 3 , 42 , 236 , 126 , 57 , 144 , 113 , 168 , 166 , 187 , 23 , 131 , 216 , 88 , 124 , ],
[ 49 , 163 , 65 , 6 , 105 , 42 , 52 , 222 , 25 , 18 , 177 , 93 , 170 , 143 , 196 , 20 , 200 , 58 , 116 , 112 , 171 , 154 , 41 , 246 , 14 , 102 , 66 , 254 , 2 , 173 , 233 , 8 , 105 , 18 , 185 , 78 , ],
[ 54 , 24 , 184 , 185 , 209 , 187 , 142 , 123 , 174 , 85 , 171 , 190 , 119 , 136 , 72 , 87 , 36 , 67 , 78 , 234 , 232 , 15 , 139 , 91 , 134 , 150 , 226 , 98 , 234 , 71 , 218 , 64 , 197 , 135 , 115 , 242 , ],
[ 132 , 3 , 185 , 62 , 160 , 86 , 32 , 5 , 44 , 163 , 219 , 10 , 5 , 132 , 124 , 129 , 128 , 220 , 36 , 59 , 105 , 216 , 200 , 205 , 116 , 218 , 53 , 170 , 110 , 49 , 202 , 187 , 179 , 120 , 3 , 146 , ],
[ 1 , 254 , 113 , 164 , 232 , 149 , 177 , 219 , 100 , 55 , 180 , 76 , 160 , 99 , 230 , 130 , 30 , 115 , 134 , 103 , 77 , 209 , 6 , 117 , 189 , 37 , 81 , 202 , 39 , 56 , 156 , 81 , 120 , 63 , 65 , 74 , ],
[ 29 , 156 , 53 , 53 , 216 , 135 , 106 , 251 , 110 , 227 , 184 , 11 , 6 , 46 , 109 , 194 , 209 , 29 , 61 , 42 , 9 , 40 , 34 , 79 , 90 , 134 , 36 , 43 , 155 , 9 , 74 , 188 , 90 , 110 , 64 , 197 , ],
[ 91 , 31 , 164 , 160 , 170 , 163 , 114 , 33 , 164 , 149 , 158 , 228 , 89 , 239 , 153 , 152 , 55 , 11 , 168 , 242 , 188 , 193 , 231 , 234 , 102 , 70 , 212 , 158 , 150 , 206 , 215 , 242 , 96 , 183 , 212 , 193 , ],
[ 38 , 0 , 42 , 95 , 194 , 20 , 114 , 109 , 248 , 180 , 139 , 233 , 176 , 60 , 233 , 4 , 29 , 131 , 249 , 70 , 199 , 173 , 121 , 125 , 187 , 84 , 104 , 134 , 84 , 244 , 0 , 175 , 56 , 155 , 57 , 92 , ],
[ 101 , 74 , 47 , 229 , 36 , 179 , 156 , 76 , 29 , 74 , 65 , 99 , 36 , 215 , 243 , 109 , 211 , 74 , 188 , 213 , 19 , 216 , 25 , 31 , 0 , 11 , 66 , 202 , 60 , 144 , 8 , 101 , 229 , 84 , 184 , 177 , ],
[ 226 , 211 , 81 , 244 , 173 , 197 , 186 , 217 , 106 , 146 , 36 , 77 , 192 , 171 , 152 , 139 , 198 , 250 , 90 , 216 , 33 , 165 , 213 , 9 , 226 , 59 , 93 , 197 , 15 , 64 , 205 , 21 , 221 , 147 , 205 , 48 , ],
[ 82 , 108 , 244 , 161 , 181 , 24 , 181 , 237 , 150 , 134 , 208 , 238 , 204 , 70 , 53 , 53 , 128 , 43 , 137 , 98 , 95 , 45 , 182 , 117 , 77 , 252 , 115 , 168 , 137 , 246 , 200 , 32 , 166 , 12 , 25 , 140 , ],
[ 44 , 120 , 66 , 132 , 28 , 155 , 52 , 189 , 144 , 30 , 192 , 71 , 133 , 238 , 175 , 173 , 140 , 71 , 84 , 158 , 142 , 191 , 115 , 101 , 164 , 131 , 130 , 97 , 137 , 159 , 233 , 214 , 225 , 159 , 63 , 252 , ],
[ 0 , 7 , 26 , 124 , 59 , 27 , 25 , 118 , 194 , 12 , 47 , 76 , 255 , 180 , 31 , 27 , 26 , 147 , 171 , 25 , 136 , 3 , 202 , 55 , 218 , 18 , 42 , 28 , 255 , 59 , 254 , 247 , 150 , 87 , 239 , 8 , ],
[ 145 , 237 , 63 , 211 , 149 , 51 , 181 , 141 , 187 , 38 , 141 , 22 , 77 , 74 , 8 , 237 , 176 , 82 , 251 , 113 , 116 , 13 , 214 , 97 , 91 , 154 , 76 , 84 , 236 , 211 , 203 , 104 , 123 , 74 , 176 , 110 , ],
[ 240 , 232 , 206 , 192 , 234 , 212 , 82 , 46 , 20 , 173 , 57 , 140 , 118 , 30 , 51 , 61 , 15 , 115 , 46 , 46 , 55 , 199 , 188 , 45 , 191 , 96 , 118 , 124 , 180 , 122 , 87 , 21 , 225 , 72 , 47 , 249 , ],
[ 219 , 121 , 84 , 210 , 24 , 14 , 202 , 11 , 84 , 244 , 227 , 83 , 128 , 88 , 155 , 215 , 218 , 57 , 114 , 243 , 76 , 4 , 211 , 251 , 71 , 200 , 134 , 251 , 207 , 47 , 115 , 47 , 167 , 81 , 83 , 24 , ],

])

sol = np.linalg.solve(eqs, res)
print sol


xx = [ 88,  45,  77,  65,  83, 123,  71,  52, 117,  53, 115,  95, 119,  52, 115,  95, 110,  49,  99,  51,  95, 116, 104,  49, 115,  95,  67, 104, 114, 105,  53, 116, 109,  97,  53, 125]
ss =""
for i in xrange(0,len(xx)):
    ss += chr(xx[i])
print ss

FLAG : X-MAS{G4u5s_w4s_n1c3_th1s_Chri5tma5}

A Christmas Carol

뭔가 삽질(…)해서 푼 느낌인데, 부채널 공격 느낌으로, 1바이트씩 맞춰 나가면서 풀었습니다.

 

 

import subprocess

for i in xrange(0,2000):
    fname = str(i)+".tmp"
    
    f = open(fname,"wb")
    f.write("1"*i)
    f.close()
    proc = subprocess.Popen(["./encoder",fname,fname+".mid"],stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    stdout, stderr = proc.communicate()
    f = open(fname+".mid","rb")
    ss = f.read()
    if (len(ss) == 1786):
        print i
    f.close()
#163,164,165

먼저 이런 코드로, 주어진 mid파일과 길이가 같으려면 몇글자를 인코딩 해야하는지 봤더니, 163,164,165글자더군요.

 

import subprocess
import hashlib

NN = 163

START_PREFIX_ORG = "O Christmas tree, o Christmas tree\nHow lovely are thy branches\nO Christmas tree, o Christmas tree\nHow lovely are thy branches\nX-MAS{4_n07_50_u5u4l_chr157m45_c4r0l}"
print len(START_PREFIX_ORG)
#Possible_Chars = ['|', '}', '~'] # ['p', 'q', 'r', 's'] #, 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o']
Possible_Chars =  [' ']
for jj in xrange(0,len(Possible_Chars)):
    if len(Possible_Chars) != 1:
        START_PREFIX = START_PREFIX_ORG + Possible_Chars[jj]
    else:
	START_PREFIX = START_PREFIX_ORG
    
    sTemp = START_PREFIX + "\x90"*(NN - len(START_PREFIX))

    flag_midf = open("flag.mid","rb")
    flag_mid = flag_midf.read()
    flag_midf.close()

    START = len(START_PREFIX)
    END = START + 1

    for i in xrange(START,END):
        fname = str(i)+".tmp"
        MAX = 0
        MyDict = {}
        isChanged = 0
        for j in xrange(0,127):

            c = chr(j)
            sFlag = sTemp[:i] + c + sTemp[i+1:]

            fName = hashlib.md5(sFlag).hexdigest()[:16]
            f = open(fName,"wb")
            f.write(sFlag)
            f.close()
            
            proc = subprocess.Popen(["./encoder",fName,fName+".mid"],stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
            stdout, stderr = proc.communicate()
            
            f = open(fName+".mid","rb")
            ss = f.read()
            f.close()
            
            for k in xrange(0,len(flag_mid)):
                if flag_mid[k] != ss[k]:
                    break
            if MAX <= k:
                    isChanged += 1
                    MAX = k
                    MAX_Char = c
                    try:
                            MyDict[str(MAX)] += MAX_Char
                    except:
                            MyDict[str(MAX)] =  [MAX_Char]
                    #print k,c
        if isChanged < (127):
            print Possible_Chars[jj], MyDict[str(MAX)]
            exit()
        print Possible_Chars[jj], MyDict
            
    #163,164,165

그런 다음, 저기 코드에 START_PREFIX_ORG 부분을 한글짜씩 늘려나가면서 전체 문자열을 따왔습니다.

FLAG : X-MAS{4_n07_50_u5u4l_chr157m45_c4r0l}

 

1 Comment

Johnk280에게 댓글 남기기 댓글 취소

이메일은 공개되지 않습니다.