Slide 1

Slide 1 text

別PWN那裡 DoubleSigma Terrynini

Slide 2

Slide 2 text

ancient pwn basic

Slide 3

Slide 3 text

Before learning the ancient pwn, Make sure that you understand the concept of stack frame. If your answer is negative, there is an ancient material for you from 2018/12/14. All the example code are at the end of this material.

Slide 4

Slide 4 text

ancient pwn buffer overflow

Slide 5

Slide 5 text

ancient pwn $ gcc -fno-stack-protector pwn_01.c -o pwn_01
 $ ./pwn_01
 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
 [1] 19730 segmentation fault (core dumped) ./pwn_01 These are some ancient tricks, so we have to turn off some modern feature.

Slide 6

Slide 6 text

ancient pwn Previous RBP Return Address aaaaaaaa aaaaaaaa aaaaaaaa low address high address name[0]~name[7] name[8]~name[15] name[16]~name[23]

Slide 7

Slide 7 text

ancient pwn Previous RBP Return Address aaaaaaaa aaaaaaaa aaaaaaaa low address high address name[0]~name[7] name[8]~name[15] name[16]~name[23] aaaaaaaa aaaaaaaa

Slide 8

Slide 8 text

ancient pwn Previous RBP Return Address aaaaaaaa aaaaaaaa aaaaaaaa low address high address name[0]~name[7] name[8]~name[15] name[16]~name[23] aaaaaaaa aaaaaaaa STACK Overflow ! /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Slide 9

Slide 9 text

ancient pwn gets() is deprecated, because it’s dangerous.

Slide 10

Slide 10 text

ancient pwn $ gcc -fno-stack-protector pwn_02.c -o pwn_02

Slide 11

Slide 11 text

ancient pwn 0 Previous RBP Return Address \00\00\00\00\00\00\00\00 low address high address visitor.name[0]~visitor.name[7] visitor.Taiwan_value

Slide 12

Slide 12 text

ancient pwn 0 Previous RBP Return Address aaaaaaaa low address high address visitor.name[0]~visitor.name[7] visitor.Taiwan_value

Slide 13

Slide 13 text

ancient pwn 0 Previous RBP Return Address aaaaaaaa low address high address visitor.name[0]~visitor.name[7] visitor.Taiwan_value 0x6161616161616161

Slide 14

Slide 14 text

ancient pwn 0 Previous RBP Return Address aaaaaaaa low address high address visitor.name[0]~visitor.name[7] visitor.Taiwan_value Buffer Overflow! 0x6161616161616161 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Slide 15

Slide 15 text

ancient pwn ret2text

Slide 16

Slide 16 text

ancient pwn $ gcc -fno-stack-protector -no-pie pwn_03.c -o pwn_03 Let’s pwn with pwntool this time.

Slide 17

Slide 17 text

ancient pwn Return Address aaaaaaaa aaaaaaaa low address high address name[0]~name[7] name[8]~name[15] Previous RBP

Slide 18

Slide 18 text

ancient pwn Return Address aaaaaaaa aaaaaaaa low address high address name[0]~name[7] name[8]~name[15] Previous RBP aaaaaaaa 0x0400577 0000000000400577 : 400577: push rbp 400578: mov rbp,rsp 40057b: lea rdi,[rip+0xd6] 400582: call 400460 400587: nop 400588: pop rbp 400589: ret .--------------------------------------. | | | | | | | | | | | | | | | | '--------------------------------------'

Slide 19

Slide 19 text

.--------------------------------------. | | | | | | | | | | | | | | | | '--------------------------------------' ancient pwn Return Address aaaaaaaa aaaaaaaa low address high address name[0]~name[7] name[8]~name[15] Previous RBP aaaaaaaa 0x0400577 Control Flow Hijack ! /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 0000000000400577 : 400577: push rbp 400578: mov rbp,rsp 40057b: lea rdi,[rip+0xd6] 400582: call 400460 400587: nop 400588: pop rbp 400589: ret

Slide 20

Slide 20 text

ancient pwn Controlling the return address, and jump to a piece of code. It was named ret2text.

Slide 21

Slide 21 text

ancient pwn ret2sc

Slide 22

Slide 22 text

Shellcode $ gcc -fno-stack-protector -z execstack pwn_04.c -o pwn_04

Slide 23

Slide 23 text

