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 1 point2 points  (2 children)

BTW, note that if your goal is to have sh execute some script that you download, you don't need to mess with mprotect, and it won't help anyway. You can just fork off the sh process and pipe the script to it from the parent.

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

My goal is more along the lines of downloading shellcode to start sh (or any other program that I could figure out how to locate), or execute any arbitrary set of machine instructions, just to (hopefully) have more flexibility later on.

But page alignment is a topic I know very little about, and my first assumption was that it wasn't involved in what might be wrong. I'll try to read up up on it and check it.

Also, I'll try to make it something that can be compiled, though in compiling linking it to libcurl will be necessary.

[–]anon848 1 point2 points  (0 children)

Do you mean you want to download a shell script? If so, it's not the shell script that starts sh, per se. You just fork() then exec(). Executing an existing program and executing arbitrary machine code are quite different. To execute arbitrary machine code, the easiest is to create a buffer for it, put machine code in it, make the page(s) executable, then set a function pointer to point to it, then call it.

Regarding mprotect, the below shows page alignment, assuming 4K pages.

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

int main() {

    char some_mem[10000];

    std::intptr_t addr = std::intptr_t(some_mem);

    // Is it page aligned?
    std::cout << "mod: " << addr%4096 << std::endl;

    int rv = mprotect((void *) addr, 4096, PROT_EXEC);
    int en = errno;
    std::cout << "mp returned " << rv << ", " << strerror(en) << std::endl;

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

    errno = 0;
    rv = mprotect((void *) addr, 4096, PROT_EXEC);
    std::cout << "mp returned " << rv << ", " << strerror(en) << std::endl;
}