This shows you the differences between two versions of the page.
cns:labs:lab-02 [2020/10/18 02:13] dennis.plosceanu [2. Shellcode] updated task |
cns:labs:lab-02 [2022/10/17 19:18] (current) mihai.dumitru2201 [2. Shellcode] |
||
---|---|---|---|
Line 244: | Line 244: | ||
<note>What is the difference between ''-d'' and ''-D''? What does ''-M'' do? In general we encourage you to check out the manpages to find out.</note> | <note>What is the difference between ''-d'' and ''-D''? What does ''-M'' do? In general we encourage you to check out the manpages to find out.</note> | ||
- | Sometimes however it is possible that the code we are dealing with doesn't have any useful metadata associated with it, e.g. it comes in a raw (flat) binary form, the executable format is not recognized or the ELF header is corrupted. Let's take for example the ''hello2'' binary generated from ''hello2.S'' in the [[http://elf.cs.pub.ro/oss/res/labs/lab-02.tar.gz|lab archive]]: | + | Sometimes however it is possible that the code we are dealing with doesn't have any useful metadata associated with it, e.g. it comes in a raw (flat) binary form, the executable format is not recognized or the ELF header is corrupted. Let's take for example the ''hello2'' binary generated from ''hello2.S'' in the ''01-hello'' dorectory: |
<code text> | <code text> | ||
Line 465: | Line 465: | ||
<note important> | <note important> | ||
Note that we have removed Address Space Layout Randomization for these examples. We'll explain this later. | Note that we have removed Address Space Layout Randomization for these examples. We'll explain this later. | ||
+ | |||
+ | Disable: ''echo 0 | sudo tee /proc/sys/kernel/randomize_va_space'' | ||
+ | |||
+ | Enable again: ''echo 2 | sudo tee /proc/sys/kernel/randomize_va_space'' | ||
</note> | </note> | ||
<code c> | <code c> | ||
Line 776: | Line 780: | ||
All content necessary for the CNS laboratory tasks can be found in [[cns:resources:repo|the CNS public repository]]. | All content necessary for the CNS laboratory tasks can be found in [[cns:resources:repo|the CNS public repository]]. | ||
+ | |||
+ | Submit your flags to [[https://cns-lab-ctf21.cyberedu.ro/|the CNS CyberEDU Platform]]. | ||
===== 1. Position independent executables ==== | ===== 1. Position independent executables ==== | ||
Line 858: | Line 864: | ||
- How do we actually use the data from this .o file? What symbols are exported? | - How do we actually use the data from this .o file? What symbols are exported? | ||
* <code> | * <code> | ||
- | $ readelf -s ./mycode.bin.o | + | $ nm ./mycode.bin.o |
0000000000000035 D _binary___mycode_bin_end | 0000000000000035 D _binary___mycode_bin_end | ||
0000000000000035 A _binary___mycode_bin_size | 0000000000000035 A _binary___mycode_bin_size | ||
Line 877: | Line 883: | ||
- The stack is still executable, remove this flag! | - The stack is still executable, remove this flag! | ||
* ''execstack -c ./my'' | * ''execstack -c ./my'' | ||
+ | |||
+ | <note> | ||
+ | If you're missing the ''execstack'' binary on the Kali VM (or on any Debian-based distribution), manually download and install it: | ||
+ | |||
+ | <code> | ||
+ | # curl -LO http://ftp.de.debian.org/debian/pool/main/p/prelink/execstack_0.0.20131005-1+b10_amd64.deb | ||
+ | # dpkg -i execstack_0.0.20131005-1+b10_amd64.deb | ||
+ | </code> | ||
+ | |||
+ | If installation freezes, cancel it then try again. | ||
+ | |||
+ | </note> | ||
+ | |||
- Why does ''execstack -c ./*.o'' throw an error? | - Why does ''execstack -c ./*.o'' throw an error? | ||
* ''execstack'' has to have information about the segments, information which is only available after the linking process | * ''execstack'' has to have information about the segments, information which is only available after the linking process | ||
- Even if the stack is not executable, you should be able to run the shellcode, the data section is executable, please check it! | - Even if the stack is not executable, you should be able to run the shellcode, the data section is executable, please check it! | ||
* ''readelf -e my | grep .data'', check for segment 03 (which maps the ''.data'' section) | * ''readelf -e my | grep .data'', check for segment 03 (which maps the ''.data'' section) | ||
- | </note> | ||
==== 3. stripped ==== | ==== 3. stripped ==== | ||
Line 902: | Line 920: | ||
* What other control-flow altering instructions are executed besides ''call'' and ''ret''? | * What other control-flow altering instructions are executed besides ''call'' and ''ret''? | ||
- | <note tip>Normally we use tools such as IDA or Radare2 to reverse engineer binaries. In this case however, we challenge you to use only your brain, a pen and a piece of paper. It's a bit tedious, but the end result should be fun.</note> | + | <note tip>Normally we use tools such as IDA, Ghidra or Radare2 to reverse engineer binaries. In this case however, we challenge you to use only your brain, a pen and a piece of paper. It's a bit tedious, but the end result should be fun.</note> |
<note important>You can dump data from within ''objdump'' using the ''-s'' flag. Use this to figure out what pointers to contents from ''.data'' are put into registers.</note> | <note important>You can dump data from within ''objdump'' using the ''-s'' flag. Use this to figure out what pointers to contents from ''.data'' are put into registers.</note> | ||
Line 911: | Line 929: | ||
$ readelf -h stripped | $ readelf -h stripped | ||
... | ... | ||
- | Entry point address: 0x40010d | + | Entry point address: 0x40105d |
... | ... | ||
</code> | </code> | ||
- | Dumping the code, we can see that ''stripped'' calls a bunch of functions starting with ''0x40010d'': | + | Dumping the code, we can see that ''stripped'' calls a bunch of functions starting with ''0x40105d'': |
<code text> | <code text> | ||
$ objdump -D stripped -M intel | $ objdump -D stripped -M intel | ||
... | ... | ||
- | 40010d: ba 0e 00 00 00 mov edx,0xe | + | 40105d: ba 0e 00 00 00 mov edx,0xe |
- | 400112: 48 be 58 01 60 00 00 movabs rsi,0x600158 | + | 401062: 48 be 00 20 40 00 00 movabs rsi,0x402000 |
- | 400119: 00 00 00 | + | 401069: 00 00 00 |
- | 40011c: e8 1a 00 00 00 call 0x40013b | + | 40106c: e8 19 00 00 00 call 0x40108a |
- | 400121: e8 d2 ff ff ff call 0x4000f8 | + | 401071: e8 d2 ff ff ff call 0x401048 |
- | 400126: b9 05 00 00 00 mov ecx,0x5 | + | 401076: b9 05 00 00 00 mov ecx,0x5 |
- | 40012b: e8 96 ff ff ff call 0x4000c6 | + | 40107b: e8 96 ff ff ff call 0x401016 |
- | 400130: e8 7c ff ff ff call 0x4000b1 | + | 401080: e8 7c ff ff ff call 0x401001 |
- | 400135: e8 0e 00 00 00 call 0x400148 | + | 401085: e8 0d 00 00 00 call 0x401097 |
- | 40013a: c3 ret | + | 40108a: b8 01 00 00 00 mov eax,0x1 |
- | 40013b: b8 01 00 00 00 mov eax,0x1 | + | 40108f: bf 01 00 00 00 mov edi,0x1 |
- | 400140: bf 01 00 00 00 mov edi,0x1 | + | 401094: 0f 05 syscall |
- | 400145: 0f 05 syscall | + | 401096: c3 ret |
- | 400147: c3 ret | + | |
... | ... | ||
</code> | </code> | ||
Line 941: | Line 958: | ||
Let's note the functions that are called starting from the entry point: | Let's note the functions that are called starting from the entry point: | ||
- | * f1: ''0x40013b'', with ''edx = 0xe'' and ''rsi = 0x600158'' (we may assume these are passed as arguments) | + | * f1: ''0x40108a'', with ''edx = 0xe'' and ''rsi = 0x600158'' (we may assume these are passed as arguments) |
- | * f2: ''0x4000f8'', with no register modifications | + | * f2: ''0x401048'', with no register modifications |
- | * f3: ''0x4000c6'', with ''ecx = 0x5'' (btw, did you notice how "looping," is printed 5 times?) | + | * f3: ''0x401016'', with ''ecx = 0x5'' (btw, did you notice how "looping," is printed 5 times?) |
* and so on. | * and so on. | ||
Line 949: | Line 966: | ||
<code text> | <code text> | ||
- | 40013b: b8 01 00 00 00 mov eax,0x1 | + | 40108a: b8 01 00 00 00 mov eax,0x1 |
- | 400140: bf 01 00 00 00 mov edi,0x1 | + | 40108f: bf 01 00 00 00 mov edi,0x1 |
- | 400145: 0f 05 syscall | + | 401094: 0f 05 syscall |
+ | 401096: c3 ret | ||
</code> | </code> | ||
Line 959: | Line 977: | ||
- | <note>This also means that we can look to see whether ''0x400148'', the final ''call'' from the main function, is code that calls the ''exit'' syscall. Notice that there are no standard C library functions in the executable, so it must manually call ''exit''.</note> | + | <note>This also means that we can look to see whether ''0x401097'', the final ''call'' from the main function, is code that calls the ''exit'' syscall. Notice that there are no standard C library functions in the executable, so it must manually call ''exit''.</note> |
- | Let's also look at the first 14 (''0xe'') bytes starting with ''0x600158'', the value in ''rsi'': | + | Let's also look at the first 14 (''0xe'') bytes starting with ''0x402000'', the value in ''rsi'': |
<code text> | <code text> | ||
Line 967: | Line 985: | ||
... | ... | ||
Contents of section .data: | Contents of section .data: | ||
- | 600158 48656c6c 6f2c2074 68657265 210a4920 Hello, there!.I | + | 402000 48656c6c 6f2c2074 68657265 210a4920 Hello, there!.I |
- | 600168 616d206c 6f6f7069 6e672c20 0a416c6c am looping, .All | + | 402010 616d206c 6f6f7069 6e672c20 0a416c6c am looping, .All |
- | 600178 20646f6e 65210a done!. | + | 402020 20646f6e 65210a done!. |
</code> | </code> | ||
Line 980: | Line 998: | ||
<code text> | <code text> | ||
strings -t x stripped | strings -t x stripped | ||
- | 158 Hello, there! | + | 2000 Hello, there! |
- | 166 I am looping, | + | 200e I am looping, |
- | 175 All done! | + | 201d All done! |
- | 44c .shstrtab | + | 2028 .shstrtab |
- | 456 .text | + | 2032 .text |
- | 45c .data | + | 2038 .data |
</code> | </code> | ||
- | The string ''%%All done!%%'' is at offset ''0x175'' in the binary, that is equivalent to ''0x600175'' in the loaded program. | + | The string ''%%All done!%%'' is at offset ''0x201d'' in the binary, that is equivalent to ''0x40201d'' in the loaded program. |
<code text> | <code text> | ||
- | $ objdump -D stripped -M intel | grep -A 2 -B 2 0x600175 | + | $ objdump -D stripped -M intel | grep -A 2 -B 1 0x40201d |
- | + | 401001: ba 0a 00 00 00 mov edx,0xa | |
- | 00000000004000b1 <h>: | + | 401006: 48 be 1d 20 40 00 00 movabs rsi,0x40201d |
- | 4000b1: ba 0a 00 00 00 mov edx,0xa | + | 40100d: 00 00 00 |
- | 4000b6: 48 be 75 01 60 00 00 movabs rsi,0x600175 | + | 401010: e8 75 00 00 00 call 0x40108a |
- | 4000bd: 00 00 00 | + | |
- | 4000c0: e8 76 00 00 00 call 40013b <puts> | + | |
</code> | </code> | ||
- | This means that the function that does the print (''0x4000b1'') is never reached! Why? The reason is that the program exits before doing that. | + | This means that the function that does the print (''0x400001'') is never reached! Why? The reason is that the program exits before doing that. |
Find the call to the exit function that occurs at run-time exactly before this print and manually replace it with NOP instructions using the hex editor of your choice. At the end the program should display the following: | Find the call to the exit function that occurs at run-time exactly before this print and manually replace it with NOP instructions using the hex editor of your choice. At the end the program should display the following: | ||
Line 1017: | Line 1032: | ||
==== 5. Memory Dump Analysis ==== | ==== 5. Memory Dump Analysis ==== | ||
- | Using your newfound voodoo skills you are now able to tackle the following task. In the middle of two programs I added the following lines: | + | Let's consider the way programs run. |
+ | Consider the length of addresses for a given system and note that: | ||
+ | * there is a 3GB / 1GB user-mode / kernel-mode split for an i386 system | ||
+ | * that split is not the case for a 32bit program running on 64bits, it uses the entire 4GB of required virtual page | ||
+ | |||
+ | In the middle of two programs I added the following lines: | ||
<code c> | <code c> | ||
Line 1085: | Line 1105: | ||
* Which of the values point to the library/mmap zone? | * Which of the values point to the library/mmap zone? | ||
- | ==== 6. Smash the Stack ==== | + | ==== 6. IO Netgarage ==== |
- | * Download level01 from Smash the stack and solve it using peda. Break on ''*main'', step through the execution and figure out what it does and how to crack it. | + | |
+ | Download `level01` from [[https://io.netgarage.org/|IO Netgarage]] and solve it using GDB / PEDA. Break on ''*main'', step through the execution and figure out what it does and how to crack it. | ||
+ | |||
+ | Use the command below to copy the ''level01'' executable locally. Use the ''.'' (dot) mark at the end of the command to refer to the current directory. Provide ''level1'' as the password. | ||
<code> | <code> | ||
- | $ scp level1@io.netgarage.org:/levels/level01 . # Password is level1 | + | $ scp level1@io.netgarage.org:/levels/level01 . |
</code> | </code> | ||
==== 7. GDB ==== | ==== 7. GDB ==== | ||
- | * Use GDB and PEDA to run the code provided at {{cns:labs:s5_pp_bash.tar.gz|}}. The executable gets input from the user and evaluates it against a static condition. If it succeeds it then calls a ''password_accepted'' function that prints out a success message and spawns a shell. | + | |
+ | Use GDB and PEDA to run the code provided from ''07-bash-login/''. The executable gets input from the user and evaluates it against a static condition. If it succeeds it then calls a ''password_accepted'' function that prints out a success message and spawns a shell. Try to not use a decompiler. | ||
Your task is to use GDB and PEDA to force the executable to call the ''password_accepted'' function. | Your task is to use GDB and PEDA to force the executable to call the ''password_accepted'' function. | ||
Line 1100: | Line 1124: | ||
Think of modifying registers for forcing the executable to call the function (there is more than one way of doing this). | Think of modifying registers for forcing the executable to call the function (there is more than one way of doing this). | ||
+ | |||
+ | Hints: | ||
+ | * https://stackoverflow.com/questions/41183935/why-does-gcc-use-multiplication-by-a-strange-number-in-implementing-integer-divi | ||
+ | * https://ridiculousfish.com/blog/posts/labor-of-division-episode-i.html | ||
</note> | </note> | ||
==== 8. Extra: FixME ==== | ==== 8. Extra: FixME ==== | ||
- | The ''change-header'' directory contains a file named ''main.bad''. | + | The ''08-change-header'' directory contains a file named ''main.bad''. |
* What is the type of ''main.bad'' as reported by ''file'' command? | * What is the type of ''main.bad'' as reported by ''file'' command? | ||
- | * Using the skeleton from ''unscramble.py'' please fix the elf header! | + | * Using the skeleton from ''unscramble.py'' please fix the elf header! You can put your solution in ''solution.py'' or directly in ''unscramble.py''. |
* The first 6 bytes were modified from the elf header. | * The first 6 bytes were modified from the elf header. | ||
* What fields correspond to the first bytes? | * What fields correspond to the first bytes? | ||
Line 1119: | Line 1147: | ||
* Modify the binary entry point such that it will call this symbol! | * Modify the binary entry point such that it will call this symbol! | ||
* The output of this exercise should be three binaries: ''main.ok.main'', ''main.ok.call_me'', ''main.ok.real_main''. ''readelf -h main.ok*'' should not complain. | * The output of this exercise should be three binaries: ''main.ok.main'', ''main.ok.call_me'', ''main.ok.real_main''. ''readelf -h main.ok*'' should not complain. | ||
+ | |||
+ | <note tip> You can find an [[http://i.imgur.com/m6kL4Lv.png | i386 ELF structure]] diagram here. </note> | ||
===== Resources ===== | ===== Resources ===== | ||
Line 1138: | Line 1168: | ||
* [[http://www.muppetlabs.com/~breadbox/software/tiny/teensy.html | Smallest elf file]] | * [[http://www.muppetlabs.com/~breadbox/software/tiny/teensy.html | Smallest elf file]] | ||
* [[https://code.google.com/p/corkami/wiki/ELF101 | Elf Header exploded view]], [[http://i.imgur.com/i6wlE5h.png | direct link (ARM)]], [[http://i.imgur.com/m6kL4Lv.png | direct link i386]] | * [[https://code.google.com/p/corkami/wiki/ELF101 | Elf Header exploded view]], [[http://i.imgur.com/i6wlE5h.png | direct link (ARM)]], [[http://i.imgur.com/m6kL4Lv.png | direct link i386]] | ||
- | * | ||