技术内容 / 本科的一些学习笔记和wp / 孟哥独家
孟哥独家
Web漏洞
1、CSRF(跨站请求伪造)
①原理
在浏览器中cookie在一段时间内是不会过期的,如果在cookie存在期间,通过构造csrf脚本或包含csrf脚本的链接发送给用户,得到cookie等信息,就可以伪造成用户身份,执行相关操作
②出现位置
- 通过URL地址分享网页内容
- 信息资料填写
- 图片加载与下载:通过URL地址加载或下载图片
③如何批量扫
这里参考的CSRF Tester的实现原理进行的总结:
使用代理抓取我们在浏览器中访问过的所有的连接以及所有的表单等信息,通过修改其中相应的表单等信息,重新提交,相当于一次伪造客户端请求,如果修测试的请求成功被网站服务器接受,则说明存在CSRF漏洞。
④防御
- 添加referer
- 添加token
- 在http头中自定义属性并验证
- 验证码交互式
2、SSRF
①原理
服务端提供了从其他服务器应用获取数据的功能,且没有对目标地址做过滤与限制,导致可以任意访问网络资源,这样就可利用存在缺陷的Web应用作为代理攻击远程和本地的服务器。
②出现位置
图片访问、文件下载等
③利用
- dict探测内网端口
- file读取本地文件
- gopher攻击内网redis、mysql等 ( Java不支持gopher协议)
④绕过
- ip进制转换
- sudo.cc、dnslog
- 特殊地址(0.0.0.0、127.1、0)
- dns重绑定
⑤防御
- 禁用不必要的协议 (file、gopher、dict)
- 内网黑名单(可正则匹配ip)
- 内网端口白名单
⑥为什么用gopher
Java代码审计
1、反射
①修改字段
Field name = c4.getDeclaredField("name"); //c4为class对象,name为属性名
name.setAccessible(true); //爆破
name.set(o,"Sentiment"); //修改属性值,o为c4对象的实例
System.out.println(name.get(o));
②调用方法
- 获取方法:Class类对象.getDeclaredMethod("方法名", 方法类型.class);;
- 调用方法:对象.invoke(实例化对象,"实参值");
Method say2 = c4.getDeclaredMethod("test", int.class); //test方法及其类型
say2.setAccessible(true);
System.out.println(say2.invoke(o,10,"tana",'M'));
③修改final属性
final
变量值可以改,但是有JVM内敛优化所以不能通过getter方法获取更改后的值,但是可以通过.get方法获取
static final
无法修改基本类型属性,所以需要通过modifiers修改成非final,之后通过反射修改
使用反射修改final变量 | 蓝亭书序 (lantingshuxu.github.io)
④高版本绕过反射黑名单
java沙箱绕过-安全客 - 安全资讯平台 (anquanke.com)
2、JNDI
①原理
在JNDI服务中,RMI服务可以通过References类来绑定一个外部的远程对象。绑定了Reference之后,服务端会先通过Referenceable.getReference()获取绑定对象的引用,并且在目录中保存。当客户端在lookup()查找这个远程对象时,客户端会获取相应的object factory,最终通过factory类将reference转换为具体的对象实例。
②8u121以下(RMI)
通过JNDI和RMI的结合攻击,将对象绑定在reference中,并通过codebase接收远程对象,最后在NamingManager调用newInstance()进行类加载造成代码执行
③8u191以下(LDAP)
在8u121之后,将rmi和cosnaming的trustURLCodebase默认值设为了false,因此上述方式不再适用,但ldap的并没有禁用,所以使用的是ldap进行攻击
流程跟RMI的基本一致,只是最终调用了DirectoryManager的getObjectInstance,而RMI调用的则是NamingManager的getObjectInstance,但最后也是通过NamingManager调用newInstance()进行类加载造成代码执行
④8u191以上
a.本地工厂(BeanFactory)
前边的流程跟RMI攻击实现中是一样的,但由于本次传入的工厂是BeanFactory,所以会调用BeanFactory.getObjectInstance(),因此后续的操作会有一些不同,主要是获取 forceString中的值,并进行反射调用
resourceRef.add(new StringRefAddr("forceString", "Sentiment=eval"));
resourceRef.add(new StringRefAddr("Sentiment", "Runtime.getRuntime().exec(\"calc\")"));
b.反序列化(LDAP)
LDAP 除了使用Reference进行利用之外,还支持反序列化,因此可以根据本地依赖选择反序列化执行命令
⑤如何审计
lookup、reference、InitialContext(个人理解)
3、URLDNS
1. HashMap->readObject()
2. HashMap->hash()
3. URL->hashCode()
4. URLStreamHandler->hashCode()
5. URLStreamHandler->getHostAddress()
6. InetAddress->getByName()
4、CC
谈下CC链中三个重要的Transformer
ConstantTransformer类的transform方法直接返回传入的类对象
ChainedTransformer类中的transform方法会链式调用其中的其他Transformer.transform方法
InvokerTransformer类根据传入参数可以反射调用对应的方法
CC3中为了绕过一些规则对InvokerTransformer的限制,所以找到了InstantiateTransformer可以直接实例化对象
CC1
原理是LazyMap.get可以触发构造的Transformer链的transform方法导致RCE
基于动态代理触发的LazyMap.get,在AnnotationInvocationHanlder中的invoke方法中存在Map.get操作
CC6
还是基于CC1的LazyMap.get触发的,只是CC1用的是AnnotationInvocationHanlder的readObject(),而CC6则是HashMap.readObject()
流程主要就是通过TiedMapEntry类的构造器,修改map属性的值,在通过TiedMapEntry.getValue()方法,调用Map属性的get()方法调用到LazyMap.get触发transform
a.序列化过程中就弹计算器
**原因:**put修改值时,调用了hash方法接着调用hashCode最终执行了命令
**解决:**在执行put前,先将transformer改成其他无法正产调用的内容,经过put后在改回来即:
Map outerMap = LazyMap.decorate(innerMap, new ConstantTransformer(1));
b.修改后仍无回显
**原因:**反序列化时key已经有值了,所以绕过了if从而绕过了transform()
**解决:**把if的key值去掉
outerMap.remove("Sentiment1");
CC5
还是基于CC1的LazyMap.get触发的,跟CC6也基本一样,这里是通过TiedMapEntry的toString()调用到了
TiedMapEntry.getValue()方法,之后执行Map.get()调用到LazyMap.get触发transform
CC3
该链用到TemplatesImpl类,生成恶意的字节码实例化仍基于CC1
CC3的最终目的是绕过⼀些规则对InvokerTransformer的限制,因此找到了InstantiateTransformer的transform,它在代码最后会执行newInstance,进行字节码加载
CC2
该链用到TemplatesImpl类,生成恶意的字节码实例化
不过触发点是PriorityQueue类,反射设置属性TransformingComparator
PriorityQueue类是优先队列,其中包含了排序功能,该功能可以设置比较器comparator,而TransformingComparator的compare方法会调用对象的transform方法
于是通过InvokerTransformer类的transform方法调用TemplatesImpl.newTransformer方法导致RCE
CC4
和CC2链一致,不过触发时候不是InvokerTransformer而是InstantiateTransformer类直接实例化TrAXFilter子类导致RCE
CC7
还是基于LazyMap.get触发的,通过Hashtable.readObject()触发了key的equals方法,AbstractMap.equals方法中包含了Map.get调用到LazyMap.get触发transform
5、CB
CommonsBeanutils中提供了动态调用getter的方法getProperty,这就可以联想到TemplatesImpl动态加载字节码中的getOutputProperties方法,通过它可以一步步的调用到defineClass并进行动态字节码加载
CB主要是结合shiro使用,因为shiro是依赖commons-beanutils的
6、7u21和8u20
7U21
主要在于AnnotationInvocationHandler的equalsImpl方法,他会遍历反射调用memberMethod.invoke(o),而 memberMethod 来自于 this.type.getDeclaredMethods() 。 也就是说, equalsImpl 这个方法是将 this.type 类中的所有方法遍历并执行了。那么,假设 this.type 是Templates类,则势必会调用到其中的 newTransformer() 或 getOutputProperties() 方法,进而触发任意代码执行。
8U20
之后JDK对AnnotationInvocationHandler类的type属性做了校验,原来的payload就会执行失败,在8u20中使用BeanContextSupport类对这个修补方式进行了绕过。
7、fastjson
fastjson提供了反序列化功能,并且可以调用任意的get、set方法,这就导致了该方法的恶意利用,造成一定安全问题
①JSON.parse()和JSON.parseObject()区别
当加上@type字段后都可获得类对象,但parse会调用对应setter方法吗,parseObject会调用setter、getter方法
②利用方式
- JdbcRowSetImpl链结合JNDI注入,需要出网
- TemplatesImpl动态加载字节码
- BasicDataSource配合BCEL不出网利用
③bypass
- **1.2.25-1.2.41:**checkAutoType()检测,但可以L开头;结尾绕过
- **1.2.42:**双写绕过
- **1.2.43:**会对[特殊处理,可以用[ xxxxxx[{绕过
- **1.2.44 -1.2.45:**三方组件mybatis绕过
- **1.2.47前:**缓存绕过,大通杀
- **1.2.66-1.2.67:**用JNDI相关类,比如Shiro的JndiObjectFactory和ignite项目的类
- **1.2.68:**用到期望类属性,只要利用类是expectClass类的子类或实现类,并且不在黑名单中,即可直接绕过AutoType检测
- 1.2.80:68版本在之后直接用黑名单简单粗暴的修复了,于是出现另一个期望类Throwable
④bypass waf
unicode编码、十六进制\x、Fastjson默认会去除键值外的空格、\b、\n、\r、\f等字符
⑤除RCE外的利用
写文件、ReDos
8、Jackson
为了解决多态问题,Jackson提供了DefaultTyping和@JsonTypeInfo注解两种解决方式,但在Jackson进行反序列化时会调用构造器和setter方法,造成恶意代码执行
①其他调用链
- CVE-2017-7525 基于TemplatesImpl利用链
- CVE-2017-1748 基于ClassPathXmlApplicationContext利用链
- CVE-2019-12086 基于MiniAdmin利用链
- CVE-2019-12384 基于logback利用链
- CVE-2019-12814 基于JDOM-XSLTransformer利用链
- 其它调用链:JdbcRowSetImpl、C3P0 、更多调用链
9、C3P0
其中有一个getObject()方法,能获取请求的url和类名(127.0.0.1和Exec.class),接着在反序列化时通过URLClassloader进行远程类加载。
①其他利用方式
JNDI
C3P0组件中有一个类叫JndiRefDataSourceBase,其中有JNDI注入需要的上下文环境,并且也有触发点lookup()函数。一般结合fastjson使用
BeanFactory
跟前边JNDI注入中提到的工厂一样,主要是通过获取 forceString中的值,并进行反射调用
Hex字节码加载
C3P0的WrapperConnectionPoolDataSource中会通过fromByteArray()函数将十六进制数据转换为ascii码,最终经过反序列化处理
10、SnakeYaml
SnakeYaml调用load()方法进行反序列化时,最终会用newInstance进行实例化,而如果我们实例化的内容为ScriptEngineManager,就会调用到SPI机制中并触发hasNext()方法,利用URLClassLoader进行远程类加载。
①SPI机制
SPI调用方来制定接口规范,提供给外部来实现。
在SPI机制中会调用hashNext()方法,获取并迭代需要执行方法的全类名,并通过newInstance实例化
②load反序列化时为什么不能用public属性
public不会调用对应的setter方法,它的逻辑是通过反射对Field进行set实现的。
③如何利用
将要执行文件达成jar包,通过URLClassLoader进行远程类加载
④Bypass
Yaml反序列化中通过!! 来表示类的全类名,跟fastjson中的@type类似,bypass主要是用TAG 的表示方式来代替!!(因为在代码执行到后期!! 修饰过的类都转成了一个 TAG):
- !<tag 代替!!
- %TAG 声明TAG
⑤不出网利用
C3P0
可以结合C3P0的十六进制方式,进行不出网编码利用
本地文件写入
和fastjson利用基本一致,可以通过写入本地文件利用
⑤如何修复
在new Yaml()中加入new SafeConstructor()类进行过滤即可,即: Yaml yaml = new Yaml(new SafeConstructor());
⑥如何审计
用了new Yaml(),没有new SafeConstructor(),且yaml内容可控就可能有该漏洞
11、Shiro
①原理
为了保持持久化,shiro将信息序列化并加密后保存在 Cookie 的 rememberMe 字段中,而在shiro1.2.4之前这段cookie是经过aes和base64加密的,若获取了aes的默认key,就可以构造恶意序列化数据导致RCE
②怎么检测key
550反序列化浔阳江头夜送客丶的博客-CSDN博客shiro550
措施
当key正确时,remeberme中不显示deleteMe字段,但这有一个前提我们构造的序列化对象必须继承于 PrincipalCollection
原因
- 当key不正确时会抛出异常,进入onRememberedPrincipalFailure函数,将remeberme的默认值改为deleteMe
- 当key正确时,在最后的反序列化后会返回PrincipalCollection类型的数据,若不为该类型则又会进入onRememberedPrincipalFailure函数将remeberme的默认值改为deleteMe,SimplePrincipalCollection继承了PrincipalCollection并且可以序列化所以可以直接使用
SimplePrincipalCollection simplePrincipalCollection = new SimplePrincipalCollection();
ObjectOutputStream obj = new ObjectOutputStream(new FileOutputStream("./1.ser"));
obj.writeObject(simplePrincipalCollection);
obj.close();
因此只需要序列化一个继承与 PrincipalCollection 的类,便可通过deleteMe字段判断key的正确性
其他方式
DNSlog、CC盲打等,但这种需要有dnslog或对应依赖
③Shiro反序列化Gadget选择有什么坑吗
当用原生依赖CB打的时候,需要注意CB的版本,因为如果不一致的话,则会serialVersionUID不一致
另一个CB1的坑是Comparator来自于CC,需要使用如下的才可以在没有CC依赖情况下成功RCE
④如何方式shiro不被挖掘
通过已经存在的反序列化可以执行代码,反射改了RememberMeManager中的key即可。但这样会导致已登录用户失效,新用户不影响
⑤Shiro的权限绕过
shiro有很多权限绕过漏洞,主要源于Shiro 与 Spring 对请求的处理方式不同,比如:
- Shiro < 1.5.0:设置authc拦截器/admin,访问/admin/,shiro无法匹配,而Spring的Servler的则会正常识别
- Shiro < 1.5.2:访问/test/..;/admin,shiro判断在分号处结束,所以路径为/test/..,若/test/**设置anon不登录也可访问,则可绕过鉴权,而Spring则会认为路径为/admin,进而绕过
- Shiro < 1.5.3:设置authc拦截器/admin/*,访问/admin/a/b,shiro只会识别/后的一个目录,若设置多个则会无法识别,绕过鉴权
- Shiro < 1.6.0:设置authc拦截器/admin/*,访问/admin/;a,shiro在;处结束,而a在Spring中会当做参数传入
- Shiro < 1.7.1:设置authc拦截器/admin/*,访问/admin/(空格),绕过
⑥Shiro注入Tomcat内存马的坑
Shiro注内存马时候由于反序列化Payload过大会导致请求头过大报错
解决办法有两种:
- 反射修改Tomcat配置里的请求头限制,但这个不靠谱,不同版本Tomcat可能修改方式不一致
- 更为通用的手段是打过去一个Loader的加载请求Body里的字节码,将内存马字节码写入请求Body中。这种方式的缺点是依赖当前请求对象,解决办法是可以写文件后URLClassLoader加载
⑦Shiro 721
原理
Shiro550之后便不再采用固定秘钥,而是根据服务启动动态生成,加密方式也改为了AES-128-CBC模式。
但cookie的解析过程没有变,这就导致攻击者可以通过Padding Oracle Attack攻击实现AES-CBC加密破解,但需要较长的爆破时间
影响版本
Shiro < 1.4.2
⑧防御
- 由于这种方法需要爆破得到key,因此可以对短时间内多次访问的ip进行禁止访问操作,达到防御目的。
- 升级至安全版本。
- 关闭rememberMe持久化登录功能。
- 反射修改key
12、log4j2
①原理
log4j2调用过程中会截取${}中的内容,并执行JndiLoop.lookup导致RCE
②检测
黑盒
外网:dnslog
内网:自行实现JNDI、LDAP服务探测
白盒
检查依赖,是否小于2.15.0版本
③bypass
- 使用类似${::-J}的方式做字符串的绕过
- 结合upper和lower标签进行嵌套
- 有些字符大小写转换
④除了RCE还能干什么
- 信息泄露,如${env}和${env_SECRET_ACCESS_KEY}
- 也可用dnslog外带敏感信息
⑤2.15.0正式版绕过(微瑕)
主要是绕过HOST限制
- 用空格导致异常绕过
- 127.0.0.1#evil.com绕过,服务端#前的127.0.0.1会被认为是某个子域名,而本地则认为是127.0.0.1
⑥拒绝服务攻击
jndi的函数,它是堵塞的,一次时间大约为2s,而log4j2在处理${}时候是会递归的,所以通过简单的拼接,即可造成拒绝服务攻击:
payload:
${jndi:ldap://127.0.0.1}${jndi:ldap://127.0.0.1}${jndi:ldap://127.0.0.1}
⑦修复
重启服务
- 在JVM参数中添加-Dlog4j2.formatMsgNoLookups=true
- 系统环境变量中将LOG4J_FORMAT_MSG_NO_LOOKUPS设置为true
- 创建log4j2.component.properties文件并增加配置log4j2.formatMsgNoLookups=true
不重启
用Java agent修改JVM字节码,删除JndiLookup的功能
13、Spring
A、SPEL
①原理
用户传入数据后,后端会通过递归获取${}的数据,并进行解析,若我们传输的为恶意数据则会被后端渲染执行,导致RCE
②Bypass
- 字符拼接,如"java.l"+"ang"
- url编码
- %00会被直接替换为空,所以可以用T%00(代替T(
- new可用大小写绕过
B、SpringBoot Actuator未授权访问
访问env路径,可以获取到数据库地址,密码等信息
①修复
禁用env等重要信息的访问
management.endpoints.web.exposure.exclude=env,heapdump,threaddump,mappings
C、Spring Getway
CVE-2022-22947 Spring Cloud Gateway漏洞浅析 - admin-神风 - 博客园 (cnblogs.com)
14、内存马
①Servlet/Filter内存马查杀手段
利用Java Agent遍历所有JVM中的class,判断是否是内存马
例如使用阿里的arthas分析,根据继承实现类黑名单,注解包名类名等黑名单来做
②Servlet/Filter不死马实现
- 在destroy中加入注入内存马的代码。弊端:不是所有方式都能触发destory
- 跑不死进程,检测存在,并及时注册
③持久化
内存马持久化这个问题必须要往本地写文件
- 写tomcat字节码里
- 改写依赖的jar
- doFilter插入恶意注册代码
- 瞒天过海计之Tomcat隐藏内存马 - admin-神风 - 博客园 (cnblogs.com)
④Agent内存马应急
通过javassist对照本地原始库中的字节码修改回去
⑤陌生框架如何挖掘内存马
通过以往的文章,可以发现其实内存马的注册大都少不了几个点:
- context上下文环境
- request和response用于构造回显内存马
- Tomcat、Spring,毕竟内存马主要出自于这两个框架·
15、tomcat
①PUT任意写文件
7.0.0 <= Tomcat <= 7.0.79
如果Tomcat开启了PUT方法(readonly改为false,默认关闭),攻击者可以利用PUT方法上传jsp文件,从而造成远程命令执行
②CGIServer RCE
9.0.0 <= Tomcat <= 9.0.17,8.5.0 <= Tomcat <= 8.5.39,7.0.0 <= Tomcat <= 7.0.93
该漏洞是由于Tomcat CGI将命令行参数传递给Windows程序的方式存在错误,使得CGIServlet被命令注入影响。
该漏洞只影响Windows平台,要求启用了CGIServlet和enableCmdLineArguments参数。但是CGIServlet和enableCmdLineArguments参数默认情况下都不启用。
③Session反序列化
当部署tomcat时配置启用了session持久化功能FileStore,且同时存在任意文件上传漏洞,攻击者可以上传指定后缀(.session)的文件,利用可能存在的gadget反序列化,将能造成服务端远程代码执行。
原因在于FileStore类读取文件时,使用了JSESSIONID的名称,没有过滤目录穿越符号,导致攻击者可以穿越到任意目录去读取后缀为.session的序列化数据进行反序列化。
④AJP 文件包含到RCE
主要是tomcat对AJP协议的请求参数检查不严格所致
⑤未授权+war后门上传
tomcat由于配置不当导致可以未授权进入后台,上传war后门
16、weblogic
①文件上传
先决条件
- 开启"Web 服务测试页",上传页面就在这
- 知道部署应用的web目录
原理
Weblogic 开启了 Web Service Test Page(web服务测试页面),这个配置默认在生产模式下是不开启的,由于管理员没注意开启了这个页面就可能造成任意文件上传。
②未授权RCE(14882,14883)
未授权(14882)
http://your-ip:7001/console/css/%252e%252e%252fconsole.portal
RCE(14883)
- 用自带的shellcoSession函数RCE
- 远程加载xml文件
③XMLDecoder 反序列化漏洞
weblogic中,XMLDecoder来解析用户传入的XML数据,在解析的过程中出现反序列化漏洞,导致可执行任意命令。
访问http://ip:7001/wls-wsat/CoordinatorPortType,出现该页面则证明XMLDecoder漏洞存在,可以传入xml数据rce
④SSRF
访问uddiexplorer路径,修改operator参数,可以内网探测、打redis。
内网渗透
2、提权
windows
①MOF
windows <=2003
mof每隔五秒会监控一次进程的创建与死亡,它是系统权限,其中有一段是vbs脚本,我们可以控制这段vbs代码,然后通过mysql的load_file 将文件写入mof文件目录下进行提权。(c:/windows/system32/wbme/mof/)
②UDF
先决条件
- 获取mysql的权限(连接上了mysql数据库)
- Mysql>5.1,需手动创建plugin文件夹, Mysql<5.1,在c:\\windows下
- mysql有写入文件的权限,即secure_file_priv的值为空
原理
利用了root 高权限,创建带有调用cmd的函数的udf.dll动态链接库
③GPP组策略结合PTH(2008)
设置GPP组策略后域内普通用户可以访问\sysvol\sentiment.com\Policies,而该目录的子目录中会有一个xml文件,包含着用户名和密码
知道密码后可通过hash传递、psexec等进行提权
④Potato家族
热土豆
通过劫持wpad配合ntlm中继来进行提权
此漏洞影响 Windows 7、8、10、Server 2008 和 Server 2012
烂土豆(MS16-075)
通过NTLM重放攻击,为system账户协商一个安全令牌,之后通过有“身份验证后模拟客户端”的账户模仿这个令牌
多汁土豆
主要通过高权限用户的cisld进行提权
linux
①suid提权
suid 其实就是该程序所有者给可执行文件添加的一个属性,那么在该程序运行期间就会是程序所有者的权限,
假如给 find添加了 s 位,那么当我们普通用户运行 find的时候 对应的 uid 也为 0,就有了对应的root权限
②sudo提权
/etc/sudoers文件是sudo权限的配置文件,其中储存了一些可以以root权限使用的用户或命令,通过赋予其他用户root权限,或者是使用某些命令的权限,可以达到提权的效果。命令提权例如:
sudo awk 'BEGIN{system("/bin/bash")}' sudo find /home -exec /bin/bash \; sudo zip 1.zip 1.txt -T --unzip-command="sh -c /bin/bash"
③脏牛
源于Linux内核的内存子系统在处理写入拷贝时存在竞争条件(race condition),允许恶意用户提权获取其他只读内存映射的写访问权限。
3、密码抓取
procdump+mimikatz 转储然后用mimikatz离线读取
4、横向移动
psexec,wmic,smbexec,winrm,net use共享+计划任务+type命令
psexec会记录大量日志,wmic不会记录下日志。wmic更为隐蔽
5、票据传递
①kerberos
Client 想要访问 Server 上的某个服务时,需要先向 AS 证明自己的身份,验证通过后AS会发放的一个TGT,随后Client再次向TGS证明自己的身份,验证通过后TGS会发放一个ST,最后Client向 Server 发起认证请求。
②黄金票据
原理
Client通过AS认证后,AS会给Client一个Logon Session Key和TGT,而Logon Session Key并不会保存在KDC中,krbtgt的NTLM Hash又是固定的,所以只要得到krbtgt的NTLM Hash,就可以伪造TGT和Logon Session Key来进入下一步Client与TGS的交互。而已有了金票后,就跳过AS验证,不用验证账户和密码,所以也不担心域管密码修改。
先决条件
- 域名称
- 域的SID值
- 域的KRBTGT账号的HASH
- 伪造任意用户名
③白银票据
先决条件
- 域名
- 域sid
- 目标服务器名
- 可利用的服务
- 服务账号的NTML HASH
- 伪造任意用户名
④金票和银票的区别
获取的权限不同
金票:伪造的TGT,可以获取任意Kerberos的访问权限银票:伪造的ST,只能访问指定的服务,如CIFS
认证流程不同
金票:同KDC交互,但不同AS交互银票:不同KDC交互,直接访问Server
加密方式不同
金票:由krbtgt NTLM Hash 加密银票:由服务账号 NTLM Hash 加密
⑤MS14-068
原理
主要是通过往TGT中插入恶意PAC,加入域管相关信息,来访问域控服务。(PAC是用来验证Client的访问权限的)
利用条件
- 域控没有打MS14-068的补丁(KB3011780)
- 拿下一台加入域的计算机
- 有这台域内计算机的域用户密码和Sid
6、约束委派
作用
用户A访问web服务器,服务器再以用户A的身份去访问文件服务器。例如:当域控访问了08机器,就在该机器上留下了票据
①非约束委派
原理
用户B想访问用户A时会向KDC提交认证,若A是非约束委派,当用户B拿着ST访问了A后就相当于得到了B的TGT,然后用B的身份访问能访问的服务。
用户B想访问服务A,于是向KDC提交认证,KDC发现A是非约束性委派,会把TGT放在ST中一并给用户B。然后用户B用这个ST去访问服务A,服务A就相当于获得了用户B的TGT,把TGT放入lsass进程,然后就可以拿着用户B的TGT以用户B的身份去访问该用户权限能够访问的服务了
②约束委派
相对于非约束委派,对特定的服务进行了限制,但引入了S4U的拓展,可以通过S4U伪造域控身份的TGT去访问域成员的ST,并将凭证保留在与成员中
③基于资源的约束委派
在大型域环境中,将机器加入到域环境中一般不会用域管权限,而是用一个专门加域的域用户。那么当我们拿下该域用户的账号密码时,就可以把通过该域用户加入到域里的所有机器都拿下。
基于资源的约束委派不需要域管理员权限去设置,⽽把设置属性的权限赋予给了机器⾃身。
7、权限维持
域权限维持
①Skeleton Key
影响版本
Server2003 <= Windows <=Windows Server2012 R2
原理
当拿到域控权限后,使用mimikatz可以注入Skeleon Key,将 Skeleton Key 注入域控制器的 lsass.exe 进程,这样会在域内的所有账号中添加一个 Skeleton Key,而这个key是自己设定的所以可以随时共享访问。
**注:**由于注入到lsass.exe进程中,所以每次关机后就不存在了
②基于验证DLL加载-SSP
SSP可以理解为一个用于身份验证的 dll,当目标系统在启动时SSP会被加载到Isass.exe进程中,所以我们可以伪造一个恶意dll文件,当目标登录到系统或重启时注入到lsass.exe
③SID History
SID也就是安全标识符,是标识用户、组和计算机帐户的唯一的号码
④Dcsync
在域环境中,不同DC间每15分钟会进行一次数据同步请求数据,mimikatz在2015年推出一个新功能Dcsync,它可以模拟一个DC从真实域控请求数据(hash等),只要赋予用户指定的DACL权限,那么普通用户也可向域控请求数据。
windows
①计划任务
②注册表自启动
③映像劫持
“映像劫持”,可以通过修改注册表中“Debugger“项值,替换执行的程序。
④GPO组策略自启动
linux
①添加超级用户
- 向passwd文件添加用户
- useradd命令添加
②suid
创建suid权限文件维权
③ssh私钥免密登录
将公钥写入authorized_keys文件中,并配置RSAAuthentication和PubkeyAuthentication为yes,用ssh秘钥远程登录
④计时任务
⑤rootkit
rootkit是维持root权限的一套工具,主要用于隐藏踪迹,收集信息
- 内核级的比如:Diamorphine
- 应用级的比如:Mafix
Mafix 是一款常用的轻量应用级别Rootkits,是通过伪造ssh协议漏洞实现远程登陆的特点是配置简单并可以自定义验证密码和端口号。
ThinkPHP
1、ThinkPHP5 命令执行
①debug模式
index.php—> start.php#run()—>app.php#param()—>method()—>server(),之后会在input和getFilter方法中,分别获取我们传入的值whoami、system,最后在filterValue通过call_user_func调用
②非debug模式
跟debug模式差不多,只是在app.php调用到了exec方法,之后也是在filterValue通过call_user_func调用
非debug模式主要是通过captcha的get方法获取GET请求的
③ByPass
- invokefunction代替input方法
- 禁用rce可以写shell,用wirte或display
- 禁用危险函数可以用大小写绕过
2、ThinkPHP3 SQL注入
①int型
注入不适用int型,因为find方法中的_parseOptions中会判断数据类型,若为int型会通过intval函数将字符串转为数字,导致无法闭合
②varchar型
同样也不适用该方法,在int判断完之后,会进入select函数执行select语句,但在执行之前会进入buildSelectSql进行一系列的过滤,最后通过is_string判断类型varchar会被escapeString方法进行转义
③数组绕过
前边会通过is_string被转义,但是数组则会进入else,retrun返回,返回后即可在select方法中成功查询
④exp、bind注入
传参?username[0]=exp或?id[0]=bind,在执行过程中不会被过滤成功执行
3、ThinkPHP5 文件包含
主要是通过对cachFile进行变量覆盖导致的
具体流程就是在最后的read()方法中,有一个include $cachFile;,而在执行这个之前会进行变量覆盖,将我们传入的cachFile覆盖到对应的变量中,导致文件包含
Others
1、入侵排查
①日志、②/etc/passwd和/etc/shadow、③/var/log/lastlog登录记录、④top查看异常进程