试图利用int溢出

时间:2015-07-14 14:11:31

标签: c memory-leaks exploit integer-overflow

以下是我使用的源代码: (完整代码可在此处找到:http://pastebin.com/APFJ4Jyb

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <netinet/in.h>
#include <sys/wait.h>

#define ALARM_TIMEOUT_SEC (1200)
#define PASSWORD_LENGTH   (100)
#define BRUTE_FORCE_TIMEOUT (1)

int is_correct(char * given_password_hex)
{
    char b2h[256] = {
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
         0,  1,  2,  3,  4,  5,  6,  7,  8,  9, -1, -1, -1, -1, -1, -1, /* 0-9 */
        -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* A-F */
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* a-f */
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    };

    char password[50] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN";
    char given_password[50];
    char value1;
    char value2;
    int i;
    char diff = 0;

    size_t given_password_hex_length = strlen(given_password_hex);
    if (PASSWORD_LENGTH != given_password_hex_length) {
        printf("bad input1: %zu\n", given_password_hex_length);
        return 0;
    }

    bzero(given_password, sizeof(given_password));
    for (i = 0; i < sizeof(given_password); i++) {
        // *********here is the place i try to exploit*******
        value1 = b2h[given_password_hex[i * 2]]; 
        value2 = b2h[given_password_hex[i * 2 + 1]];
        printf("%d- %d %X %d - %d %X\n",
                i * 2,
                i * 2+1,given_password_hex[i * 2],
                given_password_hex[i * 2],
                given_password_hex[i * 2 + 1],
                given_password_hex[i * 2 + 1]);
        if (value1 == -1 || value2 == -1) {
            printf("bad input2\n");
            return 0;
        }

        given_password[i] = (value1 << 4) | value2;

        printf("%s\n",given_password);
    }

    printf("%s\n\n\n\n\n\n\n",given_password);
    for (i = 0; i < 50; i++) {
        diff |= (password[i] ^ given_password[i]);
    }
    printf("%s\n",given_password);
    printf("%s",password);
    return (diff == 0);
}


void right_trim(char * str)
{
    char * t = str + strlen(str) - 1;
    char * p;

    for (p = t; p >= str; p--) {
        if (!strchr(" \r\n", *p)) {
        break;
        }

        *p = '\0';
    }
}

void handle(int s)
{
    char inbuf[4096];

    dup2(s, 0);
    dup2(s, 1);

    setbuf(stdout, NULL);

    alarm(ALARM_TIMEOUT_SEC);

    printf("crackme> ");

    if (NULL == fgets(inbuf, sizeof(inbuf), stdin)) {
        return;
    }

    right_trim(inbuf);

    if(is_correct(inbuf)) {
        printf("Good job!\n");
    }
}

void handle_sigchld(int sig) {
    waitpid((pid_t) (-1), 0, WNOHANG);
}

int main(int argc, char * argv[])
{
    printf("we in");
    if (1 == argc) {
        printf("Usage: %s <port>\n", argv[0]);
        printf("section 1");
        exit(-0);
    }

    int port = strtol(argv[1], NULL, 10);
    if (0 == port) {
        printf("section 2");
        perror("Invalid port");
        exit(-1);
    }

    struct sigaction sa;
    sa.sa_handler = &handle_sigchld;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = SA_RESTART | SA_NOCLDSTOP;
    if (sigaction(SIGCHLD, &sa, 0) == -1) {
        perror("Unable to register sigaction");
        exit(-2);
    }

    int s = socket(AF_INET, SOCK_STREAM, 0);
    if (-1 == s) {
        perror("Unable to create server socket");
        exit(-3);
    }

    int optval = 1;
    if (0 != setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))) {
        perror("Unable to setsockopt");
        exit(-4);
    } 

    struct sockaddr_in bind_addr = {
        .sin_family = AF_INET,
        .sin_port = htons(port)
    };

    if (0 != bind(s, (struct sockaddr *) &bind_addr, sizeof(bind_addr))) {
        perror("Unable to bind socket");
        printf("section 3");
        exit(-5);
    }

    if (0 != listen(s, 10)) {
        perror("Unable to listen");
        exit(-6);
    }

    while (1) {
        int s_ = accept(s, NULL, NULL);

        sleep(BRUTE_FORCE_TIMEOUT);

        if (-1 == s_) {
            perror("Unable to accept");
            continue;
        }

        pid_t child_pid = fork();
        if (-1 == child_pid) {
            perror("Unable to fork");
            goto accept_cleanup;
        }

        if (0 == child_pid) {
            close(s);
            handle(s_);
            exit(0);
        }

        accept_cleanup:
        close(s_);
    }

    exit(0);
}

由于我控制输入,我可以调整数组指针的大小,我可以将异常存入内存

现在我的问题: 我想在不知道密码的情况下找到好孩子。 所以,我把以下字符串用来让系统为我从内存中检索密码

 "ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñ" 

即使我在输入中包含正确大小的字符,我也没有得到密码。相反,我得到它的第一部分,然后一切都是混合的。 这是我得到的:

 "0123456789qrstuvwxyz{|}pqrstuvwxyzqrstuvwxyz{|}~" 
(Instead : "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN")

这是密码在运行时在内存中的样子:

0x7fffffffd840: 0x33323130      0x37363534      0x62613938      0x66656463
0x7fffffffd850: 0x6a696867      0x6e6d6c6b      0x7271706f      0x76757473
0x7fffffffd860: 0x7a797877      0x44434241      0x48474645      0x4c4b4a49
0x7fffffffd870: 0x1c934e4d      0x00000000      0x00400643      0x00000000
0x7fffffffd880: 0xffffffff      0x00000000      0x0000c1ff      0x00000405

(注意结束)

这是密码在内存中的位置:

0x7fffffffd840

这是b2h在内存中的位置:

0x7fffffffd8c0

为什么会这样? 我该如何解决这个问题?

0 个答案:

没有答案