{"id":194,"date":"2017-11-14T18:40:42","date_gmt":"2017-11-14T18:40:42","guid":{"rendered":"http:\/\/arielkoren.com\/blog\/?p=194"},"modified":"2020-12-27T00:52:47","modified_gmt":"2020-12-27T00:52:47","slug":"fusion-level-06-solution","status":"publish","type":"post","link":"https:\/\/arielkoren.com\/blog\/2017\/11\/14\/fusion-level-06-solution\/","title":{"rendered":"Fusion &#8211; Level 06 solution"},"content":{"rendered":"<p>Following my previous blog post (<a href=\"http:\/\/arielkoren.com\/blog\/2017\/06\/14\/fusion-level05-solution\/\">Fusion level 05 solution<\/a>), I continued my nightly quest for fun and solved the next challenge as well. As I try to keep my content unique and original, this blog post is mostly created due to the fact that as for today, there was no solution for this challenge on the internet.<br \/>\nThis time we will examine the danger of unsafe shared data structures between multiple threads, as well as function arguments type mismatch causing an integer overflow leading to stack overrun exploit. In this blog post i will cover the concepts of controllable threads race-conditions, stack overflowing while making sure the flow of the program remains safe to the end of the function, where the return address is overwritten.<br \/>\nSo let&#8217;s get to it.<\/p>\n<p><!--more--><\/p>\n<h1>The Problem<\/h1>\n<p>The code in this exercise Which can be found here:<br \/>\n<a href=\"https:\/\/exploit-exercises.com\/fusion\/level06\/\">https:\/\/exploit-exercises.com\/fusion\/level06\/&nbsp;<\/a><br \/>\nhas several compiled protections mechanisms and we expect the vulnerability type to be stack based.<\/p>\n<div id=\"attachment_195\" style=\"width: 520px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-195\" class=\"size-full wp-image-195\" src=\"https:\/\/i0.wp.com\/arielkoren.com\/blog\/wp-content\/uploads\/2017\/11\/01_protection.jpg?resize=510%2C345\" alt=\"Compiled protection\" width=\"510\" height=\"345\" srcset=\"https:\/\/i0.wp.com\/arielkoren.com\/blog\/wp-content\/uploads\/2017\/11\/01_protection.jpg?w=510&amp;ssl=1 510w, https:\/\/i0.wp.com\/arielkoren.com\/blog\/wp-content\/uploads\/2017\/11\/01_protection.jpg?resize=300%2C203&amp;ssl=1 300w\" sizes=\"auto, (max-width: 510px) 100vw, 510px\" data-recalc-dims=\"1\" \/><p id=\"caption-attachment-195\" class=\"wp-caption-text\">Compiled protection<\/p><\/div>\n<p>As this level is protected with ASLR, and Non-Executable Stack &amp; Heap, to properly exploit the server we will have to find some primitives (Basic abilities) to bypass these protections:<\/p>\n<ul>\n<li>(Arbitrary) Memory read \u2013 Mostly in order to bypass ASLR, an information leak must be at hand, reading some address can give us a clue of where exactly some modules are located at. Once we know a module&#8217;s absolute address, we can find functions relative to that address if we can determine for which module it belongs to. As arbitrary read is usually preferred, sometimes (spoiler) we just have to deal with what we have and every scenario is unique.<\/li>\n<li>Memory write \u2013 Either for writing a shellcode, or for a string command to execute, writing to a memory and knowing the address of that memory.<\/li>\n<li>Execution \u2013 Changing a previously allocated page permissions which has a shellcode or ROPing to a differen with-already-execute-permissions location (such as different functions).<\/li>\n<\/ul>\n<h1>Intro<\/h1>\n<p>The code begins with a simple SSL server listening for connection on port 20006. For every new connection established, a new thread function is created:&nbsp;<code>keyval_thread()<\/code>, which receives the session as argument and will handle the rest of the thread&#8217;s communication from here on forth. The python library I used to establish the ssl connections is &#8220;python-gnutls 3.1.1&#8221; which you can get here:<br \/>\n<a href=\"https:\/\/pypi.python.org\/pypi\/python-gnutls\/\">https:\/\/pypi.python.org\/pypi\/python-gnutls\/<\/a><\/p>\n<p>The next obvious thing to do, is understand what this new threaded function <code>keyval_thread()<\/code> is doing with the session. So first it seems like it verifies the <code>gnutls_handshake()<\/code> worked as expected, then sending us a welcome message explaining we can send <code>'h'<\/code>&nbsp;on the socket to receive help. After this happens the real logic begins: the server receives data on the socket, splits it with a delimiter of space and puts each part of the data in the <code>args[6]<\/code> variable. Further in the code the first letter of the first argument is checked against a predefined exposed server functionalities nested in a switch statement.<\/p>\n<p>So what this server does exactly? Mainly using libHX for some sort of `dictionary` based structure for insertion of a key and a data type defined as:<\/p>\n<pre class=\"toolbar:2 show-lang:2 show-plain:3 lang:c decode:true\">struct data {\n    void *data; \n    size_t length; \n};<\/pre>\n<p>The documentation for the library can be found here: <a href=\"http:\/\/libhx.sourceforge.net\/libHX_Documentation.pdf\"><br \/>\nhttp:\/\/libhx.sourceforge.net\/libHX_Documentation.pdf<br \/>\n<\/a>We can either delete an existing node by its key, set a new key:val node, update an existing node&#8217;s data, check if an existing key exists, get an existing node value, clean up the dictionary structure and finally exit the program using <code>'d'<\/code>, <code>'s'<\/code>, <code>'u'<\/code>, <code>'f'<\/code>, <code>'g'<\/code>, <code>'X'<\/code>&nbsp;and <code>'e'<\/code> respectively.<\/p>\n<h3>Focus on what&#8217;s important<\/h3>\n<p>One thing that really caught my eyes was the global variable <code>HXmap *dict<\/code>,&nbsp;which can be used between all functions with no actual locking mechanism. Since we can connect to the web server from multiple sessions and a new thread for each session, every thread can access that structure and manipulate its data simultaneously. Two different threads changing the same data type in a not atomic way, can (and will) cause disastrous results. Let&#8217;s see which functions use this global variable: <code>update_data()<\/code>&nbsp; used by&nbsp;<code>'u'<\/code> command, <code>new_dict()<\/code> used by&nbsp;<code>'X'<\/code> command, <code>HXmap_del()<\/code> used by&nbsp;<code>'d'<\/code> command, <code>gather_data()<\/code> used by&nbsp;<code>'s'<\/code> command, <code>HXmap_find()<\/code> used by&nbsp;<code>'f'<\/code> command and finally <code>HXmap_get()<\/code> used by&nbsp;<code>'g'<\/code> command.<\/p>\n<p><code>HXmap_find()<\/code> &#8211; gives us very little value. It basically sends back whether a key was found on the dictionary structure or not with no data modifications at all.<br \/>\n<code>new_dict()<\/code> &#8211; Good for a clean start. Deletes the data structure and re initializing it, but nothing else.<br \/>\n<code>HXmap_del()<\/code> &#8211; Deletes a specific key and its value from the dictionary structure.<br \/>\n<code>gather_data()<\/code> &#8211; Followed by <code>HXmap_add()<\/code>, is in charge of creating a new key:value in the global structure.<br \/>\n<code>update_data()<\/code> &#8211; Alter&#8217;s an existing key, creating a new value for it<br \/>\nFor this exploit purposes I will only focus on the commands: get, update and set.<\/p>\n<h5>Set New Data<\/h5>\n<p>Here is a pseudo python code to use this function<\/p>\n<pre class=\"toolbar:2 show-lang:2 show-plain:3 lang:python decode:true\" title=\"Set New Data\">socket = ssl_connect()\nkey = \"test\"\ndata = \"A\" * 100\n\nsocket.send(\"s %s %s\" % (key, len(data)))\nsocket.send(data)<\/pre>\n<p>The first buffer is parsed by the main thread function <code>keyval_thread()<\/code> using <code>HX_split5()<\/code>, then a call to <code>gather_data()<\/code> is made, sending the <code>data_length<\/code> as a parameter. Receiving the rest of the data from the socket, allocating memory for the buffer and the data structure as well, eventually returning the data. An interesting fact about this function is that it allocated the same buffer twice (<code>malloc()<\/code>, <code>HX_memdup()<\/code>) and it never really even checked if the <code>key<\/code> exists already. This is just a fun-memoryleak-possiblyspray-fact, lets continue. Finally the key:data are added to the dictionary using <code>HXmap_add()<\/code><\/p>\n<h5>Get Key Value<\/h5>\n<p>To receive data, we just need to send a simple buffer on the socket <code>g &lt;key&gt;<\/code>, then it triggers the function <code>HXmap_get()<\/code> which will return on the receiving the node&#8217;s data as defined above.&nbsp;The length of the data returned depends on the variable&nbsp;<code>length<\/code> in the structure.<\/p>\n<h5>Update Key Value<\/h5>\n<p>Similar to the <code>set<\/code> function in terms of what should be sent to the server.<\/p>\n<p>The rest of the content here is quite important for the rest of the exploit, so read and understand carefully.<br \/>\nThe <code>update_data()<\/code> function is looking for an existing node using <code>HXmap_get()<\/code>, and exit function if failed finding a matching node.<br \/>\nproceeds to check if the new data length is longer than the current length.<br \/>\nif longer, proceed with&nbsp;<code>realloc()<\/code> to find a new memory location matching the new length.<br \/>\nReceive new data on socket. if fails, exit function.<br \/>\nFinally, update the node&#8217;s <code>length<\/code> variable.<\/p>\n<h3>The Info Leak<\/h3>\n<p>the first part of the full exploit begins with a shwifty bug happening when two threads try to update the same data structure simultaneously. I will now explain exactly how it is done.<\/p>\n<p>We create a new node on the memory using the&nbsp;<code>'s'<\/code> command. When the new data is stored, i want it to be as small as possible, smaller than 16 bytes. that is because the heap is devided into several different parts, each for different sizes of data such as for <code>malloc(16)<\/code>, <code>malloc(32)<\/code> and a few more. I am creating a small data buffer because i want to ensure that later when a&nbsp;<code>realloc()<\/code> will occur, i will arrive into a new different heap location where surely the address will change, rather than stay on the same spot on the heap, later you will see the reason why.<\/p>\n<pre class=\"toolbar:2 show-lang:2 show-plain:3 lang:python decode:true\" title=\"set new data\"># Connect \ns = ssl_connect()\n\n# Add new key:data node\ns.send(\"s test 1\")\ns.send(\"A\")<\/pre>\n<p>After we have a new data in the memory. Its time to manipulate it simultaneously with two threads and weird <span style=\"color: #ff0000;\">m<\/span><span style=\"color: #ff00ff;\">a<span style=\"color: #3366ff;\">g<\/span><\/span><span style=\"color: #33cccc;\">i<\/span><span style=\"color: #00ff00;\">c<\/span> things will happen. Watch closely on the&nbsp;<code>update_data()<\/code> function. Here is a truncated version of it, where i left only the interesting parts<\/p>\n<pre class=\"lang:default mark:10,11,1317,25 decode:true \" title=\"update_data() function, interesting parts are highlighted\">int update_data(gnutls_session_t session, char *key, size_t length)\n{\n\tstruct data *data;\n\tsize_t offset;\n\tint ret;\n\n\tdata = HXmap_get(dict, key);\n\t...\n\n\tif(length &gt; data-&gt;length) {\n\t\t\ttmp = realloc(data-&gt;data, length);\n\t\t\t...\n\t\t\tdata-&gt;data = tmp;\n\t}\t\t\n\n\tfor(offset = 0; offset &lt; length; ) {\n\t\t\tret = gnutls_record_recv(session, data-&gt;data + offset,\n\t\t\t\t\t(length - offset) &gt; 65535 ? 65535 : (length - offset));\n\t\t\tif(ret &lt;= 0) return 0;\n\t\t\toffset += ret;\n\t}\n\n\t...\n\n\tdata-&gt;length = length;\n\treturn 0;\n}<\/pre>\n<p>Lets say i have an allocated node with the values (Imagine the pseudo code used <code>malloc()<\/code>)<\/p>\n<pre class=\"toolbar:2 show-lang:2 show-plain:3 lang:c decode:true\">data node = {0};\nnode.data = \"A\";\nnode.length = 1;<\/pre>\n<p>and now i want to update the data with a new larger in size data. for example <code>0x500<\/code>&nbsp;times the letter <code>\"B\"<\/code>. the&nbsp;<code>update_data()<\/code> function already knows i&#8217;m going to send it soon&nbsp;<code>0x500<\/code>&nbsp;bytes, as <code>size_t length<\/code> is one of the function&#8217;s parameters. But i didn&#8217;t send them just yet. so the function will&nbsp;<code>realloc()<\/code>&nbsp;the <code>data-&gt;data<\/code> into a new heap region (line 11) with the required size and before it will proceed with changing the&nbsp;<code>data-&gt;length<\/code>, a blocking function is called:&nbsp;<code>gnutls_record_recv()<\/code>&nbsp;(line 17), waiting now to receive the amount of data specified by the&nbsp;<code>length<\/code> parameter (<code>0x500<\/code>). I will send <code>0x4FF<\/code> bytes to keep the function blocking and wait for the last byte.<\/p>\n<p>So the context so far for everything:<\/p>\n<pre class=\"toolbar:2 show-lang:2 show-plain:3 lang:c decode:true\" title=\"current status\">\/* original *\/\ndata.length = 1;\ndata.data = \"BBBB...B\" (0x4FF) \/* (PVOID) Of size 0x500 *\/\n\n\/* The thread is now stuck on gnutls_record_recv() \nuntill i will send it all the data it expects - 0x500 *\/<\/pre>\n<p>Now i will connect again and update the same node with new values while the previous thread remains on a blocked state. The idea is to send a new smaller in size data (still bigger than the original) for example <code>0x100<\/code>. the node <code>data-&gt;data<\/code> will point to a heap memory region of only&nbsp;<code>0x100<\/code>&nbsp;in size, then i will continue and send <code>0x100<\/code>&nbsp;bytes of the letter&nbsp;<code>\"C\"<\/code> to complete the function, resulting in change of the original&nbsp;<code>data-&gt;length<\/code>&nbsp;parameter to&nbsp;<code>0x100<\/code>&nbsp;while the&nbsp;<code>data-&gt;data<\/code>&nbsp;points to a heap region of&nbsp;<code>0x100<\/code>&nbsp;bytes as well. Finally i finish the execution of the first thread by sending the last byte, resulting in the original data to look like that:<\/p>\n<pre class=\"toolbar:2 show-lang:2 show-plain:3 lang:default decode:true\">\/* original *\/\ndata.length = 0x500\ndata.data = \"BBB...C\" (0x100) \/* Memory region of 0x100 *\/<\/pre>\n<p>Now we have a data structure where two different threads wrote to it simultaneously, thus we could change the length of the data type to have a much larger value than the data size it self.<\/p>\n<p>Finally, we can use the <code>'g' - HXmap_get()<\/code> function to read&nbsp;<code>0x500<\/code> bytes from a&nbsp;<code>0x100<\/code> bytes region, resulting the desired memory leak.<br \/>\nAfter i played for a bit with this multi threaded memory leak concept, i noticed i could find an address of <code>libpthread-2.13.so<\/code> quite reliably based on a few simple rules, thus also finding the address of&nbsp;<code>system()<\/code>, as well as a pointer to the memory which i just allocated. Basically i have everything i need to run an exploit, the address of&nbsp;<code>system()<\/code> and the address of the currently allocated buffer. All i am missing now is a stack overflow to change the flow of the program.<\/p>\n<h3>The Stack overflow<\/h3>\n<p>Finding the stack vulnerability was actually a lot of fun. The problem occurs due to type misuse of variable causing an integer overflow allowing me to overwrite the stack. This time, the vulnerability is with the&nbsp;<code>gather_data()<\/code>&nbsp;function.<\/p>\n<p>We will have to dive a bit deeper into the code to understand exactly what is going on in this scenario. It all begins with the very first types of data that we send on the protocol:&nbsp;<code>s &lt;key&gt; &lt;key_length&gt;<\/code>. where&nbsp;<code>key<\/code> is&nbsp;<code>args[1]<\/code> and&nbsp;<code>key_length<\/code> is&nbsp;<code>args[2]<\/code>.<\/p>\n<pre class=\"toolbar:2 show-lang:2 show-plain:3 lang:default decode:true\">case 's': \/\/ set\n    data = gather_data(session, args[1], atoi(args[2]));\n    if(data != NULL) {<\/pre>\n<p>a quick observation of the <code>atoi()<\/code> documentation:<\/p>\n<blockquote><p>The function first discards as many whitespace characters (as in&nbsp;<samp>isspace<\/samp>) as necessary until the first non-whitespace character is found. Then, starting from this character, <span style=\"text-decoration: underline;\">takes an optional initial&nbsp;plus&nbsp;or&nbsp;minus&nbsp;sign<\/span> followed by as many base-10 digits as possible, and interprets them as a numerical value.<\/p><\/blockquote>\n<p><code>atoi()<\/code> is sign sensitive, so in order to send a really big number, such as <code>0xFFFFFF<\/code>, i will have to send to the <code>key_length<\/code>, the value <code>\"-1\"<\/code>.&nbsp;<code>gather_data()<\/code> function receives the length parameter as type <code>size_t<\/code> which is unsigned &#8211; not minus one, but a really big unsigned number instead &#8211; <code>4294967295<\/code>.&nbsp; Lets have a look at the prologue of the function.<\/p>\n<pre class=\"toolbar:2 show-lang:2 show-plain:3 lang:default mark:3-5 decode:true\" title=\"Function prologue \">struct data *gather_data(gnutls_session_t session, char *key, size_t length)\n{\n    unsigned char buffer[length];\n    int offset, ret;\n    struct data *data;\n    ...\n    return data;\n}<\/pre>\n<p>we see the local stack parameters are being allocated dynamically depends on the value of length (<code>unsigned char buffer[<strong>length<\/strong>]<\/code>). Here is how it happens on the assembly:<\/p>\n<div id=\"attachment_208\" style=\"width: 1055px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-208\" class=\"size-full wp-image-208\" src=\"https:\/\/i0.wp.com\/arielkoren.com\/blog\/wp-content\/uploads\/2017\/11\/02_gather_data-1.jpg?resize=680%2C405\" alt=\"\" width=\"680\" height=\"405\" srcset=\"https:\/\/i0.wp.com\/arielkoren.com\/blog\/wp-content\/uploads\/2017\/11\/02_gather_data-1.jpg?w=1045&amp;ssl=1 1045w, https:\/\/i0.wp.com\/arielkoren.com\/blog\/wp-content\/uploads\/2017\/11\/02_gather_data-1.jpg?resize=300%2C179&amp;ssl=1 300w, https:\/\/i0.wp.com\/arielkoren.com\/blog\/wp-content\/uploads\/2017\/11\/02_gather_data-1.jpg?resize=768%2C458&amp;ssl=1 768w, https:\/\/i0.wp.com\/arielkoren.com\/blog\/wp-content\/uploads\/2017\/11\/02_gather_data-1.jpg?resize=1024%2C610&amp;ssl=1 1024w\" sizes=\"auto, (max-width: 680px) 100vw, 680px\" data-recalc-dims=\"1\" \/><p id=\"caption-attachment-208\" class=\"wp-caption-text\">Prologue<\/p><\/div>\n<p><code>0x00001F99<\/code> &#8211; put the value of&nbsp;<code>size_t length<\/code> in the register&nbsp;<code>EDI<\/code>.<br \/>\n<code>0x00001FAD<\/code> &#8211; Substract&nbsp;<code>ESP<\/code> with the length (This is how local variables are allocated on the stack)<\/p>\n<p>Lets focus on the Stack variables allocation which is allocated depending on&nbsp;<code>length<\/code>. Since registers can only hold up to 32 bits of data, the number&nbsp;<code>0xFFFFFFFF<\/code> is the largest unsigned number that a register can hold. If we add&nbsp;<code>0x00000001<\/code>&nbsp;to that value, a register cant hold&nbsp;<code>0x100000000<\/code>, so the actual value will become&nbsp;<code>0x00000000<\/code>!&nbsp; Basically on add \\ sub operations the value&nbsp;<code>0xFFFFFFFF<\/code> will mean very little although its actual value is huge. With that in mind, when the function allocate variables on the stack,&nbsp;<code>ESP<\/code> will experience an integer overflow causing it to remain almost the same value, which is not even close to the actual length the function thinks it allocated.<\/p>\n<p>Moving on to the data receiving function<\/p>\n<pre class=\"toolbar:2 show-lang:2 show-plain:3 lang:default decode:true\">  for(offset = 0; offset &lt; length; ) {\n      ret = gnutls_record_recv(session, buffer + offset, (length -\n          offset) &gt; 65535 ? 65535 : (length - offset));\n      if(ret &lt;= 0) return NULL;\n      offset += ret;\n  }<\/pre>\n<p>As the <code>length<\/code>&nbsp;parameter holds the value of&nbsp;<code>0xFFFFFFFF<\/code>, the&nbsp;<code>gnutls_record_recv()<\/code>&nbsp;function is going to receive data up to length 0f&nbsp;<code>65535<\/code>, and write it on the stack variable <code>buffer<\/code>.<br \/>\nGreat because since i sent&nbsp;<code>0xFFFFFFFF<\/code> as the&nbsp;<code>length<\/code> parameter, not nearly as much is allocated on the stack (The Integer overflow i explained earlier). This will now allow me to overwrite the stack. I dont even need to write&nbsp;<code>65535<\/code> bytes. if <code>gnutls_record_recv()<\/code> fails for some reason (hint hint) it will return an error code, causing the function&#8217;s flow to&nbsp;<code>return NULL;<\/code> which is exactly what i want &#8211; easy overflow.<\/p>\n<h5>The Mini Failure<\/h5>\n<p>Well as i first tested the vulnerability by spamming &#8220;A&#8221;s on the socket \\ stack and i received a different crash, from inside the&nbsp;<code>gnutls_record_recv()<\/code> function:<\/p>\n<div id=\"attachment_210\" style=\"width: 1256px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-210\" class=\"wp-image-210 size-full\" src=\"https:\/\/i0.wp.com\/arielkoren.com\/blog\/wp-content\/uploads\/2017\/11\/03_failure.jpeg?resize=680%2C99\" alt=\"\" width=\"680\" height=\"99\" srcset=\"https:\/\/i0.wp.com\/arielkoren.com\/blog\/wp-content\/uploads\/2017\/11\/03_failure.jpeg?w=1246&amp;ssl=1 1246w, https:\/\/i0.wp.com\/arielkoren.com\/blog\/wp-content\/uploads\/2017\/11\/03_failure.jpeg?resize=300%2C44&amp;ssl=1 300w, https:\/\/i0.wp.com\/arielkoren.com\/blog\/wp-content\/uploads\/2017\/11\/03_failure.jpeg?resize=768%2C112&amp;ssl=1 768w, https:\/\/i0.wp.com\/arielkoren.com\/blog\/wp-content\/uploads\/2017\/11\/03_failure.jpeg?resize=1024%2C150&amp;ssl=1 1024w, https:\/\/i0.wp.com\/arielkoren.com\/blog\/wp-content\/uploads\/2017\/11\/03_failure.jpeg?resize=1200%2C175&amp;ssl=1 1200w\" sizes=\"auto, (max-width: 680px) 100vw, 680px\" data-recalc-dims=\"1\" \/><p id=\"caption-attachment-210\" class=\"wp-caption-text\">Mini failure<\/p><\/div>\n<p>Notice line #2: it seems like my overflow was also overflowing local stack variables that were passed to <code>gnutls_record_recv()<\/code>, causing it to receive bad parameters and crashing unexpectedly.&nbsp; To overcome this issue, i overwrote these parameters with&nbsp;<code>\\x00<\/code>s, and hoped that like every good function it will have a sanity case to see if the parameters make sense \\ valid, and if they do not to return an error code.<br \/>\nGreat success.<\/p>\n<p>I managed to overflow the local variables with values that will cause the&nbsp;<code>gnutls_record_recv()<\/code> function to return immediately, while still overflowing the&nbsp;<code>RetAddress<\/code> with the&nbsp;<code>system()<\/code> function, adding an argument of a reverse shell, which i created earlier in the memory leak function. Running the exploit and waiting locally for the reverse shell:<\/p>\n<div id=\"attachment_212\" style=\"width: 944px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-212\" class=\"size-full wp-image-212\" src=\"https:\/\/i0.wp.com\/arielkoren.com\/blog\/wp-content\/uploads\/2017\/11\/04_reverse_shell.jpg?resize=680%2C381\" alt=\"\" width=\"680\" height=\"381\" srcset=\"https:\/\/i0.wp.com\/arielkoren.com\/blog\/wp-content\/uploads\/2017\/11\/04_reverse_shell.jpg?w=934&amp;ssl=1 934w, https:\/\/i0.wp.com\/arielkoren.com\/blog\/wp-content\/uploads\/2017\/11\/04_reverse_shell.jpg?resize=300%2C168&amp;ssl=1 300w, https:\/\/i0.wp.com\/arielkoren.com\/blog\/wp-content\/uploads\/2017\/11\/04_reverse_shell.jpg?resize=768%2C431&amp;ssl=1 768w\" sizes=\"auto, (max-width: 680px) 100vw, 680px\" data-recalc-dims=\"1\" \/><p id=\"caption-attachment-212\" class=\"wp-caption-text\">Exploit &amp; Reverse shell<\/p><\/div>\n<p>As a final note, although i solved this exercise in one way, i figured out there is possibly another way to solve it which is a bit harder. With the memory leak bug, i could possibly also cause a heap corruption, and then solve this exercise using a completely different vulnerability.<\/p>\n<p>This post is already so long i decided to omit some of the things happened in this level. To understand the solution further you are welcome to see the <strong>solution code on my <a href=\"https:\/\/github.com\/arielkoren\/exploit-exercises\">github<\/a><\/strong>.<\/p>\n<p>Hope you enjoyed reading this blog post, if you have any ideas or thoughts, feel free to share in the comments below.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Following my previous blog post (Fusion level 05 solution), I continued my nightly quest for fun and solved the next challenge as well. As I try to keep my content unique and original, this blog post is mostly created due to the fact that as for today, there was no solution for this challenge on&#8230; <\/p>\n<div class=\"read-more navbutton\"><a href=\"https:\/\/arielkoren.com\/blog\/2017\/11\/14\/fusion-level-06-solution\/\">Read More<i class=\"fa fa-angle-double-right\"><\/i><\/a><\/div>\n","protected":false},"author":2,"featured_media":325,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[20],"tags":[25,26,22,28,29,30,9],"class_list":["post-194","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-exploit","tag-buffer-overflow","tag-exploit-exercises","tag-fusion","tag-fusion-level-06","tag-integer-overflow","tag-race-condition","tag-reverse-engineering"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"https:\/\/i0.wp.com\/arielkoren.com\/blog\/wp-content\/uploads\/2017\/11\/Fusion06.jpg?fit=2022%2C1517&ssl=1","jetpack_shortlink":"https:\/\/wp.me\/p849zO-38","_links":{"self":[{"href":"https:\/\/arielkoren.com\/blog\/wp-json\/wp\/v2\/posts\/194","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/arielkoren.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/arielkoren.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/arielkoren.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/arielkoren.com\/blog\/wp-json\/wp\/v2\/comments?post=194"}],"version-history":[{"count":19,"href":"https:\/\/arielkoren.com\/blog\/wp-json\/wp\/v2\/posts\/194\/revisions"}],"predecessor-version":[{"id":326,"href":"https:\/\/arielkoren.com\/blog\/wp-json\/wp\/v2\/posts\/194\/revisions\/326"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/arielkoren.com\/blog\/wp-json\/wp\/v2\/media\/325"}],"wp:attachment":[{"href":"https:\/\/arielkoren.com\/blog\/wp-json\/wp\/v2\/media?parent=194"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/arielkoren.com\/blog\/wp-json\/wp\/v2\/categories?post=194"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/arielkoren.com\/blog\/wp-json\/wp\/v2\/tags?post=194"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}