Ron Halfon
Ron Halfon

Reputation: 105

NASM Segmentation fault

I'm using a 64-bit Ubuntu 18.04.3 LTS VM and I'm trying to write a simple x64 assembly code that will print "Owned!!!".

Because I don't want any 0x00 or 0x0a bytes and I want the code to be position independent (because I'm learning how to write shellcodes), I wrote it this way:

;hello4.asm  attempts to make the code position independent

section .text

global _start

_start:
;clear out the registers we are going to need
xor rax, rax
xor rbx, rbx
xor rcx, rcx
xor rdx, rdx

;write(int fd, char *msg, unsigned int len)
mov al, 4
mov bl, 1
;Owned!!! =  4f,77,6e,65,64,21,21,21
;push !,!,!,d
push 0x21212164
;push e,n,w,O 
push 0x656e774f
mov rcx, rsp
mov dl, 8
int 0x80

;exit(int ret)
mov al,1
xor rbx, rbx
int 0x80

This is the output that I'm getting:

user@PC:~/Desktop/exploitsclass/hello_shellcode$ nasm -f elf64 hello4.asm
user@PC:~/Desktop/exploitsclass/hello_shellcode$ ld hello4.o -o hello4
user@PC:~/Desktop/exploitsclass/hello_shellcode$ objdump -d hello4 -M intel

hello4:     file format elf64-x86-64


Disassembly of section .text:

0000000000400080 <_start>:
  400080:   48 31 c0                xor    rax,rax
  400083:   48 31 db                xor    rbx,rbx
  400086:   48 31 c9                xor    rcx,rcx
  400089:   48 31 d2                xor    rdx,rdx
  40008c:   b0 04                   mov    al,0x4
  40008e:   b3 01                   mov    bl,0x1
  400090:   68 64 21 21 21          push   0x21212164
  400095:   68 4f 77 6e 65          push   0x656e774f
  40009a:   48 89 e1                mov    rcx,rsp
  40009d:   b2 08                   mov    dl,0x8
  40009f:   cd 80                   int    0x80
  4000a1:   b0 01                   mov    al,0x1
  4000a3:   48 31 db                xor    rbx,rbx
  4000a6:   cd 80                   int    0x80
user@PC:~/Desktop/exploitsclass/hello_shellcode$ ./hello4
Segmentation fault (core dumped)

How do I fix this?

UPDATE:

I've understood that int 0x80 is intended for 32-bit programs and I should use syscall instead and that syscall has different ids for each system call.

The new code is:

;hello4.asm  attempts to make the code position independent

section .text

global _start

_start:
;clear out the registers we are going to need
xor rax, rax
xor rsi, rsi
xor rdi, rdi
xor rdx, rdx

;write(int fd, char *msg, unsigned int len)
mov al, 1
add di, 1
;Owned!!! =  4f,77,6e,65,64,21,21,21
;push !,!,!,d
push 0x21212164
;push e,n,w,O 
push 0x656e774f
mov rsi, rsp
mov dl, 8
syscall

;exit(int ret)
mov al, 60
xor rdi, rdi
syscall

The output is Owne% instead of Owned!!! now. It still needs to be fixed.

Upvotes: 0

Views: 177

Answers (2)

Yaroslav Bolyukin
Yaroslav Bolyukin

Reputation: 325

Can't answer your comment, you can't just change int 0x80 to syscall to make it work, system call numbers differ, i.e sys_write you have here, have id 4 for int 0x80, and id 1 with syscall

Here you can see numbers for syscall

And here for int 0x80

Upvotes: 0

Ron Halfon
Ron Halfon

Reputation: 105

With the help of @CertainLach I've written the correct code:

;hello4.asm  attempts to make the code position independent

section .text

global _start

_start:
;clear out the registers we are going to need
xor rax, rax
xor rsi, rsi
xor rdi, rdi
xor rdx, rdx

;write(int fd, char *msg, unsigned int len)
mov al, 1
add di, 1
;Owned!!! =  4f,77,6e,65,64,21,21,21
mov rsi, 0x21212164656e774f
push rsi
mov rsi, rsp
mov dl, 8
syscall

;exit(int ret)
mov al, 60
xor rdi, rdi
syscall

This code contains no null bytes or 0x0a bytes and it's position-independent, as following:

user@PC:~/Desktop/exploitsclass/hello_shellcode$ objdump -d hello4 -M intel

hello4:     file format elf64-x86-64


Disassembly of section .text:

0000000000400080 <_start>:
  400080:   48 31 c0                xor    rax,rax
  400083:   48 31 f6                xor    rsi,rsi
  400086:   48 31 ff                xor    rdi,rdi
  400089:   48 31 d2                xor    rdx,rdx
  40008c:   b0 01                   mov    al,0x1
  40008e:   66 83 c7 01             add    di,0x1
  400092:   48 be 4f 77 6e 65 64    movabs rsi,0x21212164656e774f
  400099:   21 21 21 
  40009c:   56                      push   rsi
  40009d:   48 89 e6                mov    rsi,rsp
  4000a0:   b2 08                   mov    dl,0x8
  4000a2:   0f 05                   syscall 
  4000a4:   b0 3c                   mov    al,0x3c
  4000a6:   48 31 ff                xor    rdi,rdi
  4000a9:   0f 05                   syscall 

This is also a correct way of implementing the solution, which is 1 bytecode less, but with more memory consumption:

user@PC:~/Desktop/exploitsclass/hello_shellcode$ cat hello4.asm
;hello4.asm  attempts to make the code position independent

section .text

global _start

_start:
;clear out the registers we are going to need
xor rax, rax
xor rsi, rsi
xor rdi, rdi
xor rdx, rdx

;write(int fd, char *msg, unsigned int len)
mov al, 1
add di, 1
;Owned!!! =  4f,77,6e,65,64,21,21,21
;push !,!,!,d
push 0x21212164
;push e,n,w,O
push 0x656e774f
mov rsi, rsp
mov dl, 16
syscall

;exit(int ret)
mov al, 60
xor rdi, rdi
syscall

user@PC:~/Desktop/exploitsclass/hello_shellcode$ objdump -d hello4 -M intel

hello4:     file format elf64-x86-64


Disassembly of section .text:

0000000000400080 <_start>:
  400080:   48 31 c0                xor    rax,rax
  400083:   48 31 f6                xor    rsi,rsi
  400086:   48 31 ff                xor    rdi,rdi
  400089:   48 31 d2                xor    rdx,rdx
  40008c:   b0 01                   mov    al,0x1
  40008e:   66 83 c7 01             add    di,0x1
  400092:   68 64 21 21 21          push   0x21212164
  400097:   68 4f 77 6e 65          push   0x656e774f
  40009c:   48 89 e6                mov    rsi,rsp
  40009f:   b2 10                   mov    dl,0x10
  4000a1:   0f 05                   syscall 
  4000a3:   b0 3c                   mov    al,0x3c
  4000a5:   48 31 ff                xor    rdi,rdi
  4000a8:   0f 05                   syscall

Thank you so much!

Upvotes: 1

Related Questions