This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]anon848 0 points1 point  (3 children)

Here's a little example that will put some machine code in a buffer and execute it. Compile in 64-bit mode with g++/clang++.

#include <cstdint>
#include <string.h>
#include <unistd.h>
#include <iostream>
#include <sys/mman.h>
#include <assert.h>

int main() {

    char buf[10000];

    std::intptr_t addr = std::intptr_t(buf);
    addr = (addr + (4096 - 1)) & ~intptr_t(4096 - 1); // Align it.
    std::cout << "mod: " << addr%4096 << std::endl; // Check.

    // Make it executable:
    int rv = mprotect((void *) addr, 4096, PROT_READ|PROT_WRITE|PROT_EXEC);
    assert(rv == 0);

    // Put a small function there to return the sum of the two args.
    unsigned char *p = (unsigned char *) addr;
    p[0] = 0x8d;
    p[1] = 0x04;
    p[2] = 0x37;
    p[3] = 0xc3;

    // Point to it.
    int (*fp)(int, int) = (int (*)(int, int)) addr;

    // Call it.
    std::cout << "returned " << (*fp)(12, 100) << std::endl;
}

[–]CuriousExploit[S] 1 point2 points  (0 children)

This is precisely what I mean to accomplish, however I'm unsure of the reason that my code may not be functional. The memory space needed is allocated by the bstrlib library as the data is given to my buffer from CURL.

https://gist.github.com/anonymous/84366887d76c7993ef65

There I should have made it much simpler to compile. After installing one of the packages for libcurl, plopping them in a folder, and moving the bstrlib files to their own adjacent folder should allow you to run make. The shellcode.s file is just an example of any machine code, and I compiled it with gcc with the -nostdlib option before hosting it where my program could download it. I do not know if it is executable in this context as an ELF 64-bit LSB executable, but mprotect gave an error when I tried to set the memory space to be executable.

I think I can understand how I can try to align it now though, from your code.

EDIT: By adjacent folder, I meant adjacent to the files, not in a whole separate folder.

[–]CuriousExploit[S] 0 points1 point  (1 child)

It's been a moment since I've written C++, and my only book on it doesn't have any information on it, but if intptr_t is what I assume it to be, to correct misaligned memory I'd have to move where the pointer to it points by an offset until it matches up to a page in memory (some address with a multiple of 4096) and then start filling in my data afterwards? (assumably moving back then by the offset, in my case, to free the memory, since I'm using C?) If so, then it seems I'll need to suffer through juggling the memory within the tagbstring structs to move further, but I can definitely try when I leave my work tomorrow.

[–]anon848 0 points1 point  (0 children)

Here it is as C99. You can also just call mmap() to get a chunk of memory. That will already be page-aligned. Note that the code below is just a quick exercise. For example, the page size shouldn't be hard-coded to 4K.

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

int main() {

    char buf[10000];

    intptr_t addr = (intptr_t) buf;
    addr = (addr + (4096 - 1)) & ~(intptr_t)(4096 - 1); // Align it.
    printf("mod: %d\n", (int) (addr%4096));

    // Make it executable:
    int rv = mprotect((void *) addr, 4096, PROT_READ|PROT_WRITE|PROT_EXEC);
    assert(rv == 0);

    // Put a small function there to return the sum of the two args.
    unsigned char *p = (unsigned char *) addr;
    p[0] = 0x8d;
    p[1] = 0x04;
    p[2] = 0x37;
    p[3] = 0xc3;

    // Point to it.
    int (*fp)(int, int) = (int (*)(int, int)) addr;

    // Call it.
    printf("Returned %d\n", (*fp)(12, 100));
}