Understanding Byte, Endianness, and Memory Addressing in Computer Systems
Delve into the intricacies of bytes, endianness, and memory addressing in computer systems through information on gdbserver installation, binary representation, ASCII encoding, byte sizes, and memory address allocation. Explore the fundamentals of data representation and manipulation to enhance your understanding of how computers handle information.
Download Presentation
Please find below an Image/Link to download the presentation.
The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author. Download presentation by click this link. If you encounter any issues during the download, it is possible that the publisher has removed the file from their server.
E N D
Presentation Transcript
CSE 545 Stack Overflow Tiffany Bao tbao@asu.edu
Please install gdbserverin your Linux environment. e.g., sudo apt install gdbserver 1
01010001010001001111101010001010001010001001111101010001010 00101000100111110101000101000101000100111110101000101000101 000100111110101000101001001101001110001010001001111101010001 01000101000100111110101000101000101000100111110010100010100 010011111010100010100010100010011111010100010100010100010011 1110101000101000101000100111110101000101000101000100111110101 00010100100110100111000101000100111110101000101000101000100 1111101010001010001010001001111100101000101000100111110101000 10100010100010011111010100010100010100010011111010100010100 0101000100111110110101000100100110100111000101000100111110101 Byt e Byt e
7 7 6 6 5 5 4 4 3 3 2 2 1 1 0 0 Bit Posit ion Bit Posit ion 1 1 0 0 1 1 0 0 1 1 1 1 0 0 0 0 1 1 0 0 1 1 0 0 1 1 1 1 0 0 0 0 1 * 2 1 * 23 3+ 1 * 2 + 1 * 21 1= 10 a a = 10 1 * 2 1 * 23 3+ 1 * 2 + 1 * 22 2= 12 c c = 12 0xac 0xac
char a = a; ASCII ASCII: : A Amer ican mer ican S St andar d t andar d C Code f or ode f or I Inf or mat ion nf or mat ion I Int er change nt er change a : 0x61 : 0x61 0 0 1 1 1 1 0 0 0 0 0 0 0 0 1 1 0x61 0x61
char a[2] = ab; a : 0x61 : 0x61 b : 0x62 : 0x62 0x61 0x61 0x62 0x62 Byt e 1 Byt e 1 Byt e 2 Byt e 2 Low memor y addr ess Low memor y addr ess High memor y addr ess High memor y addr ess
int i = 1100; int : 4 byt es, int : 4 byt es, i i = 0x44c = 0x 00 00 04 4c = 0x44c = 0x 00 00 04 4c Byt e 1 Byt e 1 Byt e 3 Byt e 3 Byt e 2 Byt e 2 Byt e 4 Byt e 4 Low memor y addr ess Low memor y addr ess High memor y addr ess High memor y addr ess
int i = 1100; int : 4 byt es, int : 4 byt es, i i = 0x44c = 0x 00 00 04 4c = 0x44c = 0x 00 00 04 4c Byt e 1 Byt e 1 Byt e 3 Byt e 3 Byt e 2 Byt e 2 Byt e 4 Byt e 4 Low memor y addr ess Low memor y addr ess High memor y addr ess High memor y addr ess
int i = 1100; int : 4 byt es, int : 4 byt es, i i = 0x44c = 0x 00 00 04 4c = 0x44c = 0x 00 00 04 4c 4c 4c 04 04 00 00 00 00 Byt e 1 Byt e 1 Byt e 3 Byt e 3 Byt e 2 Byt e 2 Byt e 4 Byt e 4 Low memor y addr ess Low memor y addr ess High memor y addr ess High memor y addr ess
char s[4] = \x4c\x04\x00\x00; 4c 4c 04 04 00 00 00 00 Byt e 1 Byt e 1 Byt e 3 Byt e 3 Byt e 2 Byt e 2 Byt e 4 Byt e 4 Low memor y addr ess Low memor y addr ess High memor y addr ess High memor y addr ess To int : 0x 00 00 04 4c = 0x44c = 1100 To int : 0x 00 00 04 4c = 0x44c = 1100
int i = 1100; int : 4 byt es, int : 4 byt es, i i = 0x44c = 0x 00 00 04 4c 32 bits: struct.pack( <i , 1100) pwn.p32(1100) 64 bits: struct.pack( <I , 1100) pwn.p64(1100) = 0x44c = 0x 00 00 04 4c 4c 4c 04 04 00 00 00 00 Byt e 1 Byt e 1 Byt e 3 Byt e 3 Byt e 2 Byt e 2 Byt e 4 Byt e 4 Low memor y addr ess Low memor y addr ess High memor y addr ess High memor y addr ess
char s[4] = \x4c\x04\x00\x00; 4c 4c 04 04 00 00 00 00 32 bits: struct.unpack("<i", "\x4c\x04\x00\x00")[0] 64 bits: struct.unpack("<I", "\x4c\x04\x00\x00")[0] Byt e 1 Byt e 1 Byt e 3 Byt e 3 Byt e 2 Byt e 2 Byt e 4 Byt e 4 Low memor y addr ess Low memor y addr ess High memor y addr ess High memor y addr ess To int : 0x 00 00 04 4c = 0x44c = 1100 To int : 0x 00 00 04 4c = 0x44c = 1100
low address void foo(){ int x = 0; int y = 1; printf( %d\n , x + y); } void bar(){ foo(); printf( bye\n ); } saved rip high address rsp -> rbp -> 16
low address void foo(){ int x = 0; int y = 1; printf( %d\n , x + y); } <+0>: <+1>: <+4>: push rbp mov rbp,rsp sub rsp,0x50 void bar(){ foo(); printf( bye\n ); } rsp -> saved rip (return address) high address rbp -> 17
low address void foo(){ int x = 0; int y = 1; printf( %d\n , x + y); } <+0>: <+1>: <+4>: push rbp mov rbp,rsp sub rsp,0x50 rsp -> saved rbp saved rip (return address) void bar(){ foo(); printf( bye\n ); } high address rbp -> 18
low address void foo(){ int x = 0; int y = 1; printf( %d\n , x + y); } <+0>: <+1>: <+4>: push rbp mov rbp,rsp sub rsp,0x50 rsp -> rbp -> saved rbp saved rip (return address) void bar(){ foo(); printf( bye\n ); } high address 19
low address rsp -> void foo(){ int x = 0; int y = 1; printf( %d\n , x + y); } <+0>: <+1>: <+4>: push rbp mov rbp,rsp sub rsp,0x50 rbp -> saved rbp saved rip (return address) void bar(){ foo(); printf( bye\n ); } high address 20
low address mov rsp, rbp pop rbp void foo(){ int x = 0; int y = 1; printf( %d\n , x + y); } <+182>: leave <+183>: ret rsp -> rbp -> saved rbp saved rip (return address) void bar(){ foo(); printf( bye\n ); } high address 21
low address mov rsp, rbp pop rbp void foo(){ int x = 0; int y = 1; printf( %d\n , x + y); } <+182>: leave <+183>: ret saved rbp saved rip (return address) void bar(){ foo(); printf( bye\n ); } rsp -> high address rbp -> 22
low address void foo(){ int x = 0; int y = 1; printf( %d\n , x + y); } <+182>: leave <+183>: ret saved rbp saved rip (return address) void bar(){ foo(); printf( bye\n ); } rip high address rsp -> rbp -> 23
low address void foo(){ int x = 0; int y = 1; printf( %d\n , x + y); } <+182>: leave <+183>: ret Over wr i Over wr i t e t e saved rbp saved rip (return address) void bar(){ foo(); printf( bye\n ); } rip high address rsp -> rbp -> 24
void check(char id[15]){ char path[50] = {}; int res; sprintf(path, "records/%s", id); if (valid_path(path) != 0){ res = execl("/usr/bin/cat", "/usr/bin/cat", path, NULL); if (res == 0) printf("Check pass!\n"); else printf("Check failed\n"); } } int main(){ char *id = NULL; size_t size = 0; ssize_t len = 0; len = getline(&id, &size, stdin); id[len - 1] = 0; check(id); } 25
rsp -> void check(char id[15]){ char path[50] = {}; char path[50] int res; sprintf(path, "records/%s", id); if (valid_path(path) != 0){ int res saved rbp saved rip (return address) rbp -> res = execl("/usr/bin/cat", rbp + 8 -> "/usr/bin/cat", path, NULL); if (res == 0) printf("Check pass!\n"); else printf("Check failed\n"); } } 26
rsp -> void check(char id[15]){ char path[50] = {}; char path[50] int res; sprintf(path, "records/%s", id); Over wr it e Over wr it e if (valid_path(path) != 0){ int res saved rbp saved rip (return address) rbp -> res = execl("/usr/bin/cat", rbp + 8 -> "/usr/bin/cat", path, NULL); if (res == 0) printf("Check pass!\n"); else printf("Check failed\n"); } } 27
rsp -> void check(char id[15]){ char path[50] = {}; char path[50] int res; sprintf(path, "records/%s", id); Over wr it e Over wr it e if (valid_path(path) != 0){ int res saved rbp saved rip (return address) rbp -> res = execl("/usr/bin/cat", rbp + 8 -> "/usr/bin/cat", path, NULL); 0xdeadbeefdeadbeef if (res == 0) printf("Check pass!\n"); else printf("Check failed\n"); } } 28
rsp -> 1. 2. Check the address of saved rip 3. Overwrite path until the saved rip Check the address of path char path[50] Over wr it e Over wr it e int res saved rbp saved rip (return address) rbp -> rbp + 8 -> 0xdeadbeefdeadbeef sprintf(path, "records/%s", id); 29
How to take advantage of the vulnerability? 30
Stack Overflow + Shellcode 31
void record(){ } rsp -> char path[50] int check(char *id){ char path[50] = {}; sprintf(path, "records/%s", id); return(access(path, F_OK) != -1); } Over wr it e Over wr it e int res saved rbp saved rip (return address) rbp -> rbp + 8 -> record() 32
void record(){ } rsp -> char path[50] int check(char *id){ char path[50] = {}; sprintf(path, "records/%s", id); return(access(path, F_OK) != -1); } shellcode Over wr it e Over wr it e int res saved rbp saved rip (return address) rbp -> rbp + 8 -> &path 33
Instructions you hope to execute. What do you wanna execute? 34
get the shell: execute /bin/sh so that attacker can act as if operating on the victim machine with a shell or other purpose: e.g., read a secret file 36
There may be special conditions on the inputs e.g., no \n , no \0 , readable, etc. The buffer is not long enough. 37
void record(){ } int check(char *id){ char path[50] = {}; sprintf(path, "records/%s", id); [code] return(access(path, F_OK) != -1); } <- time of triggering <- time of exploiting 38
http://shell-storm.org/shellcode/ pwnlib.shellcraft: https://docs.pwntools.com/en/stable/shellcraf t.html Write your own shellcode! 39
1. write disassembly, and compile it or write source code, and compile it 2. get the disassembly by objdump objdump -d [binary] 40
section .data ; initialized variable message: db 'Hello world!' section .bss ; uninitialized variable filename: resb 255 ; Reserve 255 bytes section .text ; Code goes here global _start _start: mov edx, $message nasm -felf64 example.s -o example 41
.global _start _start: .intel_syntax noprefix mov rdx, message message: .string "abc" gcc -nostdlib -static ./example.s 42
Service IP: 107.21.135.41 Port: 3333 Connect to the server: nc 107.21.135.41 3333 Service file: https://cse545.tiffanybao.com/labs/week4/service.c https://cse545.tiffanybao.com/labs/week4/service