{"id":101,"date":"2022-11-01T02:08:48","date_gmt":"2022-11-01T02:08:48","guid":{"rendered":"https:\/\/blogs.oregonstate.edu\/paul\/?p=101"},"modified":"2022-11-01T02:08:48","modified_gmt":"2022-11-01T02:08:48","slug":"writeup-stackulator","status":"publish","type":"post","link":"https:\/\/blogs.oregonstate.edu\/paul\/2022\/11\/01\/writeup-stackulator\/","title":{"rendered":"Writeup: Stackulator"},"content":{"rendered":"\n<p>NAME: stackulator<br>CATEGORY: pwn<br>POINTS: 200<\/p>\n\n\n\n<p>First pwn of the season! And the second pwn of my life!<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Welcome to my first calculator!\n \nWhat is your name?:<\/code><\/pre>\n\n\n\n<p>Aw man. What a polite calculator. What a shame we have to pummel it with malicious input.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>undefined8 main(void)\n\n{\n  int iVar1;\n  undefined8 uVar2;\n  long lVar3;\n  undefined8 *puVar4;\n  long in_FS_OFFSET;\n  undefined8 local_88 &#091;8];\n  int local_48;\n  undefined8 local_44;\n  undefined8 local_3c;\n  undefined8 local_30;\n  undefined8 local_28;\n  char local_20 &#091;16];\n  long local_10;\n  \n  local_10 = *(long *)(in_FS_OFFSET + 0x28);\n  puVar4 = local_88;\n  for (lVar3 = 0xe; lVar3 != 0; lVar3 = lVar3 + -1) {\n    *puVar4 = 0;\n    puVar4 = puVar4 + 1;\n  }\n  local_44 = 0x6c2e636c61632f2e;\n  local_3c = 0x676f;\n  puts(\"Welcome to my first calculator!\\n\\nWhat is your name?:\");\n  fgets((char *)local_88,99,stdin); \/\/ Reads 99 bytes to local_88\n  printf(\"\\nHello %s\",local_88);\n  if (local_48 == 1) { \/\/ This seems important\n    debug_menu(&amp;local_44);\n  }\n  else {\n    ...\n<\/code><\/pre>\n\n\n\n<p>OK, so we have an opportunity to write past the 64 bytes that are allocated to local_88. The following variable is local_48, which needs to be set to 1 to enter the debug menu. So if we send 64 bytes of gibberish, we can overwrite local_48. Appending 1 as a 4-byte little-endian integer gets us to the debug menu:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Select an option:\n1) Receive a compliment\n2) View log file\n3) Get a random YouTube link\n4) Show me an ASCII bee<\/code><\/pre>\n\n\n\n<p>This now gives us an option to read a file. More importantly, however, we can get a compliment:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>You are good at making secure calculators\n\nGoodbye!<\/code><\/pre>\n\n\n\n<p>Wrong!<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void debug_menu(char *param_1)\n\n{\n...\n      if (local_40d == '2') {\n        puts(\"\\nLog contents:\");\n        local_40c = open(param_1,0);\n        read(local_40c,local_408,1000);\n        puts(local_408);\n        goto code_r0x00101396;\n      }\n...\n}<\/code><\/pre>\n\n\n\n<p>This reads a file that&#8217;s passed in by param_1. Which conveniently is just after the stuff you&#8217;ve overwritten. Now it is time to spend 20 minutes guessing the name of the flag. It&#8217;s not flag.txt or calc.log. 2 minutes after the challenge expires we will learn that the correct file is merely titled flag. I don&#8217;t know why I went so long without trying that. Appending that will get us the flag, so all is well!<\/p>\n\n\n\n<p>Craft the exploit with a final payload of 64 bytes, the integer 1, and then &#8220;flag&#8221;, being sure to add a null terminator. Submitting this prints out the contents of a file named &#8220;flag&#8221;!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>NAME: stackulatorCATEGORY: pwnPOINTS: 200 First pwn of the season! And the second pwn of my life! Aw man. What a polite calculator. What a shame we have to pummel it with malicious input. OK, so we have an opportunity to write past the 64 bytes that are allocated to local_88. The following variable is local_48, &hellip; <a href=\"https:\/\/blogs.oregonstate.edu\/paul\/2022\/11\/01\/writeup-stackulator\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Writeup: Stackulator<\/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":[1],"tags":[],"class_list":["post-101","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/blogs.oregonstate.edu\/paul\/wp-json\/wp\/v2\/posts\/101","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=101"}],"version-history":[{"count":4,"href":"https:\/\/blogs.oregonstate.edu\/paul\/wp-json\/wp\/v2\/posts\/101\/revisions"}],"predecessor-version":[{"id":105,"href":"https:\/\/blogs.oregonstate.edu\/paul\/wp-json\/wp\/v2\/posts\/101\/revisions\/105"}],"wp:attachment":[{"href":"https:\/\/blogs.oregonstate.edu\/paul\/wp-json\/wp\/v2\/media?parent=101"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.oregonstate.edu\/paul\/wp-json\/wp\/v2\/categories?post=101"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.oregonstate.edu\/paul\/wp-json\/wp\/v2\/tags?post=101"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}