Your Ad Here
                  - P H R A C K   M A G A Z I N E -

                        Volume 0xa Issue 0x38
                              05.01.2000
                              0x0c[0x10]

|----------------------------- DISTRIBUTED TOOLS -----------------------------| |-----------------------------------------------------------------------------| |----------------------------- sasha / lifeline ------------------------------|

"The COAST approach has been to look at limits and underlying problems and see what we can do to change the paradigm. We don't start with the view that 'well, the system gives us X and we know Y, so what can we find using that?' Instead, we ask questions about the whole process of intrusion and misuse, and try to find new ideas there."

- Gene Spafford

----| Distributed Denial of Service Attacks

It is perhaps prophetic that the first CERT advisory of the 21st century should concern a distributed Denial of Service attack (see CA-2000-01 [1]).

In November 1999, CERT even held a 'Distributed-Systems Intruder Tools Workshop' [2], to discuss "the threat" of distributed DoS (Denial of Service) tools.

Briefly: in a distributed DoS attack, daemons are installed on multiple compromised hosts; a client is used to identify a target to the daemons who each then launch a DoS attack (usually using flood-like attacks i.e. UDP, ICMP, SYN). The unified and sustained nature of attacks generated by multiple daemons can often cripple a target network/host.

Some good work has been done on analysis of current distributed DoS tools, and we direct the interested reader to the work of David Dittrich [3].

----| Applications of a Distributed Approach

It is somewhat depressing that DoS is very often the first application of any new idea which can be utilized in a security context, and this is especially true of distributed techniques, since the distributed 'philosophy' is applicable to many facets of computer network penetration.

Below, we describe two examples of the distributed approach applied to very familiar tasks: port scanning and password sniffing. Source code for an example distributed port scanner implementation is included at the end of the article.

----| Port Scanning

In P55-09 - 'Distributed Information Gathering' [4], the advantages in using a distributed network information gathering approach are described, namely:

I. Stealth

By employing co-operation, time dilation, and randomization techniques we hope to elude NIDS (network-based intrusion detection systems).

II. Correlation Information

The acquisition of multiple 'points of view' of a target enables a more complete model of the target to be constructed, including multiple route and timing information.

III. Pervasive Information Gathering

The countermeasures which some N-IDS can employ, such as injecting a 'deny rule' into a firewall (for example, using an OPSEC API [5]), become less effective at stopping ongoing information gathering.

----| Distributed Port Scan Detection

To detect a distributed port scan in which multiple hosts are being used to distribute and "share the work" of information gathering, the functionality must exist in a detection system to analyze a recorded event (for example - a SYN packet sent to a port) in context, i.e. using circumstantial information.

The difficulty lies in knowing which information it is valuable to keep; you may throw away the one byte which unlocks the puzzle! Resource starvation and state-holding attacks then become applicable, since the resources available to the detection system are unlikely to be infinite.

Assuming no pathologically obvious variations of information gathering techniques are used (e.g. SYN+RST), a detection system must almost ignore source IP addresses when performing analysis, since by definition, multiple source hosts can distribute the set of probes to be performed.

For example, if you receive a connect to each port from 1 to 1024 over the duration of a week, from multiple hosts, you are likely to have been port scanned; however, the set of ports an individual is interested in determining are open on your machine (or network), is unlikely to be as easy to recognize as 1-1024.

There obviously exists an opportunity to perform much more research in the area of programmatically identifying distributed attacks.

----| Password Sniffing

In P55-16 - 'Distributed Metastasis' [6], the advantages associated with using a distributed model for password sniffing are described; briefly, the two primary advantages are in removing the need to revisit a compromised host to collect sniffer logs, and to increase the speed with which the sniffed information is made available so that the penetration can be immediately continued/deepened.

----| The Implementation

An implementation of a distributed port scanner is provided for illustrative purposes.

DPS (Distributed Port Scanner) consists of a client working in conjunction with agents located on multiple remote hosts.

The communication between the client and the agents is provided via some basic commands encapsulated in ICMPECHOREQUEST/REPLY packets, thus providing a fairly covert channel. Strong data payload encryption is planned for a later release.

The port scan request is done by the client; the agents perform the port scan itself, and then report the results back to the client.

