Hgame 2023 pwn部分wp
week1
pwn
test_nc
nc即得flag
easy_overflow
简单的ret2text,但程序会关闭标准输出,百度搜了下,发现可以重定位stdout到stderr,然后就可以得到flag了
1 | #!/usr/bin/env python3 |
choose_the_seat
checksec
看到只开了NX
在if
判断看到判断条件不严格,没有判断负数的情况,导致可以越界修改got表。
为了便于进行后续操作,我们先将exit
函数的got表项改为vuln
函数地址,这样就可以无限执行vuln
函数了。
然后需要泄露libc
,由于题目已经给出了libc文件,知道要覆盖项的偏移后,部分覆盖然后就可以打印出libc
,计算得到libc
基址。最后直接修改puts
函数got表为system
函数即可,最后写一个/bin/sh\x00
即可getshell
1 | #!/usr/bin/env python3 |
orw
checksec
看到只开了NX,seccomp-tools
看到禁用了execve
,那就只能orw了。
发现溢出大小不足,因此泄露libc后在bss段上找一块位置写下payload,然后leave_ret
栈迁移到该位置即可得到flag
1 | #!/usr/bin/env python3 |
simple_shellcode
checksec
看到保护全开,seccomp-tools
看到禁用了execve
,orw即可。
程序会使用mmap
函数开辟一块可读可写可执行的空间,并且在读取后会跳到该位置执行shellcode
,但是read
的太小,因此我们可以在这一小段shellcode
里面继续调用read
函数对该区域进行大量写入,程序即可顺序执行orw
1 | #!/usr/bin/env python3 |
reverse
test_your_IDA
用IDA打开即得flag
hgame{te5t_y0ur_IDA}
easyasm
记事本打开看到汇编,分析汇编可得程序逻辑为对每一位与 0x33
进行异或,直接异或解密得到flag
hgame{welc0me_t0_re_wor1d!}
easyenc
IDA打开看到主要逻辑为
1 | while ( 1 ) |
直接python解密
1 | enc = [0x4,0xff,0xfd,0x9,0x1,0xf3,0xb0,0x0,0x0,0x5,0xf0,0xad,0x7,0x6,0x17,0x5,0xeb,0x17,0xfd,0x17,0xea,0x1,0xee,0x1,0xea,0xb1,0x5,0xfa,0x8,0x1,0x17,0xac,0xec,0x1,0xea,0xfd,0xf0,0x5,0x7,0x6] |
hgame{4ddit1on_is_a_rever5ible_0peration}
a_cup_of_tea
程序为tea加密,但改了里面的delta,并且把加密时的sum+=delta
改成了sum-=delta
c脚本为:
1 |
|
hgame{Tea_15_4_v3ry_h3a1thy_drlnk}
encode
主要逻辑为:
1 | for ( i = 0; i < 50; ++i ) |
对每次结果及下一位和0xf
进行与操作,每次加密两位
python脚本为
1 | enc = [8, 6, 7, 6, 1, 6, 0xD, 6, 5, 6, 0xB, 7, 5, 6, 0xE, 6, 3, 6, 0xF, 6, 4, 6, 5, 6, 0xF, 5, 9, 6, 3, 7, |
hgame{encode_is_easy_for_a_reverse_engineer}
week2
pwn
YukkuriSay
checksec
看到只开了NX和canary
IDA打开,刚看到还是比较懵,只有一次格式化字符串的机会,要改got表的话后面没有执行的函数。之后发现可以泄露出libc偏移和栈地址,然后修改vuln
函数返回地址为one_gadget即可
1 | #!/usr/bin/env python3 |
editable_note
checksec
看到保护全开
delete
里面UAF,而且可以edit。思路很明显就是先通过unsorted bin泄露libc,然后one_gadget打hook,或者修改__free_hook
为system
,然后free掉存储/bin/sh\x00
的堆块,虽然它是libc-2.31.so
,但是tcache
内堆块的key可以改掉。
1 | #!/usr/bin/env python3 |
fast_note
checksec
看到保护只开了canary和NX
libc-2.23.so
没有tcache,IDA看到程序中没有edit功能,在添加堆块时会进行一次写。而且有一个UAF。
思路就是先泄露libc,然后fastbin attack打__malloc_hook-0x23
,同时配合__libc_realloc
函数调整栈帧,在__realloc_hook
中填入one_gadget。
1 | #!/usr/bin/env python3 |
new_fast_note
checksec
看到保护全开,这道题和上道题相比就是换了个高版本的libc。
思路和上道题一样,甚至不需要realloc函数调整栈帧(我竟然不知道已经分配过内存的index可以再分配,在这里浪费了贼多时间
1 | #!/usr/bin/env python3 |
reverse
before_main
一个变表base64,这个表会在main
函数执行之前被复制到对应位置,对应__init_array
里面的函数指针sub_1229
1 | import base64 |
stream
给了一个exe程序,很明显是pyinstaller打包的,直接百度python exe反编译,然后出来一大堆教程
最后得到程序源码,写出解密程序即可
1 | import base64 |
week3
pwn
三道题都是现学的,后两道因为不太会largebin attack
(低版本都没接触过),所以找了点模板,都套了house of banana
的模板,竟然直接秒了。(模板来自winmt师傅在看雪写的堆利用文章,tql)
safe_note
保护全开,并且libc-2.32.so
在这个版本中,tcache bin
的fd
位置会放置(pos>>12)^next
计算得到的值。当对应链表中只有一个堆块时,也就是其next
为0
。因此我们可以直接fd<<12
得到就是堆的基地址。因此我们可以计算(pos>>12)^target
,从而放入fd
位置,再申请即可得到target
位置。
本题很明显就是要利用UAF绕过tcache
新增的safe unlink
机制。
1 | #!/usr/bin/env python3 |
large_note
保护全开,libc-2.32.so
,只能申请largebin
范围内的chunk
,存在UAF漏洞
找了点资料,发现largebin attack
在该版本可以在任意地址写入一个堆地址,也就是大数值。貌似可以修改global_max_fast
,但是我找不到global_max_fast
在哪(太菜了)。因此又转向了house of banana
,正好有模板,稍微改下直接用。
house of banana
是利用exit
函数调用链触发的一种利用方式,调用链:exit()->_dl_fini->(fini_t)array[i]
,利用起来十分方便,只要我们能通过largebin attack
等方式劫持_rtld_global
首地址_ns_loaded
到我们的可控区域,就可以对link_map
进行伪造,从而进行一系列调用。
大概流程就是largebin attack
劫持_rtld_global
首项指针为可控堆块地址,直接伪造link_map
实现house of banana
从而getshell
house of banana
模板:
1 | fake_link_map_addr = heap_base + 0x6c0 |
exp:
1 | #!/usr/bin/env python3 |
note_context
和第二题程序主要逻辑完全一样,不同的是这个程序开了沙箱,禁用了execve
largebin attack + house of banana
实现orw直接得到flag
1 | #!/usr/bin/env python3 |
week4
pwn
这两道题都是libc-2.36的,刚看到就想到了最近看到的house of apple,但是没怎么看懂(主要是因为没模板),然后看了另一个新技巧house of cat,不出所料,构造好后两道直接秒出。
without_hook
从libc-2.34开始,删除了我们喜闻乐见的_malloc_hook
,_free_hook
,因此从这以后新的技巧大都转向IO函数,其中,house of cat就是典型例子,并且目前适用于所有版本。
保护全开,依然是开了沙箱的largebin attack
house of cat的具体细节不在这里详述,House of Cat利用了House of emma的虚表偏移修改思想,通过修改虚表指针的偏移,避免了对需要绕过TLS上 _pointer_chk_guard的检测相关的IO函数的调用,转而调用**_IO_wfile_jumps中的_IO_wfile_seekoff函数,然后进入到_IO_switch_to_wget_mode函数中来攻击,从而使得攻击条件和利用变得更为简单。并且house of cat在FSOP的情况下也是可行的,只需修改虚表指针的偏移来调用_IO_wfile_seekoff即可(通常是结合__malloc_assert,改vtable为_IO_wfile_jumps+0x10**)。
在本题中,伪造好IO结构体后,因为提供了exit
函数,可以通过FSOP触发
exp:
1 | #!/usr/bin/env python3 |
4nswer’s gift
看到题目描述给了内核版本,以为是内核题,差点就要直接题都不看了,附件下载完后发现还是个house of cat
没开canary,题目会直接告诉一个地址,在gdb里面看一下发现是_IO_list_all
地址,并且程序结束时会把分配到的堆地址赋值到_IO_list_all
位置,直接伪造fake_IO_FILE
,没开沙箱,会自己调用exit
函数,和上一题做法一样,甚至比上一题简单的多(或许是我上一题做复杂了
其中伪造时需要知道堆地址,但因为已知libc地址,且mmap分配堆和libc有固定偏移,所以直接malloc(-1),然后gdb看下直接算下就知道fake_io_addr了
exp:
1 | #!/usr/bin/env python3 |
- Title: Hgame 2023 pwn部分wp
- Author: Static
- Created at : 2024-03-10 16:33:30
- Updated at : 2024-03-10 16:33:26
- Link: https://staticccccccc.github.io/2024/03/10/CTFS-wp/Hgame 2023 部分wp/
- License: This work is licensed under CC BY-NC-SA 4.0.