Recent posts

SECCON CTF 2015 - Remote GDB

Given an ELF binary putskey and a text file log.txt. As the title suggests, log.txt is a remote GDB command log.

1. Reverse binary

The binary is simple. It reads two inputs, flag and enc using getc() into buffers in .data section. Then it xors two string into enc, and prints the result. But we don’t know the data.

The location of first input buffer is flag: 0x80d7300 ~ 0x80d7340. Second input buffer is located at rnd: 0x80d7340 ~ 0x80d7380. Resulting data are stored at enc: 0x80d7380 ~ 0x80d73c0.

2. Parse log file

Remote GDB protocol is throughly documented at https://sourceware.org/gdb/onlinedocs/gdb/Overview.html and https://sourceware.org/gdb/onlinedocs/gdb/Packets.html.

First I focused on memory read command (m) because data are written in fixed locations. From this, content of rnd could be recovered:

65 6f 26 02 13 06 25 60 34 0b 27 3b 78 3a 26 00 39 4a 46 5d 3d 5e 58 36

Content of flag and enc did not appear in memory read commands. Instead, I found many repetitive breakpoint, continue and register (g) read command. I extracted eax of every register read command, hopefully contains the return value of getc(). Among bunch of numbers, I found the data that looks like flag.

36 2a 65 41 5c 48 5e 28 51 67 4b 54 3f 7e 64 50 4b 25 32 32 5e 31 34 4b

The answer is xor of two strings. SECCON{HelloGDBProtocol}.


SECCON CTF 2015 - Individual Elebin

Execute all ELF files

We are given 11 ELF binaries, for all different architectures.

$ file *
10.bin:  ELF 32-bit LSB  executable, ARM, version 1, statically linked, stripped
11.bin:  ELF 32-bit MSB  executable, MIPS, MIPS-I version 1 (SYSV), statically linked, stripped
1.bin:   ELF 32-bit LSB  executable, Intel 80386, version 1 (FreeBSD), statically linked, stripped
2.bin:   ELF 32-bit MSB  executable, MC68HC11, version 1 (SYSV), statically linked, stripped
3.bin:   ELF 32-bit LSB  executable, NEC v850, version 1 (SYSV), statically linked, stripped
4.bin:   ELF 32-bit MSB  executable, Renesas M32R, version 1 (SYSV), statically linked, stripped
5.bin:   ELF 64-bit MSB  executable, Renesas SH, version 1 (SYSV), statically linked, stripped
6.bin:   ELF 32-bit MSB  executable, SPARC version 1 (SYSV), statically linked, stripped
7.bin:   ELF 32-bit LSB  executable, Motorola RCE, version 1 (SYSV), statically linked, stripped
8.bin:   ELF 32-bit LSB  executable, Axis cris, version 1 (SYSV), statically linked, stripped
9.bin:   ELF 32-bit LSB  executable, Atmel AVR 8-bit, version 1 (SYSV), statically linked, stripped

There are number of ways to deal with this problem

Read more


Writing Video in OSX with OpenCV

Tutorial doesn’t work!

The tutorial says we can record a webcam video with following code. (which doesn’t work)

#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

int main()
{
  VideoCapture capture(0);

  int w = capture.get(CV_CAP_PROP_FRAME_WIDTH);
  int h = capture.get(CV_CAP_PROP_FRAME_HEIGHT);
  int fps = 30;
  VideoWriter writer("out.mp4", CV_FOURCC('X','2','6','4'), fps, Size(w,h), true);

  Mat frame;
  while (true)
  {
    capture >> frame;
    writer << frame;
    imshow("frame", frame);
    if (waitKey(20) == 27) break;
  }
}

It doesn’t work on default OpenCV library for OSX. The program runs without error, but produces an empty file. I tried to change the fourcc values into 'M','J','P','G' and change the extension to .avi or even set fourcc to -1. But all these tries didn’t work.

According to a Stackoverflow Thread OSX version of OpenCV does not have a working video writer. Ouch! Instead, this thread suggests me another way.

Read more


HITCON Quals 2015 - puzzleng

Next Generation of Puzzle!

puzzleng은 파일을 암호화해주는 프로그램인 encrypt와 암호화된 파일인 flag.puzzle두 파일로 구성된 forensic 문제이다.

1. encrypt 분석

encrypt는 간단한 프로그램이다. 암호화 과정은 다음과 같다.

  • 주어진 비밀번호를 SHA1 해시하여 얻은 20바이트를 암호화 키로 사용한다.
  • 대상 파일을 같은 크기의 20조각으로 나누어 각 조각을 암호화 키의 한 바이트로 xor한다.

2. 파일 헤더 복구

암호화 키에 대한 정보가 하나도 없으므로 직접 모든 경우를 대입해 봐야 한다. 그러나 20바이트를 전부 시도할 수는 없어서 파일 헤더가 있을 것으로 예상되는 첫 번째 블록만 xor해보았다.

from hexdump import hexdump

f = open("flag.puzzle")
raw = f.read()
f.close()

raw = map(ord, list(raw))
L = len(raw)
B = (L + 19) // 20
k = [0]*20

def decrypt():
    for i in range(20):
        start = i * B
        end = min((i+1) * B, L)
        for j in range(start, end):
            raw[j] ^= k[i]

def dump_block(i):
    start = i * B
    end = min((i+1) * B, L)
    block = raw[start:end]
    block = ''.join(map(chr, block))
    hexdump(block)

n = 0
for i in range(256):
    print "="*40, i
    k[n] = i
    decrypt()
    dump_block(n)
    decrypt()

그 결과 키의 첫 번째 바이트가 101일 때 PNG 헤더가 나오는 것을 확인했다.

======================================== 101
00000000: 89 50 4e 47 0d 0a 1a 0a  00 00 00 0d 49 48 44 52  .PNG........IHDR
00000010: 00 00 03 90 00 00 03 90  01 03 00 00 00 75 82 0c  .............u..
00000020: 67 00 00 00 06 50 4c 54  45 8f 77 b5 8f 77 b4 6d  g....PLTE.w..w.m
00000030: c4 59 ac 00 00 00 02 74  52                       .Y.....tR

Read more


LD_PRELOAD hooking

https://rafalcieslak.wordpress.com/2013/04/02/dynamic-linker-tricks-using-ld_preload-to-cheat-inject-features-and-investigate-programs/

/* target.c */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(){
  srand(time(NULL));
  int i = 10;
  while(i--) printf("%d\n",rand()%100);
  return 0;
}
/* hook.c */
int rand()
{
  return 42;
}

이렇게 두 파일을 작성한다.

gcc target.c -o target
./target

이걸 실행하면 0~99 사이의 랜덤한 숫자가 열 개 출력된다.

gcc -shared -PIC hook.c -o hook.so
env LD_PRELOAD=$PWD/hook.so ./target

이렇게 hook.so를 만들고 LD_PRELOAD를 설정한 뒤 실행하면 42가 열 개 출력된다. 함수 이름만 맞춰주면 모든 dynamically linked call을 후킹할 수 있다.