Imagine that we have 4 agents, located on 4 different hosts: 'hardbitten', 'doubt', 'ketamine' and 'neurosponge'. Our goal is to obtain the status of ports 21, 22, 23, 80 and 143 on 10.0.2.10. The client is located on the host 'implode' and agents.txt is a file containing a list of agents.

[root@implode dps]# ./client 10.0.2.10 21-23,80,143 agents.txt eth0 packet sent. 1 of 1 Using device eth0 21 iz open 23 iz open 80 iz open

[root@implode dps]#

The client distributes the "workload" (the set of ports) between the different agents; each agent scans the target host for a subset of the total ports, then reports the results back to the client.

This isn't by any means a finished product - it is proof-of-concept. Planned features for future releases include: distributed password sniffing, distributed remote OS detection, strong crypto, multi-threaded agents, and other ideas that people have been throwing seen this project was begun. Stay tuned. Take your time to browse through the source code. Both Libnet and Libpcap are needed by both the agent and the client.

----| Conclusions

It is interesting to see historically the wave-like effect that exists between centralized and distributed computing: mainframe, client/server, thin-client (such as Windows Terminal Server and the JavaStation Network Computer), etc. This same effect has not yet been fully witnessed in computer security (the Morris Worm [7] is an obvious exception).

Conversely, the concept of 'remote control' is not new to security; Loki [8], Back Orifice [9], and NetBus [10] all provide client/server style remote control functionality.

To conclude, the key to the distributed 'philosophy', is the combination of the above two concepts.

----| References

[1] CERT Advisory CA-2000-01 - Denial-of-Service Developments, CERT/CC and FedCIRC, January 3, 2000, http://www.cert.org/advisories/CA-2000-01.html

[2] Results of the Distributed-Systems Intruder Tools Workshop, Pittsburgh, Pennsylvania USA, November 2-4, 1999, Published at the CERT Coordination Center, Software Engineering Institute, Carnegie Mellon University, Pittsburgh, PA, 15213, December 7, 1999, http://www.cert.org/reports/dsit_workshop.pdf

[3] The Dos Project's "trinoo" distributed denial of service attack tool, The "Tribal Flood Network" distributed denial of service attack tool, The "stacheldraht" distributed denial of service attack tool, David Dittrich, University of Washington, December 31, 1999, http://www.washington.edu/People/dad/

[4] Distributed Information Gathering, hybrid, Phrack Magazine, Vol. 9, Issue 55, Article 9 of 16, 09.09.99, http://www.phrack.com/search.phtml?view&article=p55-9

[5] Check Point Open Platform for Security (OPSEC), Check Point Software Technologies Ltd, 1999, http://www.opsec.com

[6] Distributed Metastasis: A Computer Network Penetration Methodology, Andrew J. Stewart, Phrack Magazine Vol. 9, Issue 55, Article 16 of 19, 09.09.99, http://www.phrack.com/search.phtml?view&article=p55-16

[7] The Internet Worm Program: An Analysis, Eugene H. Spafford, Purdue University, 1998, http://www.cerias.purdue.edu/coast/archive/data/categ29.html

[8] Project Loki, daemon9 & alhambra, Phrack Magazine Vol. 7, Issue 49, Article 06 of 19, August 1996, http://www.phrack.com/search.phtml?view&article=p49-6

[9] Back Orifice 2000, Cult of the Dead Cow, http://www.b02k.com

[10] http://www.netbus.org

----| Source Code

<++> p56/dps/Makefile !5f996922 CC = gcc CFLAGS = -O3 -DDEBUG LIBS = -lnet -lpcap CLIOBJECTS = source/cltmain.o source/cltpacketinjection.o source/cltwait.o AGTOBJECTS = source/agtmain.o source/agtpscan.o DPSOBJECTS = source/dpshelper.o source/dps_pcap.o

.c.o: $(CC) $(CFLAGS) $(DEFINES) -c $< -o $@

common: $(DPS_OBJECTS)

client: $(CLIOBJECTS) $(DPSOBJECTS)
$(CC) $(DPSOBJECTS) $(CLIOBJECTS) $(LIBS) -o client strip client

