mirror of
https://github.com/fdiskyou/Zines.git
synced 2025-03-09 00:00:00 +01:00
1163 lines
31 KiB
Text
1163 lines
31 KiB
Text
![]() |
- 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 ICMP_ECHO_REQUEST/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
|
||
|
CLI_OBJECTS = source/clt_main.o source/clt_packet_injection.o source/clt_wait.o
|
||
|
AGT_OBJECTS = source/agt_main.o source/agt_pscan.o
|
||
|
DPS_OBJECTS = source/dps_helper.o source/dps_pcap.o
|
||
|
|
||
|
.c.o:
|
||
|
$(CC) $(CFLAGS) $(DEFINES) -c $< -o $@
|
||
|
|
||
|
common: $(DPS_OBJECTS)
|
||
|
|
||
|
client: $(CLI_OBJECTS) $(DPS_OBJECTS)
|
||
|
$(CC) $(DPS_OBJECTS) $(CLI_OBJECTS) $(LIBS) -o client
|
||
|
strip client
|
||
|
|
||
|
agent: $(AGT_OBJECTS) $(DPS_OBJECTS)
|
||
|
$(CC) $(DPS_OBJECTS) $(AGT_OBJECTS) $(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 ECHO_REQUEST/ECHO_REPLY 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 MAX_HOST_SIZE 64 /* maximum hostname size allowed */
|
||
|
|
||
|
#define MAX_ICMP_PAYLOAD_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 <pcap.h>
|
||
|
|
||
|
#define LOOPBACK_OFFSET 4
|
||
|
#define ETHERNET_OFFSET 14
|
||
|
#define SLIP_PPP_OFFSET 24
|
||
|
|
||
|
char errbuf[PCAP_ERRBUF_SIZE];
|
||
|
|
||
|
void
|
||
|
dps_pcap_err(
|
||
|
char *,
|
||
|
char *
|
||
|
);
|
||
|
|
||
|
pcap_t *
|
||
|
dps_pcap_prep(
|
||
|
int,
|
||
|
char *,
|
||
|
char *
|
||
|
);
|
||
|
|
||
|
int
|
||
|
dps_pcap_datalink(
|
||
|
pcap_t *
|
||
|
);
|
||
|
|
||
|
void *
|
||
|
dps_pcap_next(
|
||
|
pcap_t *
|
||
|
);
|
||
|
|
||
|
#endif /* DPS_PCAP */
|
||
|
|
||
|
/* EOF */
|
||
|
<-->
|
||
|
<++> p56/dps/include/prototypes.h !f50ce3e5
|
||
|
#include <linux/types.h>
|
||
|
|
||
|
extern char *itoa(int);
|
||
|
|
||
|
struct agentnfo {
|
||
|
u_long address; /* agent's IP address */
|
||
|
u_long 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 {
|
||
|
u_long victim;
|
||
|
u_long cli_addr;
|
||
|
char *ports;
|
||
|
};
|
||
|
|
||
|
struct sp_header {
|
||
|
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 <stdio.h>
|
||
|
#include <string.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <unistd.h>
|
||
|
#include <errno.h>
|
||
|
#include <ctype.h>
|
||
|
#include <strings.h>
|
||
|
|
||
|
#include <arpa/inet.h>
|
||
|
|
||
|
#include <sys/types.h>
|
||
|
#include <sys/stat.h>
|
||
|
|
||
|
#include <netinet/in.h>
|
||
|
#include <netinet/in_systm.h>
|
||
|
#include <netinet/ip_var.h>
|
||
|
#include <netinet/ip.h>
|
||
|
#include <netinet/tcp.h>
|
||
|
|
||
|
#endif /* SOLARIS_H */
|
||
|
|
||
|
/* EOF */
|
||
|
<-->
|
||
|
<++> p56/dps/source/agt_main.c !aaf7e1ae
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
|
||
|
#include <pcap.h>
|
||
|
|
||
|
#include <netinet/in.h>
|
||
|
#include <netinet/ip.h>
|
||
|
#include <netinet/tcp.h>
|
||
|
#include <netinet/ip_icmp.h>
|
||
|
|
||
|
#include <asm/types.h>
|
||
|
|
||
|
#include "../include/config.h"
|
||
|
#include "../include/prototypes.h"
|
||
|
|
||
|
#define SNAPLEN 64
|
||
|
#define ETHHDR 14
|
||
|
|
||
|
void pkt_analyser_func(char *, char *);
|
||
|
|
||
|
/* Global variables */
|
||
|
unsigned int dlink_s;
|
||
|
const u_char *snapend;
|
||
|
|
||
|
int main(int argc, char **argv) {
|
||
|
|
||
|
pkt_analyser_func(argv[1], MAGIC);
|
||
|
|
||
|
}
|
||
|
|
||
|
void pkt_analyser_func(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 <= MAX_ICMP_PAYLOAD_SIZE; 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(u_long));
|
||
|
memcpy(scan + sizeof(u_long), payload + 16, sizeof(u_long));
|
||
|
scan->ports = malloc(strlen(payload + 16 + 2*sizeof(u_long)) + 1);
|
||
|
memset(scan->ports, '\0', strlen(payload + 16 + 2*sizeof(u_long)) + 1);
|
||
|
memcpy(scan->ports, payload + 16 + 2*sizeof(u_long), strlen(payload + 16 + 2*sizeof(u_long)));
|
||
|
pscan(scan, pd, dev);
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
}
|
||
|
<-->
|
||
|
<++> p56/dps/source/agt_pscan.c !6b34db79
|
||
|
#include <libnet.h>
|
||
|
#include <pcap.h>
|
||
|
|
||
|
#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 = (u_char *)pcap_next(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->ihl*4);
|
||
|
if (tcph->th_sport == htons(p) && tcph->th_dport == htons(1030)) {
|
||
|
if ((tcph->th_flags & (TH_SYN|TH_ACK)) == (TH_SYN|TH_ACK)) { send_result(p, scan->cli_addr); }
|
||
|
// if (tcph->th_flags & 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 send_result(int p, u_long 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 <stdio.h>
|
||
|
#include <string.h>
|
||
|
#include <stdlib.h>
|
||
|
#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 <target_host> <ports to scan> <agents file> <device>\n", exec);
|
||
|
exit(1);
|
||
|
}
|
||
|
<-->
|
||
|
<++> p56/dps/source/clt_packet_injection.c !cbbedc0d
|
||
|
#include <libnet.h>
|
||
|
#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 =+ (MAX_ICMP_PAYLOAD_SIZE - 16);
|
||
|
}
|
||
|
else {
|
||
|
head->plus = 0;
|
||
|
memset(pload, '\0', MAX_ICMP_PAYLOAD_SIZE + 1);
|
||
|
memcpy(pload, head, 16);
|
||
|
memcpy(pload + 16, &cli_addr, sizeof(u_long));
|
||
|
memcpy(pload + 16 + sizeof(u_long), &(agent->victim), sizeof(u_long));
|
||
|
memcpy(pload + 16 + 2*sizeof(u_long), agent->ports + offset, strlen(agent->ports));
|
||
|
// memset(pload + 16 + 2*sizeof(u_long) + strlen(agent->ports + offset), 'A', MAX_ICMP_PAYLOAD_SIZE - (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 = libnet_write_ip(sock, buf, ICMP_ECHO_H + IP_H + MAX_ICMP_PAYLOAD_SIZE);
|
||
|
if (c < ICMP_ECHO_H + IP_H + MAX_ICMP_PAYLOAD_SIZE) {
|
||
|
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 <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
|
||
|
#include <pcap.h>
|
||
|
|
||
|
#include <netinet/in.h>
|
||
|
#include <netinet/ip.h>
|
||
|
#include <netinet/tcp.h>
|
||
|
#include <netinet/ip_icmp.h>
|
||
|
|
||
|
#include <asm/types.h>
|
||
|
|
||
|
#include "../include/config.h"
|
||
|
#include "../include/prototypes.h"
|
||
|
|
||
|
#define SNAPLEN 64
|
||
|
#define ETHHDR 14
|
||
|
|
||
|
|
||
|
/* Global variables */
|
||
|
unsigned int dlink_s;
|
||
|
const u_char *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
|
||
|
dps_pcap_err(char *function, char *error)
|
||
|
{
|
||
|
fprintf(stderr, "%s: %s\n", function, error);
|
||
|
exit (1);
|
||
|
}
|
||
|
|
||
|
pcap_t *
|
||
|
dps_pcap_prep(int snaplen, char *filter, char *device)
|
||
|
{
|
||
|
pcap_t *pd;
|
||
|
bpf_u_int32 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
|
||
|
dps_pcap_datalink(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 DLT_NULL:
|
||
|
offset = LOOPBACK_OFFSET;
|
||
|
break;
|
||
|
case DLT_SLIP:
|
||
|
case DLT_PPP:
|
||
|
offset = SLIP_PPP_OFFSET;
|
||
|
break;
|
||
|
case DLT_EN10MB:
|
||
|
default:
|
||
|
offset = ETHERNET_OFFSET;
|
||
|
break;
|
||
|
}
|
||
|
return (offset);
|
||
|
}
|
||
|
|
||
|
void *
|
||
|
dps_pcap_next(pcap_t *pd)
|
||
|
{
|
||
|
void *ptr;
|
||
|
struct pcap_pkthdr hdr;
|
||
|
|
||
|
while ((ptr = (void *)pcap_next(pd, &hdr)) == NULL);
|
||
|
|
||
|
return (ptr);
|
||
|
}
|
||
|
|
||
|
/* EOF */
|
||
|
<-->
|
||
|
|
||
|
|
||
|
|EOF|-------------------------------------------------------------------------|
|
||
|
|