Return Address shellcode shellcode note[0x90]~note[0x97] Previous RBP Shellcode push 0x68 mov rax, 0x732f2f2f6e69622f push rax mov rdi, rsp push 0x1010101 ^ 0x6873 xor dword ptr [rsp], 0x1010101 xor esi, esi push rsi push 8 pop rsi add rsi, rsp push rsi mov rsi, rsp xor edx, edx push SYS_execve pop rax syscall note[0x97]~note[0x9e] .------------------------------------. | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | '------------------------------------' | | | asm() '---------------------------->

Slide 24

Slide 24 text

Return Address shellcode shellcode 0x7ffcbe83d7c0 high address note[0x90]~note[0x97] Previous RBP Shellcode note[0x97]~note[0x9e]

Slide 25

Slide 25 text

Return Address shellcode shellcode 0x7ffcbe83d7c0 high address Previous RBP Shellcode Garbage 0x7ffcbe83d7c0 note[0x90]~note[0x97] note[0x97]~note[0x9e]

Slide 26

Slide 26 text

Return Address shellcode shellcode 0x7ffcbe83d7c0 high address Previous RBP Shellcode Garbage 0x7ffcbe83d7c0 note[0x90]~note[0x97] note[0x97]~note[0x9e] retturn to shellcode! /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Slide 27

Slide 27 text

ancient pwn Practice time

Slide 28

Slide 28 text

ancient pwn How ancient humans deal with these kind of attack?

Slide 29

Slide 29 text

Stack Guard Previous RBP Return Address aaaaaaaa aaaaaaaa aaaaaaaa low address high address name[0]~name[7] name[8]~name[15] name[16]~name[23] canary

Slide 30

Slide 30 text

Previous RBP Return Address aaaaaaaa aaaaaaaa aaaaaaaa low address high address name[0]~name[7] name[8]~name[15] name[16]~name[23] canary aaaaaaaa aaaaaaaa aaaaaaaa Stack Guard

Slide 31

Slide 31 text

Previous RBP Return Address aaaaaaaa aaaaaaaa aaaaaaaa low address high address name[0]~name[7] name[8]~name[15] name[16]~name[23] canary aaaaaaaa aaaaaaaa aaaaaaaa stack smashing detected /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Stack Guard

Slide 32

Slide 32 text

ASLR Address Space Layout Randomization It’s a feature of kernel, Linux kernel enable it by default. To randomize the .text, a binary have to be compiled with PIE.

Slide 33

Slide 33 text

ASLR Address Space Layout Randomization $ gcc -fno-stack-protector pwn_03.c -o pwn_03

Slide 34

Slide 34 text

ASLR Address Space Layout Randomization 0000000000400577 : 400577: push rbp 400578: mov rbp,rsp 40057b: lea rdi,[rip+0xd6] 400582: call 400460 400587: nop 400588: pop rbp 400589: ret 00000000000006ca : 6ca: push rbp 6cb: mov rbp,rsp 6ce: lea rdi,[rip+0xd3] 6d5: call 580 6da: nop 6db: pop rbp 6dc: ret .---------------------------------------. .----------------------------------. | | | | | | | | | | | | | | PIE | | | |>>>>>>>>>>>>>>>>>>>>>>| | | | | | | | | |
 | | | | | | | |
 | | | | '---------------------------------------' '----------------------------------'

Slide 35

Slide 35 text

DEP Data execution prevention Need hardware support which called CPU NX bit. NX bit, no execute bit, marks certain areas of memory as non-executable.

Slide 36

Slide 36 text

$ gcc -fno-stack-protector pwn_04.c -o pwn_04 DEP Data execution prevention The shellcode on stack and heap would become unexecutable.

Slide 37

Slide 37 text

ancient pwn ret2plt

Slide 38

Slide 38 text

PLT&GOT Procedure Linkage Table & Global offset Table A dynamic link binary has to relocate library function calls during execution. $ gcc -c pwn_05.c -o pwn_05.o

Slide 39

Slide 39 text

PLT&GOT Procedure Linkage Table & Global offset Table A dynamic link binary has to relocate library function calls during execution. $ gcc -c pwn_04.c -o pwn_04.o

Slide 40

Slide 40 text

PLT&GOT Procedure Linkage Table & Global offset Table External functions are unknown during the link stage, and we shouldn’t modify the instruction after compilation. 0000000000000000 : ... 30: e8 00 00 00 00 call 35 35: 48 8d 85 f0 fe ff ff lea rax,[rbp-0x110]