agent: $(AGTOBJECTS) $(DPSOBJECTS) $(CC) $(DPSOBJECTS) $(AGTOBJECTS) $(LIBS) -o agent strip agent

clean: rm -f source/*.o core

<--> <++> p56/dps/README !6dab2725 dps 1.0

dps is a distributed portscanning tool. It consists in a client working in conjuction with agents located in several remote hosts thus providing 'many-to-one' and 'many-to-many' portscanning.

The communication between the client and the agents is provided via some basic commands encapsulated in ICMP ECHOREQUEST/ECHOREPLY packets this way providing a fairly covert channel.

Data payload encryptation is also available using the most popular symmetric-key algorithms (except for DES due to the pathetic export restrictions is U.S.). (not yet implemented)

The portscan request is done by the client, being the portscan itself done by the agents which then report back to the client the results obtained.

Compilation notes:

  1. make client
  2. make agent

and that'z it! <--> <++> p56/dps/agents.txt !96b84d09 foo bar neuro.somewieirddomain.org 10.0.2.10 <--> <++> p56/dps/localtest.txt !ea0d9aae 127.0.0.1 <--> <++> p56/dps/include/config.h !5d33c259

define MAGIC "lifeline" /* magic string, only alphanumerical

                                   characters please. Btw, you will
                                   become an idiot if you don't change this.
                                */

define BLOWFISH_KEY "lifelinerox"

define MAXHOSTSIZE 64 /* maximum hostname size allowed */

define MAXICMPPAYLOAD_SIZE 56 /* ok, this one is tricky. A maximum payload

                                   of 56 bytes is recommended is you want 
                                   the packets to seem real. But 56 may not
                                   be enough to store all the port 
                                   information, in this case the program
                                   will split up in various ICMP packets, 
                                   however in the case that the port 
                                   information may be really large it will 
                                   cause a tremendous ICMP flood in the
                                   network, so deal with it and use the 
                                   option that fits you best.                   
                                 */

<--> <++> p56/dps/include/dps_pcap.h !3dca6d72

ifndef DPS_PCAP

define DPS_PCAP

ifdef SOLARIS

include "./solaris.h"

endif

include

define LOOPBACK_OFFSET 4

define ETHERNET_OFFSET 14

define SLIPPPPOFFSET 24

char errbuf[PCAPERRBUFSIZE];

void dpspcaperr( char *, char * );

pcapt * dpspcap_prep( int, char *, char * );

int dpspcapdatalink( pcap_t * );

void * dpspcapnext( pcap_t * );

endif /* DPS_PCAP */

/* EOF */ <--> <++> p56/dps/include/prototypes.h !f50ce3e5

include

extern char *itoa(int);

struct agentnfo { ulong address; /* agent's IP address */ ulong victim; /* victim's IP address / char *ports; / ports to scan separated by comas(",") and minus("-"); / struct agentnfo *next; / next agent in list, this is a linked list */ };

struct scannfo { ulong victim; ulong cli_addr; char *ports; };

struct spheader { char magic[8]; _u8 plus:1, res2:1, res3:1, res4:1, res5:1, res6:1, res7:1, res8:1; };

extern short int inject(struct agentnfo *, char *); <--> <++> p56/dps/include/solaris.h !acb0956b

ifndef SOLARIS_H

define SOLARIS_H

include

include

include

include

include

include

include

include

include

include

include

include

include

include

include

endif /* SOLARIS_H */

/* EOF */ <--> <++> p56/dps/source/agt_main.c !aaf7e1ae

include

include

include

include

include

include

include

include

include "../include/config.h"

include "../include/prototypes.h"

define SNAPLEN 64

define ETHHDR 14

void pktanalyserfunc(char *, char *);

/* Global variables */ unsigned int dlinks; const uchar *snapend;

int main(int argc, char **argv) {

pkt_analyser_func(argv[1], MAGIC);

}

