I try to make a Programm where you put in some assembled assembly in hex and run it. With simple instructions like int3
it works, but when I try to exit from the programm with a syscall it doesnt work. I assembled it with rasm2
mov eax, 1
mov ebx, 12
int 0x80
and then put it as an argument ./Programm b801000000bb0c000000cd80 1
but i get a segfault.
Here is my code:
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
char *base16dec(char *b16str) {
size_t stingrlength = strlen(b16str);
char *decodedstr = malloc(stingrlength / 2);
for (size_t i = 0; i < stingrlength; i += 2) {
u_int8_t num = 0;
char stringIn[3];
stringIn[0] = b16str[i];
stringIn[1] = b16str[i+1];
stringIn[2] = 0;
sscanf(stringIn, "%hhx", &num);
decodedstr[i/2] = (char) num;
}
return decodedstr;
}
this decodes the hex string
int main(int argc, char *argv[]) {
char *dirstr = "XXXXXX";
char dir[7];
strcpy(dir, dirstr);
int fd = mkstemp(dir);
if (fd == -1) {
dirstr = "/tmp/XXXXXX";
char dir[12];
strcpy(dir, dirstr);
fd = mkstemp(dir);
}
unlink(dir);
this creates the tmp file where the assembly is stored
char *stringIn;
if (argc == 2) {
stringIn = malloc(strlen(argv[1]));
strcpy(stringIn, argv[1]);
} else if (argc == 3) {
u_int8_t num = 0;
sscanf(argv[2], "%hhu", &num);
if (num == 1) {
char *done = base16dec(argv[1]);
stringIn = malloc(strlen(done));
strcpy(stringIn, done);
} else {
stringIn = malloc(strlen(argv[1]));
strcpy(stringIn, argv[1]);
}
} else {
stringIn = malloc(1024);
scanf("%s", stringIn);
char *done = base16dec(stringIn);
stringIn = malloc(strlen(done));
strcpy(stringIn, done);
}
this parses and copies the input to stringIn
ftruncate(fd, strlen(stringIn));
u_int8_t *code = mmap(NULL, strlen(stringIn), PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE , fd, 0);
this expands the tmp file and makes it executable and creates a pointer to it named code
for (int i = 0; i < 1024; i++) {
code[i] = (u_int8_t) stringIn[i];
}
this copies the assembly bytes into code
#if __x86_64__
__asm__(
"mov %0, %%rbx\n"
"jmp *%%rbx"
:
: "g" (code)
: "memory"
);
#elif __i386__
__asm__(
"mov %0, %%ebx\n"
"jmp *%%ebx"
:
: "r" (code)
);
#else
#endif
this jumps to the the assembly
return 0;
}
EDIT:
I can't debug the shellcode using gdb
I use 64bit Linux Mint
I tried to copy 0
using strcpy
Since this is a shellcode you can't have null bytes. In your code you have 2 movs with immediates that are padded to 32-bits
mov eax, 1
mov ebx, 12
Which encodes as B801 000000 BB0C 000000 , when C hits the null bytes it thinks the string has ended so it only ends up copying part of the instruction and then it executes garbage.
Instead you'll need to use:
xor eax, eax
inc eax
xor ebx, ebx
mov bl, 12
This will provide the values you want for your system call and does not encode as any null bytes.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.