0x1 Shellcode-Lab 32Bit Basics
0x1 Shellcode-Lab 32Bit Basics
by Marco Lux
Syscall Basics
INTRO
2
PREREQUISITES
3
PREREQUISITES OS
[multilib]
Include = /etc/pacman.d/mirrorlist
# pacman -S multilib
# pacman -S lib32-glibc
4
SYNTAX
• AT&T Syntax
• Looks a bit more “odd”
• Forced to be more correct
• Advantage in ordering
• Calculation of addresses are a nightmare
5
SYNTAX
• AT&T Syntax
• Instruction, Src Operand, Dst Operand
6
SYNTAX
• AT&T Syntax
• What’s about that one:
7
SYNTAX
• Intel Syntax
• More aesthetic and obvious
• Mathematical touch
8
SYNTAX
• Intel Syntax
9
SYNTAX
• Intel Syntax
10
SYNTAXES
11
CPU REGISTERS
12
CPU GENERAL PURPOSE
REGISTERS
● We can address different components of registers
● Save space
● Being exact
● No Nullbytes
13
CPU GENERAL PURPOSE
REGISTERS
14
SYSCALL
● What is a syscall?
● *nix using Syscalls!
● man 2 syscall
● Quite some differences in number 32/64bit
● /usr/include/asm/unistd_32.h
● /usr/include/asm/unistd_64.h
15
SYSCALL EXAMPLES
• 32BIT • 64Bit
● exit 1 ● exit 60
● read 3 ● read 0
● write 4 ● write 1
● open 5 ● open 2
● close 6 ● close 3
● execve 11 ● execve 59
● chdir 12 ● chdir 80
● chmod 15 ● chmod 90
● kill 37 ● kill 62
16
SYSCALL
17
SYSCALL
18
BASIC ASSEMBLY INSTRUCTIONS
19
BASIC ASSEMBLY INSTRUCTIONS
20
BASIC ASSEMBLY INSTRUCTIONS
21
BASIC ASSEMBLY INSTRUCTIONS
22
23
BASIC ASSEMBLY INSTRUCTIONS
24
BASIC ASSEMBLY INSTRUCTIONS
25
BASIC ASSEMBLY INSTRUCTIONS
26
BASIC ASSEMBLY INSTRUCTIONS
● NOP
● Please note that NOPs are discussed a lot for nopsleds
● While opcode 0x90 is the ‘default’ NOP
● Everything *can* be a nop
● As long it is not destroying your payload
● Or the state of the application you attack
27
BASIC ASSEMBLY INSTRUCTIONS
28
BASIC ASSEMBLY INSTRUCTIONS
29
BASIC ASSEMBLY INSTRUCTIONS
30
BASIC ASSEMBLY INSTRUCTIONS
● CALL Call toplabel
● Call a function Result Calls label: Continues
toplabel execution at
label, but saves
return address
● Difference to jump is, that the function prologue is executed
“In assembly language programming, the function prologue is a few lines of code at the
beginning of a function, which prepare the stack and registers for use within the function.
Similarly, the function epilogue appears at the end of the function, and restores the stack
and registers to the state they were in before the function was called.”
https://en.wikipedia.org/wiki/Function_prologue
31
BASIC ASSEMBLY INSTRUCTIONS
32
BASIC ASSEMBLY INSTRUCTIONS
Mnemonic Dest Operand Src Operand Explanation
xor eax ebx Do an Boolean
exclusive or
mov eax 0x23 Copy a value into
mov eax ebx destination
push eax Place a value on
push 0x23 the stack
pop eax From stack pointer
to register
inc eax Increase value in
register
dec eax Decrease value in
register
jmp label Jump to a label
call function Call a function
int 80h Interrupt and
Execute 33
WARNING
34
WARNING
35
SYSCALL: EXIT
36
SYSCALL: EXIT
BITS 32
_start:
● Register EAX for Syscall (1)
xor eax, eax
● Register EBX for return-
xor ebx, ebx
code
mov eax, 1
mov ebx, 4
int 0x80
37
SYSCALL: EXIT
$ nasm -f elf32 exit.asm BITS 32
$ ld -m elf_i386 exit.o -o exit
global _start
$ ./exit
$ ./exit ; echo $?
4
_start:
xor eax, eax
xor ebx, ebx
mov eax, 1
mov ebx, 4
int 0x80
38
SYSCALL: EXIT
08048060 <_start>:
• -d for dissassembly
• -M for presenting in Intel Instruction Set
39
SYSCALL: EXIT
41
ARGL NULLBYTES
42
ARGL NULLBYTES
08048060 <_start>:
8048060: 31 c0 xor eax,eax
8048062: 31 db xor ebx,ebx
8048064: b3 04 mov bl,0x4
8048066: b0 01 mov al,0x1
8048068: cd 80 int 0x80
43
EXECUTE OUR SHELLCODE
(CLASSIC)
#include <stdio.h>
#include <unistd.h>
#include <string.h>
main()
ret();
44
EXECUTE OUR SHELLCODE
(CLASSIC)
$ gcc –m32 exit.c –o exit
$ ./exit; echo $?
$0
• Or
./exit; echo $?
$4
• Or
./exit; echo $?
Segmentation Fault
45
EXECUTE OUR SHELLCODE
(CLASSIC)
● Works on systems without stack protection
● The problem is the memory are we are writing our shellcode
too. We cannot write and execute.
● (Non-Executeable Stack)
● Several solutions:
● Compile with –z execstack (make stack executeable again)
● Create a memory area with rwx flags
46
EXECUTE OUR SHELLCODE-MMAP
(RWX FLAGS)
#include <string.h>
#include <sys/mman.h>
int (*func)();
(int)(*func)();
munmap(mem, sizeof(shellcode));
return 0;
47
BREAK ANYONE?
48
RECAP
● Registers
● Simple Stack Layout
● Exit shellcode
● How to run it on classic and how to mmap
● Of course exit is right now pretty useless for us, so lets do
something more helpful
49
COMPILING
50
BITS MODE
51
USE32
52
LABEL _START
● global _start
● global is NASM specific
● _start is not
● _start is the Entry point for the program
● Check this
● ld –verbose /bin/bash|grep ENTRY
53
LABEL _START
54
NEXT SHELLCODE
55
CHMOD 0777 /ETC/SHADOW
● man 2 chmod
● int chmod(const char *pathname, mode_t mode);
● Eax: 15, Ebx: *pathname (ptr from stack), Ecx: mode (0x1ff)
● Preview Code:
mov ecx, 0x1ff
push <string onto stack with null terminator>
mov ebx, esp
mov al, 15
56
CHMOD 0777 /ETC/SHADOW
57
CHMOD 0777 /ETC/SHADOW
<xor used registers>
;chmod
push 0x??
push 0x??
mov eax, ??
int 0x80
;exit
mov eax, ??
int 0x80
58
CHMOD 0777 /ETC/SHADOW
<xor used registers> xor eax, eax
mov eax, ??
mov ebx, esp ;put the address of esp to ebx (shadow)
int 0x80
;exit
;exit
xor eax, eax
xor eax, eax
59
SETUID R00TSHELL
● Create a shellcode which will give 4777 permissions to a
shell placed somewhere on the filesystem. NO NULLBYTES!
● Download the shell.c file here && compile it
● chown it to root
● Shellcode == chmod 4777 shell
60
SETUID R00TSHELL
● HOWTO:
● Chmod
● Exit
● check with objdump for nullbytes
● remove them(use other registers, not pushb 0x0)
● compile the shell and put it somewhere, chown by hand to root
● Use your shellcode with mmap to change the permissions of the file
● Result:
$ ./r00tshell
# id
uid=0(root) gid=1000(shell)
groups=0(root),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),108(lpadmin),124(sambashare),1000(shell)
61
SETUID R00TSHELL
Problems?
62
ADDUSER TO /ETC/PASSWD
63
ADDUSER TO /ETC/PASSWD
64
ADDUSER TO /ETC/PASSWD
65
ADDUSER TO /ETC/PASSWD
• Check following include files:
/usr/include/bits/fcntl.h
/usr/include/bits/fcntl-linux.h
$1 = 0x401
66
ADDUSER TO /ETC/PASSWD
;write
;open
ret value(file descriptor) is in eax, so lets grab it:
mov eax, ?? syscall ??
xor ebx
67
ADDUSER TO /ETC/PASSWD
68
ADDUSER TO /ETC/PASSWD
● Hint:
● push byte 0x0a
69
ADDUSER TO /ETC/PASSWD
70
R00TSHELL
71
R00TSHELL - SETUIDS
72
R00TSHELL - SETUID
73
R00TSHELL - EXECVE
74
BAD EXECVE
;setuid
int 0x80
correct – watchout!
;execve
● Impr0ve!
Btw. Thats it for Syscall
xor ecx, ecx
●
push ecx
int 0x80
75
BAD EXECVE
TROUBLESHOOTING
77
REFERENCES
● Sockets, Shellcode, Porting & Coding – James C Foster
● History and advances in Windows Shellcode – SK
● http://phrack.org/issues/62/7.html
78
PREREQUISITES C0DE
● Code Snippets in Example_Code folder:
● adduser_etc_passwd.asm - Adding a user with password to /etc/passwd
● bad_setuid_shell.asm - Setuid Root shell
● crypt_des_tool.py - Addon for ‘adduser_etc_passwd.asm’
● skeleton_oldstyle.c – Exploit skeleton for our shellcode
● ascii_converter.py - Convert text, prepare for push
● chmod_shadow_0bytes.asm - relates to 2nd handson
● shell.c – c shell
● ascii_converter2.py – slightly improved version
● chmod_shadow_no0.asm - chmod code without 0 bytes
● skeleton_mmap.c – Exploit skeleton with mmap usage
79
EOF