void pktanalyserfunc(char *dev, char *magic) {

pcap_t                          *pd;
char                            *data;
struct pcap_pkthdr      h;
struct iphdr            *iph;
char                            *payload;
int x;
struct sp_header        *head;
struct scannfo          *scan;

if(!dev) {
    if(!(dev = pcap_lookupdev(NULL))) {
        perror("pcap_lookupdev");                       
        exit(1);
    }               
}
printf("Using device %s\n", dev);       


pd = pcap_open_live(dev, SNAPLEN, 0, 10, NULL);

switch(pcap_datalink(pd)) {
case DLT_EN10MB:
case DLT_IEEE802:
    dlink_s = ETHHDR;
    break;
case DLT_NULL:
    dlink_s = 4;
    break;
default:
    perror("unknown datalink header");
    exit(0);
    break;
}                               

for(;;) {
    data = pcap_next(pd, &h);       

    iph = (struct iphdr *)(data + dlink_s);

    if(iph->protocol == IPPROTO_ICMP) {
        struct icmphdr *icmph = (struct icmphdr *)(data + dlink_s + iph->ihl*4);
        if(icmph->type == 8 && icmph->code == 0) {

            payload = malloc(MAX_ICMP_PAYLOAD_SIZE);
            memcpy(payload, data + dlink_s + iph->ihl*4 + 8, MAX_ICMP_PAYLOAD_SIZE);

/* for(x = 0; x <= MAXICMPPAYLOADSIZE; x++) printf("%c", *(payload+x)); printf("\n"); */
if (!(strncmp(MAGIC, payload, strlen(MAGIC)))) { head = malloc(16); memcpy(head, payload, 16); if (!(head->plus)) { scan = malloc(sizeof(struct scannfo)); memcpy(scan, payload + 16 + sizeof(u
long), sizeof(ulong)); memcpy(scan + sizeof(ulong), payload + 16, sizeof(ulong)); scan->ports = malloc(strlen(payload + 16 + 2*sizeof(ulong)) + 1); memset(scan->ports, '\0', strlen(payload + 16 + 2sizeof(u_long)) + 1); memcpy(scan->ports, payload + 16 + 2sizeof(ulong), strlen(payload + 16 + 2*sizeof(ulong)));
pscan(scan, pd, dev);

                }               


            }
        }                                                       
    }
}

} <--> <++> p56/dps/source/agt_pscan.c !6b34db79

include

include

include "../include/prototypes.h"

include "../include/config.h"

define SNAPLEN 64

define ETHHDR 14

int pscan(struct scannfo *scan, pcap_t *pd, char *dev) {

extern unsigned int dlink_s;
int i, timeout = 10;
char    *port, *ebuf;
int c, sock;
char *buf;
u_long src_ip, dst_ip;
int p;
u_char *data;
struct iphdr *iph;
struct tcphdr *tcph;
struct pcap_pkthdr h;
time_t utime;

srandom(time(NULL));

if(!(buf = malloc(IP_MAXPACKET))) {
    return 0;
}               

if(!(sock = open_raw_sock(IPPROTO_RAW))) {
    return 0;
}               
src_ip = htonl(get_ipaddr(NULL, dev, ebuf)); 
dst_ip = scan->victim;

libnet_build_ip(TCP_H, 0, random() % 65536, 0, 64, IPPROTO_TCP, 
                src_ip, dst_ip, NULL, 0, buf);

// sleep(2);

port = strtok(scan->ports, ",");
p = atoi(port);

while (port) {

    libnet_build_tcp(1030, p, 11111, 99999, TH_SYN, 
                     1024, 0, NULL, 0, buf + IP_H);

    libnet_do_checksum(buf, IPPROTO_TCP, TCP_H);

    c = libnet_write_ip(sock, buf, TCP_H + IP_H);

// sleep(2); i = 1; utime = time(NULL); while ((time(NULL) - utime) <= timeout && i) { data = (uchar *)pcapnext(pd, &h); iph = (struct iphdr )(data + dlink_s); if (iph->saddr == dst_ip && iph->daddr == src_ip) { if (iph->protocol == IPPROTO_TCP) { tcph = (struct tcphdr *)(data + dlink_s + iph->ihl4); if (tcph->thsport == htons(p) && tcph->thdport == htons(1030)) { if ((tcph->thflags & (THSYN|THACK)) == (THSYN|THACK)) { sendresult(p, scan->cliaddr); } // if (tcph->thflags & TH_RST)printf("%d it'z closed\n", p); i = 0; }
}
}
}

