1.1实验准备(1)登录界面
这是测试页面的主体部分。单击登陆按钮时,进行登录验证。进行验证的sql语句为:
cmd.CommandText = "SELECT * FROM [test].[dbo].[user] where [user]='"+username+"' and [pswd]='"+pswd+"'";
后台代码为:
public partial class _Default : System.Web.UI.Page
{
string username;//存储用户输入的用户名
string pswd;//存储用户输入的密码
SqlConnection conn;// SqlConnection实例
SqlCommand cmd;// SqlCommand实例
protected void Page_Load(object sender, EventArgs e)
{
conn = new SqlConnection();
conn.ConnectionString = SqlDataSource1.ConnectionString;
conn.Open();//打开数据库连接
cmd = new SqlCommand();
cmd.Connection = conn;
cmd.CommandType = CommandType.Text;
}
protected void Button1_Click(object sender, EventArgs e)
{
username = tusername.Text;//获取用户输入的用户名
pswd = tpassword.Text;//获取用户输入的密码
cmd.CommandText = "SELECT * FROM [test].[dbo].[user] where [user]='"+username+"' and [pswd]='"+pswd+"'";//查询字符串
if( cmd.ExecuteScalar()!=null)
Response.Redirect("Welcom.aspx");//如果用户名密码正确,跳转到欢迎界面
else
TextBox1.Text = "用户名或密码错误";//错误,显示错误信息。
}
}
(2)欢迎界面
只显示一条语句:welcom
1.2正常测试
(1)在登录界面输入正确的用户名和密码。
结果跳转到欢迎界面
(2)输入不正确的密码
1.3 注入测试
正常情况下,这样的登录验证看起来没什么问题。我们来看一下单击登陆时的查询语句:
cmd.CommandText="SELECT * FROM [test].[dbo].[user] where [user]='xuanhun' and [pswd]='123456'"
被验证的变量都在两个单引号中间,and语句要求前后都为真结果才为真,但是我们可以想到如果是or语句的话,那么只有结果只要有一个为真的话,那么整个语句就可顺利进行。如果查询语句是这样的话:
cmd.CommandText="SELECT * FROM [test].[dbo].[user] where [user]='xuanhun' and [pswd]='123456' or ‘a’=’a’"
结果会怎么样呢? or ‘a’=’a’肯定为真,那么就意味着“where [user]='xuanhun' and [pswd]='123456' or ‘a’=’a’"为真,如果这样的话,无论我们输入设么样的用户名密码都可以通过验证。下面测试一下我们的设想。
结果是:
证明注入成功。
1.4 总结
现在总结一下构成注入漏洞的原因:因为变量的值在两个单引号中间,要想执行我们添加的语句,必须使语句在单引号之外。我们输入密码aa之后加了单引号aa’,这样[pswd]=''的第一个单引号和aa后的单引号闭合,使得后面的语句可以执行,但还有后面一个单引号,我们用后一个’a前面的单引号和它闭合。这样语句变成了where [user]='xuanhun' and [pswd]='aa' or ‘a’=’a’,执行是没问题了。问题的根源在于没有对输入做过滤,用用户输入的单引号闭合了原来的单引号。
asp.net sql注入实验(2)(转载请注明作者及出处)
作者:玄魂(QQ:717532978)
跨页传递在asp时代最简单的做法是查询字符串。这种做法在asp.net 2.0已经不是推荐的做法了,但对于简单数据传输还是一种简单的便利的做法。今天我们就通过查询字符串进一步了解sql注入的注入漏洞判断的相关知识。
一.实验准备:page1:传递参数
Page2: 接收并处理参数.
二.相关代码:
(1)page1传递参数的代码
protected void Button1_Click1(object sender, EventArgs e)
{
Response.Redirect("page2.aspx?name=”+textbox_name.Text.Tostring()+ “&password=”+ textbox_password.Text.Tostring());
}
(2) page2接收并处理
username.Text = Request.QueryString["name"].ToString();
tpassword.Text = Request.QueryString["password"].ToString();
username = tusername.Text;
pswd = tpassword.Text;
cmd.CommandText = "SELECT * FROM [test].[dbo].[user] where [user]='" + username + "' and [pswd]='" + pswd + "'";
if (cmd.ExecuteScalar() != null)
Response.Write("hao");
//Response.Redirect("Welcom.aspx");
else
TextBox1.Text = "用户名或密码错误";
运行情况:
用查询字符串,传递的参数会在地址栏显示出来:
http://localhost:1239/WebSite/page2.aspx?name=xuanhun&password=123456,
根据这个形式的地址,我们讨论一个简单的注入漏洞判断的原理。
三.
1.数字型
查询语句类似为:Select * from 表名 where 字段=23。因为数字型没有引号,直接加查询语句测试是否可以执行
①http://localhost:1239/WebSite/page2.aspx?id=23。这是正常网页。查询语句为
Select * from 表名 where 字段=23
②http://localhost:1239/WebSite/page2.aspx?id=23 and 1=1。因为and 1=1为真,所以如果返回的页面和①同,说明我们插入的语句执行了。查询语句为:Select * from 表名 where 字段=23 and 1=1.
③http://localhost:1239/WebSite/page2.aspx?id=23 and 1=2。因为and 1=2为假,查询语句为:Select * from 表名 where 字段=23 and 1=2。
这就是经典的1=1、1=2测试法的原理。可以注入的表现:
① 正常显示(这是必然的,不然就是程序有错误了) ② 正常显示,内容基本与①相同 ③ 提示BOF或EOF(程序没做任何判断时)、或提示找不到记录(判断了rs.eof时)、或显示内容为空(程序加了on error resume next)
不可以注入就比较容易判断了,①同样正常显示,②和③一般都会有程序定义的错误提示,或提示类型转换时出错。
2.字符型。
查询语句类似为:Select * from 表名 where 字段=’xuanhun’。
测试不过是先屏蔽单引号再用上面的方法来检测漏洞。
比如我们上面的测试页面:
http://localhost:1239/WebSite/page2.aspx?name=xuanhun&password=123456,
查询语句为:Select * from [user] where [name]=’xuanhun’and [pswd]=’123456’。
字符型可以直接在单引号看程序的错误信息,如
http://localhost:1239/WebSite/page2.aspx?name=xuanhun&password=123456’返回错误信息:
“/WebSite”应用程序中的服务器错误。
--------------------------------------------------------------------------------
字符串 '123456'' 后的引号不完整。 '123456'' 附近有语法错误。
再屏蔽单引号看结果:
http://localhost:1239/WebSite/page2.aspx?name=xuanhun&password=123456’and ‘a’=’a’- -
页面正常。
http://localhost:1239/WebSite/page2.aspx?name=xuanhun&password=123456’and ‘a’=’b’- -
页面错误。
3.搜索型。
查询语句类似为:Select * from 表名 where 字段like ’%关键字%’
要屏蔽单引号和百分号再用上面的方法测试,注入也是一样。
例如:select * from [user] where [username] like ‘%a%’ and 1=1--
原理跟上面讲的相同,就不详细介绍了。