Recent posts

성질 급한 사람을 위한 LaTeX

LaTex 입문서로는 142분 동안 익히는 LaTeX 2e 라는 좋은 한국어 문서가 있으나, 나처럼 성질 급한 사람을 위해 이 글을 쓴다.

1. 설치하기 (Mac OS X)

  1. 권장하는 방법은 MacTex를 설치하는 것이지만 MacTex는 용량이 너무 커서 오래걸리니 BasicTex를 다운받는다. 링크:
  2. 다운받은 pkg파일을 더블클릭하여 설치를 완료한다.

2. 설치하기 (Ubuntu)

sudo apt-get install texlive

3. 사용하기

다음 파일을 hello.tex로 저장한다.


다음을 실행한다.

pdflatex hello.tex

그려면 hello.pdf가 생성된다.

Holyshield 2016 - Holy Cat writeup

Go가 핫하긴 한가보다. Holy Cat (Reversing, 250)은 이번 Holyshield 2016에 출제된 윈도우용 Go 바이너리 리버싱 문제다. exe파일과 서버 IP를 줬는데, 아마 이 exe파일이 어떤 웹서버인 듯 하다.

1. 일단 실행

일단 윈도우 VM에서 프로그램을 실행해보니, 방화벽 경고가 떴다. 역시 네트워크로 뭔가를 하나보다. netstat으로 확인해 보니 LISTEN이 있었다. 브라우저로 localhost:9999에 접속해 보니 404 not found가 나왔다. 이제 코드를 볼 차례다.

제일 먼저 프로그램 내에 있는 string 중에서 /로 시작하는 것들을 찾았다. /login, /login_check, /debug_server_status 세 개가 있었다. 브라우저로 들어가 보니 /login 페이지에는 패스워드 입력창 하나가, /login_check에는 “Access Denied” 메시지, /debug_server_status에는 이런 메시지가 나왔다.

--------------DEBUG INFO--------------
Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.111 Safari/537.36

세 번째 줄은 브라우저의 IP와 포트인 것 같고 (이 경우엔 IPv6 loopback 주소인 ::1), 그 다음 브라우저의 User-Agent, 알수없는 1488, 현재 타임스탬프, 그리고 컴퓨터 이름이 나왔다. 1488은 이리 저리 생각하다가 작업관리자를 켜서 holycat.exe의 PID라는 것을 알아냈다. 이 값들을 조합하면 맞는 비밀번호가 되는 식인 것 같다.

Read more

Regex Crossword Solver with Z3

1. Problem Statement

Regex Crossword ( is a crossword puzzle where you fill in a rectangular board, so that regular expressions on every row and column are satisfied. It looks like this.


During fun geeky solving time, I thought it could be solved with computer. And actually there are great works with Regex Crossword solvers.

Herman Schaaf has solved it in Go-lang ( His solution analyzes the DFA generated by Go-lang’s regular expression compiler. His solution solves it really fast, that it only takes few miliseconds to solve one, but it cannot deal with backreferences.

Thomas Parslow has solved hexagonal version in Haskell ( His approach is basically same as solving by hand. He wrote a custom regular expression engine to do that. His solution can solve ones with backreferences, very quickly.

I’ve decided to take another approach, using SMT solver.

Read more

32C3 CTF - gurke

Non-standard gurke: Talk to it via HTTP on

Gurke is German for ‘cucumber’. Server runs this code:

#!/usr/bin/env python
import sys
import os

import socket
import pickle
import base64
import marshal
import types
import inspect
import encodings.string_escape

class Flag(object):
    def __init__(self):
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect(("", 1234))
        self.flag = s.recv(1024).strip()
flag = Flag()

from seccomp import *

f = SyscallFilter(KILL)
f.add_rule_exactly(ALLOW, "read")
f.add_rule_exactly(ALLOW, "write", Arg(0, EQ, sys.stdout.fileno()))
f.add_rule_exactly(ALLOW, "write", Arg(0, EQ, sys.stderr.fileno()))
f.add_rule_exactly(ALLOW, "close")
f.add_rule_exactly(ALLOW, "exit_group")

f.add_rule_exactly(ALLOW, "open", Arg(1, EQ, 0))
f.add_rule_exactly(ALLOW, "stat")
f.add_rule_exactly(ALLOW, "lstat")
f.add_rule_exactly(ALLOW, "lseek")
f.add_rule_exactly(ALLOW, "fstat")
f.add_rule_exactly(ALLOW, "getcwd")
f.add_rule_exactly(ALLOW, "readlink")
f.add_rule_exactly(ALLOW, "mmap", Arg(3, MASKED_EQ, 2, 2))
f.add_rule_exactly(ALLOW, "munmap")

data =, 4096)
    res = pickle.loads(data)
    print 'res: %r\n' % res
except Exception as e:
    print >>sys.stderr, "exception", repr(e)


Everyone knows that unpickling user provided data is dangerous. I’ve used arbitrary code execution pickle from

We cannot just “print flag.flag”, because the context where our code is executed is inside pickle module of remote server. So we needed some workaround by reading:


Read more

32C3 CTF - ey_or

We have a large (24MB) x86_64 ELF executable. It’s very difficult to reverse engineer this size. Instead, one of the printable strings looked interesting.

$ strings ey_or
] ==secret
] ==f
 secret len ==l
 [ ] ==buffer
 0 ==i
 0 ==j
 "Enter Password line by line\n" sys .out .writeall
  #str .fromArray secret bxor
  txt .consume .u
[ buffer _ len dearray j ] =buffer
[ secret _ len dearray j eq { } { 1 sys .exit } ? * ] =secret
  i 1 add =i
  i l eq {
  buffer f bxor str .fromArray sys .out .writeall
 0 sys .exit
} { } ? *
} sys .in .eachLine
"ey_or" sys .freeze

Read more