Slide 41

Slide 41 text

PLT&GOT Procedure Linkage Table & Global offset Table To solve that, we have GOT, global offset table. ld is response to resolve xxxx@GLIBC during loading. : call printf@GOT GOT 0x12345678 <_IO_puts@@GLIBC_2.2.5>: push r13 push r12 mov r12,rdi push rbp push rbx .---------------.
 | scanf@GLIBC | '---------------' .---------------.
 | printf@GLIBC | '---------------' .---------------.
 | read@GLIBC | '---------------' .---------------.
 | exit@GLIBC | '---------------' .------------> ---' .-------> | ---'

Slide 42

Slide 42 text

PLT&GOT Procedure Linkage Table & Global offset Table When a binary is too big, it takes lots of time to fill out GOT. Sometimes, some functions won’t be called during execution, we don’t need to resolve them each time.

Slide 43

Slide 43 text

PLT&GOT Procedure Linkage Table & Global offset Table To solve that, we have PLT, procedure linkage table, and a mechanism named Lazy binding. : call printf@plt GOT .---------------.
 | printf@GLIBC | '---------------' .-------> ---' .-----------------------------------. |: | | jmp QWORD PTR [rip+0x200aba] | | push 0x0 | | jmp 500 <.plt> | '-----------------------------------' .----------> | | first call | -----------' ------------. second call | | | | '----> .----. | ld | '----' | | | | resolve | | | v

Slide 44

Slide 44 text

ret2plt Return Address aaaaaaaa aaaaaaaa low address high address Previous RBP .-----------------------------------. |: | | jmp QWORD PTR [rip+0x200aba] | | push 0x0 | | jmp 500 <.plt> | '-----------------------------------'

Slide 45

Slide 45 text

ret2plt Return Address aaaaaaaa aaaaaaaa low address high address Previous RBP Garbage printf@plt .-----------------------------------. |: | | jmp QWORD PTR [rip+0x200aba] | | push 0x0 | | jmp 500 <.plt> | '-----------------------------------'

Slide 46

Slide 46 text

Return Address aaaaaaaa aaaaaaaa low address high address Previous RBP Garbage printf@plt .-----------------------------------. |: | | jmp QWORD PTR [rip+0x200aba] | | push 0x0 | | jmp 500 <.plt> | '-----------------------------------' Return to plt ! /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ret2plt

Slide 47

Slide 47 text

ancient pwn GOT hijack

Slide 48

Slide 48 text

$ gcc -zlazy pwn_04.c -o pwn_04 GOT Hijack If the Lazy Binding is applied, GOT must be writable.

Slide 49

Slide 49 text

.---------------.
 | call puts | '---------------' GOT+0x20 .------------.
 | puts@GLIBC | '------------' ---> -------> 0x12345678 <_IO_puts@@GLIBC_2.2.5>: push r13 push r12 mov r12,rdi push rbp push rbx .---------------------------. | | | | | | | | | | | | | | '---------------------------' .-----------------.
 | puts(“/bin/sh”) | '-----------------' ---> GOT Hijack

Slide 50

Slide 50 text

.---------------------------------------------.
 | GOT+0x20 = __libc_system@@GLIBC_PRIVATE | '---------------------------------------------' .---------------.
 | call puts | '---------------' GOT+0x20 .------------.
 | puts@GLIBC | '------------' ---> -------> 0x12345678 <_IO_puts@@GLIBC_2.2.5>: push r13 push r12 mov r12,rdi push rbp push rbx .---------------------------. | | | | | | | | | | | | | | '---------------------------' .-----------------.
 | puts(“/bin/sh”) | '-----------------' ---> GOT Hijack

Slide 51

Slide 51 text

.---------------------------------------------.
 | GOT+0x20 = __libc_system@@GLIBC_PRIVATE | '---------------------------------------------' | .--------------------------' | | | v Over Write .---------------.
 | call puts | '---------------' GOT+0x20 .------------.
 | puts@GLIBC | '------------' ---> -------> 0x12345678 <_IO_puts@@GLIBC_2.2.5>: push r13 push r12 mov r12,rdi push rbp push rbx .---------------------------. | | | | | | | | | | | | | | '---------------------------' .-----------------.
 | puts(“/bin/sh”) | '-----------------' ---> GOT Hijack

