Understanding Byte, Endianness, and Memory Addressing in Computer Systems

Slide Note
Embed
Share

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.


Uploaded on Sep 12, 2024 | 0 Views


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


  1. CSE 545 Stack Overflow Tiffany Bao tbao@asu.edu

  2. Please install gdbserverin your Linux environment. e.g., sudo apt install gdbserver 1

  3. Byte and Endianness

  4. 0 1

  5. 01010001010001001111101010001010001010001001111101010001010 00101000100111110101000101000101000100111110101000101000101 000100111110101000101001001101001110001010001001111101010001 01000101000100111110101000101000101000100111110010100010100 010011111010100010100010100010011111010100010100010100010011 1110101000101000101000100111110101000101000101000100111110101 00010100100110100111000101000100111110101000101000101000100 1111101010001010001010001001111100101000101000100111110101000 10100010100010011111010100010100010100010011111010100010100 0101000100111110110101000100100110100111000101000100111110101 Byt e Byt e

  6. Byte = 8 bits, ISO/IEC 2382-1:1993

  7. 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

  8. 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

  9. 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

  10. 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

  11. 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

  12. 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

  13. 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

  14. 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

  15. 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

  16. Stack overflow 15

  17. 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

  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 void bar(){ foo(); printf( bye\n ); } rsp -> saved rip (return address) high address rbp -> 17

  19. 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

  20. 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

  21. 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

  22. 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

  23. 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

  24. 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

  25. 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

  26. 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

  27. 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

  28. 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

  29. 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

  30. 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

  31. How to take advantage of the vulnerability? 30

  32. Stack Overflow + Shellcode 31

  33. 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

  34. 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

  35. Instructions you hope to execute. What do you wanna execute? 34

  36. http://shell-storm.org/shellcode/ 35

  37. 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

  38. There may be special conditions on the inputs e.g., no \n , no \0 , readable, etc. The buffer is not long enough. 37

  39. 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

  40. http://shell-storm.org/shellcode/ pwnlib.shellcraft: https://docs.pwntools.com/en/stable/shellcraf t.html Write your own shellcode! 39

  41. 1. write disassembly, and compile it or write source code, and compile it 2. get the disassembly by objdump objdump -d [binary] 40

  42. 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

  43. .global _start _start: .intel_syntax noprefix mov rdx, message message: .string "abc" gcc -nostdlib -static ./example.s 42

  44. 43

  45. In-class Lab

  46. 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

  47. alias: PIC, position independent code 46

Related