port = strtok('\0', ",");
if(!port) return 0;
p = atoi(port);

}
free(buf);
return 1;

}

int sendresult(int p, ulong dst_ip) {

char    *buf;
int     c, sock;
u_long  src_ip;


src_ip = libnet_name_resolve("127.0.0.1", 1);

if(!(sock = open_raw_sock(IPPROTO_RAW))) {
    return 0;
}               
buf = malloc(IP_MAXPACKET);
memset(buf, '\0', IP_MAXPACKET);

libnet_build_ip(ICMP_ECHO_H + sizeof(int) + strlen(MAGIC),
        0,
        random() % 65535,
        0,
        32,
        IPPROTO_ICMP,
        src_ip,
        dst_ip,
        NULL,
        0,
        buf);

libnet_build_icmp_echo(ICMP_ECHO, 0, 440, 1, NULL, 0, buf + IP_H);

memcpy(buf + IP_H + ICMP_ECHO_H, "araiarai", strlen(MAGIC));
memcpy(buf + IP_H + ICMP_ECHO_H + strlen(MAGIC), &p, sizeof(int));

if (libnet_do_checksum(buf, IPPROTO_ICMP, ICMP_ECHO_H + strlen(MAGIC) + sizeof(int)) == -1) {
    return -1;
}


c = libnet_write_ip(sock, buf, ICMP_ECHO_H + IP_H + strlen(MAGIC) + sizeof(int));
if (c < ICMP_ECHO_H + IP_H + strlen(MAGIC) + sizeof(int)) {

// printf("Error writing to network\n"); return -1; }

// printf("wrote %d bytes.\n", c);

return 1;

} <--> <++> p56/dps/source/clt_main.c !6b6e9348

include

include

include

include "../include/config.h"

include "../include/prototypes.h"

void usage(char *);

int main(int argc, char **argv) {

int                             x, round;
FILE                            *agentsfd;
struct agentnfo         *agent, *first_agent;
char                            *temp, *ports;  
u_char                          buf2[MAX_HOST_SIZE], *buf3;
u_long                          address;
u_short                         begin_port, end_port;
char                            *sequence;


if (getuid() || geteuid()) {
    fprintf(stderr, "You need to be root to run dps.\n");
    exit(0);
}

if (argc != 5) usage(argv[0]);                          

if ((agentsfd = fopen(argv[3], "r")) == NULL) {
    fprintf(stderr, "Error opening %s.\n", argv[3]);
    exit(0);
}               

round = 0;

while ((fgets(buf2, MAX_HOST_SIZE, agentsfd)) != NULL) {  

    buf3 = malloc(strlen(buf2));
    memset(buf3, '\0', strlen(buf2));
    memcpy(buf3, buf2, strlen(buf2) - 1);

    if ((address = libnet_name_resolve(buf3, 1)) == -1) {
        fprintf(stderr, "Error resolving %s\n", buf3);
        fclose(agentsfd);
        exit(0);
    }

    free(buf3);

    if (!round)     {       
        agent = malloc(sizeof(struct agentnfo));
        first_agent = agent;
        round = 1;
    }
    else {
        agent->next = malloc(sizeof(struct agentnfo)); 
        agent = agent->next;
    }

    memcpy((struct agentnfo *)agent, &address, sizeof(u_long));

    agent->victim = libnet_name_resolve(argv[1], 1);

    agent->ports = NULL;

    agent->next = NULL;

}

fclose(agentsfd);


agent = first_agent;    
ports = strtok(argv[2], ",");
if (strrchr(ports, '-')) {
    if (strchr(ports, '-')) {
        sequence = malloc(strchr(ports, '-') - ports);
        memcpy(sequence, ports, strchr(ports, '-') - ports);
        begin_port = atoi(sequence);
        sequence = malloc(strlen(ports) - (strchr(ports, '-')-ports));
        memcpy(sequence, strchr(ports, '-') + 1, strlen(ports) - (strchr(ports, '-')-ports));
        end_port = atoi(sequence); 
        for (x = begin_port ; x <= end_port ; x++) {
            if (agent->next == NULL || x == begin_port) {                                   
                agent = first_agent;
            }
            else
                agent = agent->next;
            if (agent->ports == NULL) {
                agent->ports = malloc(strlen(ports) + 2);
                memset(agent->ports, '\0', strlen(ports) + 2);
            }
            else {
                temp = malloc(strlen(agent->ports) + strlen(ports) + 2);
                memset(temp, '\0', strlen(agent->ports) + strlen(ports) + 2);
                memcpy(temp, agent->ports, strlen(agent->ports));
                free(agent->ports);
                agent->ports = temp;
            }
            memcpy(agent->ports + strlen(agent->ports), itoa(x), strlen(ports));
            memcpy(agent->ports + strlen(agent->ports), ",", 1);
        }
    }
}
else {
    agent->ports = malloc(strlen(ports) + 2);
    memset(agent->ports, '\0', strlen(ports) + 2);
    memcpy(agent->ports, ports, strlen(ports));
    memcpy(agent->ports + strlen(ports), ",", 1);
}
while (ports) {
    ports = strtok('\0', ",");
    if (ports) { 
        if (strchr(ports, '-')) {
            seq:
            sequence = malloc(strchr(ports, '-') - ports);
            memcpy(sequence, ports, strchr(ports, '-') - ports);
            begin_port = atoi(sequence);
            sequence = malloc(strlen(ports) - (strchr(ports, '-')-ports));
            memcpy(sequence, strchr(ports, '-') + 1, strlen(ports) - (strchr(ports, '-')-ports));
            end_port = atoi(sequence); 
            for (x = begin_port ; x <= end_port ; x++) {
                if (agent->next == NULL)                                        
                    agent = first_agent;
                else
                    agent = agent->next;
                if (agent->ports == NULL) {
                    agent->ports = malloc(strlen(ports) + 2);
                    memset(agent->ports, '\0', strlen(ports) + 2);
                }
                else {
                    temp = malloc(strlen(agent->ports) + strlen(ports) + 2);
                    memset(temp, '\0', strlen(agent->ports) + strlen(ports) + 2);
                    memcpy(temp, agent->ports, strlen(agent->ports));
                    free(agent->ports);
                    agent->ports = temp;
                }
                memcpy(agent->ports + strlen(agent->ports), itoa(x), strlen(ports));
                memcpy(agent->ports + strlen(agent->ports), ",", 1);
            }



        }
        else {
            if (agent->next == NULL) 
                agent = first_agent;
            else 
                agent = agent->next;
            if (agent->ports == NULL) { 
                agent->ports = malloc(strlen(ports) + 2);
                memset(agent->ports, '\0', strlen(ports) + 2);
            }
            else {
                temp = malloc(strlen(agent->ports) + strlen(ports) + 2);
                memset(temp, '\0', strlen(agent->ports) + strlen(ports) + 2);
                memcpy(temp, agent->ports, strlen(agent->ports));
                free(agent->ports);
                agent->ports = temp;
            }
            memcpy(agent->ports + strlen(agent->ports), ports, strlen(ports));
            memcpy(agent->ports + strlen(agent->ports), ",", 1);
        }
    }
}

ifdef DEBUG

for (agent = first_agent; agent != NULL; agent = agent->next) {
    printf("%ld -> %s\t%p\t%ld\n", agent->address, agent->ports, agent->ports, agent->victim);
}

endif

printf("elite\n");
// free(temp); // free(sequence); printf("ultra-elite\n"); if(inject(first_agent, argv[4]) != 1) { printf("Error in packet injection\n"); }

wait_results(argv[4]);

exit(1);

}

void usage(char *exec) { printf("dps - lifeline lifeline@against.org\n"); printf("%s \n", exec); exit(1); }
<--> <++> p56/dps/source/cltpacketinjection.c !cbbedc0d

include

include "../include/config.h"

include "../include/prototypes.h"

define MAGIC "lifeline"

define AGENT "doubt"

define SOURCE "hardbitten"

/* * * Packet injection routines. * */ short int inject (struct agentnfo *first_agent, char *dev) {

struct agentnfo *agent;
struct sp_header *head;
int                     sock, x, c, offset, y;
unsigned int    each_p, info_s, packets_n;
char                    *pload, *buf, *ebuf;    
u_long                  src_ip, dst_ip, cli_addr;


cli_addr = src_ip = htonl(get_ipaddr(NULL, dev, ebuf));

/* dps control header construction */
head = malloc(16);
memset(head, '\0', 16); 
memcpy(head, &MAGIC, 8);/* MAGIC string should be no longer than 8 chars */


sock = libnet_open_raw_sock(IPPROTO_RAW);
if (sock == -1) return -1;

for (agent = first_agent ; agent != NULL ; agent = agent->next) {
    /* 
     * First let'z take care of our special payload. 
     *
 * -------------------------
 * | MAGIC |+|R|R|R|R|R|R|R|
     * -------------------------------------        
     * cli_addr | victim_addr | ports_info |
     * -------------------------------------
     */     

    /* Space available in each packet */
    each_p = MAX_ICMP_PAYLOAD_SIZE - 16;

    /* Total information size */    
    info_s = 2*sizeof(u_long) + strlen(agent->ports);

    /* Calculate the number of packets needed for all the info. */
    packets_n = (info_s % each_p ? info_s / each_p + 1 : info_s / each_p);


    /* Allocate memory */
    pload = malloc(MAX_ICMP_PAYLOAD_SIZE + 1);
    memset(pload, '\0', MAX_ICMP_PAYLOAD_SIZE + 1);

    buf = malloc(IP_H + ICMP_ECHO_H + MAX_ICMP_PAYLOAD_SIZE + 1);
    memset(buf, '\0', IP_H + ICMP_ECHO_H + MAX_ICMP_PAYLOAD_SIZE + 1);

    dst_ip = agent->address;

    libnet_build_ip(MAX_ICMP_PAYLOAD_SIZE,
                    0,
                    random() % 65535,
                    0,
                    32,
                    IPPROTO_ICMP,
                    src_ip,
                    dst_ip,
                    NULL,
                    0,
                    buf);


    offset = 0;     
    for (x = 1 ; x <= packets_n ; x++) {

        if (x < packets_n) { 
            head->plus = 1;
            memset(pload, '\0', MAX_ICMP_PAYLOAD_SIZE + 1); 
            memcpy(pload, head, 16);
            memcpy(pload + 16, agent->ports + offset, MAX_ICMP_PAYLOAD_SIZE - 16);

// memcpy(pload + 16, agent->ports + offset, strlen(agent->ports)); offset =+ (MAXICMPPAYLOADSIZE - 16); } else { head->plus = 0; memset(pload, '\0', MAXICMPPAYLOADSIZE + 1); memcpy(pload, head, 16); memcpy(pload + 16, &cliaddr, sizeof(ulong)); memcpy(pload + 16 + sizeof(ulong), &(agent->victim), sizeof(ulong)); memcpy(pload + 16 + 2sizeof(u_long), agent->ports + offset, strlen(agent->ports)); // memset(pload + 16 + 2sizeof(ulong) + strlen(agent->ports + offset), 'A', MAXICMPPAYLOADSIZE - (16 + 2*sizeof(u_long) + strlen(agent->ports + offset)));

        } 

        libnet_build_icmp_echo(ICMP_ECHO, 0, 440, 1, NULL, 0, buf + IP_H);

        memset(buf + IP_H + ICMP_ECHO_H, '\0', MAX_ICMP_PAYLOAD_SIZE + 1);
        memcpy(buf + IP_H + ICMP_ECHO_H, pload, MAX_ICMP_PAYLOAD_SIZE);

        if (libnet_do_checksum(buf, IPPROTO_ICMP, ICMP_ECHO_H + MAX_ICMP_PAYLOAD_SIZE) == -1) {
            return -1;
        }

/* for (y = 0 ; y <= 64 ; y++)
printf("%c", *(buf + 28 + y)); printf("\n"); */ c = libnetwriteip(sock, buf, ICMPECHOH + IPH + MAXICMPPAYLOADSIZE); if (c < ICMPECHOH + IPH + MAXICMPPAYLOADSIZE) { printf("Error writing to network\n"); return -1; } printf("packet sent. %d of %d\n", x, packets_n);

    }

}

free(buf);
return 1;

} <--> <++> p56/dps/source/clt_wait.c !cd679af6

include

include

include

include

include

include

include

include

include "../include/config.h"

include "../include/prototypes.h"

define SNAPLEN 64

define ETHHDR 14

/* Global variables */ unsigned int dlinks; const uchar *snapend;

int wait_results(char *dev) {

pcap_t                          *pd;
char                            *data;
struct pcap_pkthdr      h;
struct iphdr            *iph;
char                            *payload;
int x;

if(!dev) {
    if(!(dev = pcap_lookupdev(NULL))) {
        perror("pcap_lookupdev");                       
        exit(1);
    }               
}
printf("Using device %s\n", dev);       


pd = pcap_open_live(dev, SNAPLEN, 0, 10, NULL);

switch(pcap_datalink(pd)) {
case DLT_EN10MB:
case DLT_IEEE802:
    dlink_s = ETHHDR;
    break;
case DLT_NULL:
    dlink_s = 4;
    break;
default:
    perror("unknown datalink header");
    exit(0);
    break;
}                               

for(;;) {
    data = pcap_next(pd, &h);       

    iph = (struct iphdr *)(data + dlink_s);

    if(iph->protocol == IPPROTO_ICMP) {
        struct icmphdr *icmph = (struct icmphdr *)(data + dlink_s + iph->ihl*4);
        if(icmph->type == 8 && icmph->code == 0) {

            payload = malloc(MAX_ICMP_PAYLOAD_SIZE);
            memcpy(payload, data + dlink_s + iph->ihl*4 + 8, MAX_ICMP_PAYLOAD_SIZE);
            if (!(strncmp("araiarai", payload, strlen(MAGIC)))) {
                memcpy(&x, payload + strlen(MAGIC), sizeof(int));
                printf("%d iz open\n", x);      
            }
        }                                                       
    }
}

} <--> <++> p56/dps/source/dps_helper.c !a6720d71 /* * dps * --- * helper functions * * lifeline * */

char s[]; char *itoa (int n) {

int i, sign, x, y, z;

if ((sign = n) < 0)
    n = -n;
i = 0;
do {
    s[i++] = n % 10 + '0';
} while ((n /= 10) > 0);
if (sign < 0)
    s[i++] = '-';
s[i] = '\0';

for (y = 0, z = strlen(s)-1 ; y < z ; y++, z--) {
    x = s[y];
    s[y] = s[z];
    s[z] = x;
}
return s;

} <--> <++> p56/dps/source/dps_pcap.c !dfe55d3e

include "../include/dps_pcap.h"

void dpspcaperr(char *function, char *error) { fprintf(stderr, "%s: %s\n", function, error); exit (1); }

pcapt * dpspcapprep(int snaplen, char *filter, char *device) { pcapt *pd; bpfuint32 localnet, netmask; struct bpf_program fcode;

if(!device) {
    if ((device = pcap_lookupdev(errbuf)) == NULL)
{
    dps_pcap_err("pcap_lookupdev", errbuf);
    }
}

if ((pd = pcap_open_live(device, snaplen, 1, 500, errbuf)) == NULL)
{
dps_pcap_err("pcap_open_live", errbuf);
}

if (pcap_lookupnet(device, &localnet, &netmask, errbuf) == -1)
{
dps_pcap_err("pcap_lookupnet", errbuf);
}

if (pcap_compile(pd, &fcode, filter, 1, netmask) == -1)
{
dps_pcap_err("pcap_compile", errbuf);
}

if (pcap_setfilter(pd, &fcode) == -1)
{
dps_pcap_err("pcap_setfilter", errbuf);
}
return (pd);

}

int dpspcapdatalink(pcap_t *pd) { int offset;

switch (pcap_datalink(pd))
{

/* There'z no such DLT in OpenBSD, I'm changing to NULL, should work on solaris. */ case DLTNULL: offset = LOOPBACKOFFSET; break; case DLTSLIP: case DLTPPP: offset = SLIPPPPOFFSET; break; case DLTEN10MB: default: offset = ETHERNETOFFSET; break; } return (offset); }

void * dpspcapnext(pcapt *pd) { void *ptr; struct pcappkthdr hdr;

while ((ptr = (void *)pcap_next(pd, &hdr)) == NULL);

return (ptr);

}

/* EOF */ <-->

|EOF|-------------------------------------------------------------------------|