{"id":71,"date":"2022-10-14T06:37:19","date_gmt":"2022-10-14T06:37:19","guid":{"rendered":"https:\/\/blogs.oregonstate.edu\/paul\/?p=71"},"modified":"2022-10-14T06:37:19","modified_gmt":"2022-10-14T06:37:19","slug":"writeup-pop-quiz","status":"publish","type":"post","link":"https:\/\/blogs.oregonstate.edu\/paul\/2022\/10\/14\/writeup-pop-quiz\/","title":{"rendered":"Writeup: pop quiz"},"content":{"rendered":"\n<p>POP QUIZ TIME! Can you solve these challenging questions?<\/p>\n\n\n\n<p class=\"has-text-align-center\"><strong>What number am I thinking of?<\/strong><\/p>\n\n\n\n<p id=\"r1\">If I were a human, it would be difficult to know what the answer to this question might be<sup><strong><a href=\"#f1\" data-type=\"internal\" data-id=\"#f1\">1<\/a><\/strong><\/sup>. Thankfully, I am a computer, and will bare my essential nature to anyone with a keyboard. How about you decompile me and figure out what I&#8217;m thinking? In fact, I&#8217;ll do it for you.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>bool question_1(void)\n\n{\n  long in_FS_OFFSET;\n  int local_18;\n  int local_14;\n  long local_10;\n  \n  local_10 = *(long *)(in_FS_OFFSET + 0x28);\n  local_14 = 0x2325;\n  printf(\"What number am I thinking of? \");\n  __isoc99_scanf(&amp;DAT_00100e27,&amp;local_18);\n  if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) {\n                    \/* WARNING: Subroutine does not return *\/\n    __stack_chk_fail();\n  }\n  return local_14 == local_18;\n}<\/code><\/pre>\n\n\n\n<p>First, I check if <code>local_14<\/code> (my secret number) is equal to <code>local_18<\/code> (your input). <code>local_14<\/code> is assigned a value of <code>0x2325<\/code> (in my language). Converting to meat numbers gives us 8997, which is hopefully the number you were thinking of already. Regardless,<\/p>\n\n\n\n<p class=\"has-text-align-center\"><strong>gimme some characters<\/strong><\/p>\n\n\n\n<p>This isn&#8217;t even a question! It&#8217;s a command! And it&#8217;s so vague! Does it mean fictional characters? historical figures? This quiz sucks!<\/p>\n\n\n\n<p>These are all things you might be saying if this had been written by a human. Thankfully, you&#8217;re asking a computer, who is more than willing to bare its essential nature to anyone with a keyboard. Isn&#8217;t this easy?<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>bool question_2(void)\n\n{\n  long in_FS_OFFSET;\n  undefined4 local_14;\n  long local_10;\n  \n  local_10 = *(long *)(in_FS_OFFSET + 0x28);\n  printf(\"Gimme some characters: \");\n  local_14 = 0;\n  __isoc99_scanf(\"\\n%c%c%c%c\",&amp;local_14,(long)&amp;local_14 + 1,(long)&amp;local_14 + 2,(long)&amp;local_14 + 3)\n  ;\n  if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) {\n                    \/* WARNING: Subroutine does not return *\/\n    __stack_chk_fail();\n  }\n  return (int)local_14._3_1_ + (int)(char)local_14 + (int)local_14._1_1_ + (int)local_14._2_1_ ==\n         0x1a0;\n}<\/code><\/pre>\n\n\n\n<p>If you&#8217;re paying attention, you&#8217;ll notice that I don&#8217;t particularly care what the characters are. I just want them to add up to <code>0x1a0<\/code>. Which is 416 in meat numbers. It&#8217;s time for you to google &#8220;ASCII table&#8221; once again and click the top result which is really the worst result because it&#8217;s not ctrl-F&#8217;able.<sup><a href=\"#f5\">5<\/a><\/sup><\/p>\n\n\n\n<p>I also am only <code>scanf<\/code>ing 4 characters, so please be concise. &#8220;hhhh&#8221; works for me.<sup><a href=\"#f2\" data-type=\"internal\" data-id=\"#f2\"><strong>2<\/strong><\/a><\/sup><\/p>\n\n\n\n<p class=\"has-text-align-center\"><strong>???<\/strong><\/p>\n\n\n\n<p>Screw you, meatbag! You don&#8217;t even get a vague command anymore!<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void question_3(void)\n\n{\n  long in_FS_OFFSET;\n  undefined4 local_14; \/\/ int\/uint\n  long local_10;\n  \n  local_10 = *(long *)(in_FS_OFFSET + 0x28);\n  puts(\"???\");\n  local_14 = 0;\n  __isoc99_scanf(&amp;DAT_00100e27,&amp;local_14);\n  check(local_14); \/\/ Check runs on the integer\n  if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) {\n                    \/* WARNING: Subroutine does not return *\/\n    __stack_chk_fail();\n  }\n  return;\n}<\/code><\/pre>\n\n\n\n<p>Haha! This function doesn&#8217;t even return anything! That&#8217;ll throw you for a loop! What&#8217;s that, you didn&#8217;t even notice and have begun to reverse <code>check(local_14)<\/code>??<sup><a href=\"http:\/\/f3\">3<\/a><\/sup><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>undefined8 check(uint guess)\n\n{\n  int iVar1;\n  int WHAT;\n  size_t sVar2;\n  undefined8 WIN;\n  long lVar3;\n  undefined8 *inputPointer;\n  long in_FS_OFFSET;\n  int local_128;\n  int local_124;\n  undefined8 input;\n  long local_10;\n  \n  local_10 = *(long *)(in_FS_OFFSET + 0x28);\n  inputPointer = &amp;input;\n  for (lVar3 = 0x1f; lVar3 != 0; lVar3 = lVar3 + -1) {\n    *inputPointer = 0;\n    inputPointer = inputPointer + 1;\n  }\n  *(undefined4 *)inputPointer = 0;\n  *(undefined2 *)((long)inputPointer + 4) = 0;\n  *(undefined *)((long)inputPointer + 6) = 0;\n  sprintf((char *)&amp;input,\"%d\",(ulong)guess);\n  sVar2 = strnlen((char *)&amp;input,0xff);\n  WHAT = (int)sVar2;\n  if ((sVar2 &amp; 1) == 0) {\n    if (WHAT &lt; 4) {\n      WIN = 0;\n    }\n    else {\n      for (local_128 = 1; iVar1 = WHAT \/ 2, local_128 &lt; WHAT \/ 2; local_128 = local_128 + 1) {\n        if (*(char *)((long)&amp;input + (long)local_128) &lt;=\n            *(char *)((long)&amp;input + (long)(local_128 + -1))) {\n          WIN = 0;\n          goto function1;\n        }\n      }\n      do {\n        local_124 = iVar1 + 1;\n        if (WHAT &lt;= local_124) {\n          WIN = 1;\n          goto function1;\n        }\n        lVar3 = (long)iVar1;\n        iVar1 = local_124;\n      } while (*(char *)((long)&amp;input + (long)local_124) &lt; *(char *)((long)&amp;input + lVar3));\n      WIN = 0;\n    }\n  }\n  else {\n    WIN = 0;\n  }\nfunction1:\n  if (local_10 == *(long *)(in_FS_OFFSET + 0x28)) {\n    return WIN;\n  }\n                    \/* WARNING: Subroutine does not return *\/\n  __stack_chk_fail();\n}<\/code><\/pre>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:100%\">\n<p>Try reversing this, bucko! You don&#8217;t stand a chance! Wait, what&#8217;s that? You still had 8997 in your clipboard and entered that and got the flag? Wait, you even added some gibberish text to the end and it passed my function?<sup><a href=\"#4\" data-type=\"internal\" data-id=\"#4\">4<\/a><\/sup> That&#8217;s awesome \ud83d\ude42<\/p>\n\n\n\n<p>Hacking is all about playing by the rules however, so let&#8217;s build some character and actually look at what this does (pardon the partial variable renames):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>undefined8 check(uint guess)\n\n{\n  int iVar1;\n  int WHAT;\n  size_t sVar2;\n  undefined8 WIN;\n  long lVar3;\n  undefined8 *inputPointer;\n  long in_FS_OFFSET;\n  int local_128;\n  int local_124;\n  undefined8 input;\n  long local_10;\n  \n\n  local_10 = *(long *)(in_FS_OFFSET + 0x28);\n  \/\/ Honestly the next lines are so ugly. They look like they're zeroing out\n  \/\/ input via inputPointer, so we'll go with that\n  inputPointer = &amp;input;\n  for (lVar3 = 0x1f; lVar3 != 0; lVar3 = lVar3 + -1) {\n    *inputPointer = 0; \/\/ null bytes\n    inputPointer = inputPointer + 1;\n  }\n  *(undefined4 *)inputPointer = 0;\n  *(undefined2 *)((long)inputPointer + 4) = 0;\n  *(undefined *)((long)inputPointer + 6) = 0;\n  sprintf((char *)&amp;input,\"%d\",(ulong)guess); \/\/ Scan guess into input\n  sVar2 = strnlen((char *)&amp;input,0xff); \/\/ These lines put the length\n  WHAT = (int)sVar2;                    \/\/ of input into WHAT\n  if ((sVar2 &amp; 1) == 0) { \/\/ strlen must be even\n    if (WHAT &lt; 4) {      \/\/ Input has to be at least 4 char\n      WIN = 0;           \/\/ As soon as I got to this function I just tossed\n    }                    \/\/ in 8997 and won. lol. onwards!\n    else {\n      \/\/ Looks like we're looping through the first half of the string\n      for (local_128 = 1; iVar1 = WHAT \/ 2, local_128 &lt; WHAT \/ 2; local_128 = local_128 + 1) {\n        \/\/ If the character at local_128 is &lt;= the previous one, fail\n        if (*(char *)((long)&amp;input + (long)local_128) &lt;=\n            *(char *)((long)&amp;input + (long)(local_128 + -1))) {\n          WIN = 0;\n          goto function1; \/\/ Considered harmful\n        }\n      }\n      \/\/ Let's not pretend that either of us are fully familiar with\n      \/\/ do while syntax.\n      \/\/ But it's gotta be somewhat intuitive, right?\n      \/\/ Looks like this increments iVar1 and local_124\n      \/\/ starting just after where we stopped\n      do {\n        local_124 = iVar1 + 1;\n        \/\/ If we've iterated past the end of the string, win!\n        if (WHAT &lt;= local_124) {\n          WIN = 1;\n          goto function1;\n        }\n        lVar3 = (long)iVar1;\n        iVar1 = local_124; \/\/ iVar1 gets set to where the first loop ended\n      } while (*(char *)((long)&amp;input + (long)local_124) &lt; *(char *)((long)&amp;input + lVar3)); \/\/ Same as the last loop, but descend\n      WIN = 0; \/\/ Otherwise, lose\n    }\n  }\n  else {\n    WIN = 0;\n  }\nfunction1:\n  if (local_10 == *(long *)(in_FS_OFFSET + 0x28)) {\n    return WIN;\n  }\n                    \/* WARNING: Subroutine does not return *\/\n  __stack_chk_fail();\n}<\/code><\/pre>\n<\/div>\n<\/div>\n\n\n\n<p>This function walks up the first half of the number, expecting each digit to be greater than the last. It then walks back down, expecting each digit to be lesser than the last. Any number that fits this criteria will work, but 8997 happens to be a convenient test case \ud83d\ude42<\/p>\n\n\n\n<h2 class=\"has-text-align-center wp-block-heading\">footnotes<\/h2>\n\n\n\n<p id=\"f1\">1: The most common PIN numbers are 1234, 1111, and 0000, in case you ever find a debit card on the street and want to take your chances at the ATM.<\/p>\n\n\n\n<p id=\"f2\">2: There also might be junk after the bytes you send in. Testing shows that <code>0xD0 + 0xD0 + 0x00 + 0x00<\/code> (\u00d0\u00d0), which should sum correctly does not succeed. <s>It doesn&#8217;t<\/s> I don&#8217;t seem to like extended ASCII codes anyways, but bonus points if you can figure out a way to do it with fewer characters. I think I&#8217;ll drop the computer roleplay for the rest of the footnotes<\/p>\n\n\n\n<p>3: This is, presumably, a Ghidra bug. Anyways, I didn&#8217;t notice until afterward. And I started by googling various permutations of &#8220;check c&#8221; because I had forgotten that it was a handmade function.<\/p>\n\n\n\n<p id=\"f4\">4:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignleft is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/i.pinimg.com\/originals\/67\/5f\/bf\/675fbf80eabf11721c93f345a156b40f.jpg\" alt=\"Pin em wojak\" width=\"285\" height=\"341\" \/><figcaption>Nooo you can&#8217;t just paste gibberish you&#8217;re supposed to read through my incomprehensible function!!<\/figcaption><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignright size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4941\/files\/2022\/10\/zoomerSmirk-2-edited.png\" alt=\"\" class=\"wp-image-78\" width=\"369\" height=\"349\" \/><figcaption>8997abagaga go brrrrr<\/figcaption><\/figure><\/div>\n\n\n\n<p id=\"f5\">5: Seriously, I need to permanently remove that site from search results. Sorry this footnote is out of order, I&#8217;m putting them in by hand. Next project a writeup bloginator with footnote capabilities that would bring David Foster Wallace to jealous tears.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>POP QUIZ TIME! Can you solve these challenging questions? What number am I thinking of? If I were a human, it would be difficult to know what the answer to this question might be1. Thankfully, I am a computer, and will bare my essential nature to anyone with a keyboard. How about you decompile me &hellip; <a href=\"https:\/\/blogs.oregonstate.edu\/paul\/2022\/10\/14\/writeup-pop-quiz\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Writeup: pop quiz<\/span><\/a><\/p>\n","protected":false},"author":11809,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[8],"class_list":["post-71","post","type-post","status-publish","format-standard","hentry","category-writeups","tag-rev"],"_links":{"self":[{"href":"https:\/\/blogs.oregonstate.edu\/paul\/wp-json\/wp\/v2\/posts\/71","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.oregonstate.edu\/paul\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.oregonstate.edu\/paul\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.oregonstate.edu\/paul\/wp-json\/wp\/v2\/users\/11809"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.oregonstate.edu\/paul\/wp-json\/wp\/v2\/comments?post=71"}],"version-history":[{"count":10,"href":"https:\/\/blogs.oregonstate.edu\/paul\/wp-json\/wp\/v2\/posts\/71\/revisions"}],"predecessor-version":[{"id":86,"href":"https:\/\/blogs.oregonstate.edu\/paul\/wp-json\/wp\/v2\/posts\/71\/revisions\/86"}],"wp:attachment":[{"href":"https:\/\/blogs.oregonstate.edu\/paul\/wp-json\/wp\/v2\/media?parent=71"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.oregonstate.edu\/paul\/wp-json\/wp\/v2\/categories?post=71"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.oregonstate.edu\/paul\/wp-json\/wp\/v2\/tags?post=71"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}