Slide 52

Slide 52 text

.------------.
 | call puts | '------------' GOT+0x20 .-------------------------------.
 | __libc_system@@GLIBC_PRIVATE | '-------------------------------' ---> .-----------------.
 | puts(“/bin/sh”) | '-----------------' ---> .---------------------------------------------.
 | GOT+0x20 = __libc_system@@GLIBC_PRIVATE | '---------------------------------------------' | .--------------------------' | | | v Over Write ---> .-------------------.
 | system(“/bin/sh”) | '-------------------' GOT Hijack

Slide 53

Slide 53 text

GOT Hijack .------------.
 | call puts | '------------' GOT+0x20 .-------------------------------.
 | __libc_system@@GLIBC_PRIVATE | '-------------------------------' ---> .-----------------.
 | puts(“/bin/sh”) | '-----------------' ---> .---------------------------------------------.
 | GOT+0x20 = __libc_system@@GLIBC_PRIVATE | '---------------------------------------------' | .--------------------------' | | | v Over Write ---> .-------------------.
 | system(“/bin/sh”) | '-------------------' GOT Hijack ! /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Slide 54

Slide 54 text

But you have to leak libc base address first. GOT Hijack

Slide 55

Slide 55 text

ancient pwn Practice time

Slide 56

Slide 56 text

ancient pwn ROP

Slide 57

Slide 57 text

ROP Return Oriented Programming What if we can’t reach our goal by jumping on a piece of code?

Slide 58

Slide 58 text

.------------. | | | | | | | | '------------' ROP Return Oriented Programming xor rax, rax ret inc rax ret mov rcx, rax ret .------------. | | | | | | | | '------------' .--------------. | | | | | | | | '--------------' 0x8010AB0 0x8010CD0 0x8010EF0 + +

Slide 59

Slide 59 text

.----------------------------------------------------------------------------. | | | | | | | | | | | | | | | | ‘----------------------------------------------------------------------------' .------------. | | | | | | | | '------------' ROP Return Oriented Programming xor rax, rax ret inc rax ret mov rcx, rax ret .------------. | | | | | | | | '------------' .--------------. | | | | | | | | '--------------' 0x8010AB0 0x8010CD0 0x8010EF0 + + .------------. | | | | | | | | '------------' xor rax, rax inc rax mov rcx, rax .------------. | | | | | | | | '------------' rcx = 1 = =

Slide 60

Slide 60 text

.------------. | | | | | | | | '------------' .--------------. | | | | | | | | '--------------' Return Address aaaaaaaa aaaaaaaa low address high address Previous RBP .------------. | | | | | | | | '------------' xor rax, rax ret inc rax ret mov rcx, rax ret 0x8010AB0 0x8010CD0 0x8010EF0 0x8010CD0 0x8010AB0 0x8010EF0 ROP aaaaaaaa

Slide 61

Slide 61 text

ancient pwn ret2libc

Slide 62

Slide 62 text

ancient pwn Practice time

Slide 63

Slide 63 text

ancient pwn codes

Slide 64

Slide 64 text

Example pwn_01.c #include int main(){ char name[24]; gets(name); printf(" Your namename is %s.", name); return 0; }

Slide 65

Slide 65 text

Example pwn_02.c #include #include typedef struct{ char name[8]; long int Taiwan_value; }passport; int main(){ passport visitor; visitor.Taiwan_value = 0; read(0, visitor.name, 18); if( visitor.Taiwan_value > 0){ printf(" %s !? welcome, Taiwanese.", visitor.name); printf("Value : %d",visitor.Taiwan_value); }else{ printf(" %s ?? Get off, outlander.",visitor.name); } return 0; }

Slide 66

Slide 66 text

Example pwn_03.c #include #include void cheat(){ puts("My grandpa taught me this in Hawaii "); } int main(){ char name[0x10]; read(0, name, 0x20); printf("%s", name); return 0; }

Slide 67

Slide 67 text

Example pwn_04.c #include #include int main(){ char note[0x100]; printf("the address is : %p \n",note); read(0, note, 0x120); return 0; }

Slide 68

Slide 68 text

Example pwn_05.c #include #include int main(){ char note[0x100]; puts("So... where is the system ?"); system("echo 'here'"); printf("printf is at %p\nsystem is at %p\noffset = %d\n", printf, system, (int) (system)-(int)(printf)); return 0; }