pwnable.kr input

作者: CodeRambler | 来源:发表于2019-05-28 23:30 被阅读0次

    下载题目

    sudo scp -P 2222 input2@pwnable.kr:~/* ./
    

    查看源码

    $ cat input.c
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/socket.h>
    #include <arpa/inet.h>
    
    int main(int argc, char* argv[], char* envp[]){
        printf("Welcome to pwnable.kr\n");
        printf("Let's see if you know how to give input to program\n");
        printf("Just give me correct inputs then you will get the flag :)\n");
    
        // argv
        if(argc != 100) return 0;
        if(strcmp(argv['A'],"\x00")) return 0;
        if(strcmp(argv['B'],"\x20\x0a\x0d")) return 0;
        printf("Stage 1 clear!\n"); 
    
        // stdio
        char buf[4];
        read(0, buf, 4);
        if(memcmp(buf, "\x00\x0a\x00\xff", 4)) return 0;
        read(2, buf, 4);
            if(memcmp(buf, "\x00\x0a\x02\xff", 4)) return 0;
        printf("Stage 2 clear!\n");
        
        // env
        if(strcmp("\xca\xfe\xba\xbe", getenv("\xde\xad\xbe\xef"))) return 0;
        printf("Stage 3 clear!\n");
    
        // file
        FILE* fp = fopen("\x0a", "r");
        if(!fp) return 0;
        if( fread(buf, 4, 1, fp)!=1 ) return 0;
        if( memcmp(buf, "\x00\x00\x00\x00", 4) ) return 0;
        fclose(fp);
        printf("Stage 4 clear!\n"); 
    
        // network
        int sd, cd;
        struct sockaddr_in saddr, caddr;
        sd = socket(AF_INET, SOCK_STREAM, 0);
        if(sd == -1){
            printf("socket error, tell admin\n");
            return 0;
        }
        saddr.sin_family = AF_INET;
        saddr.sin_addr.s_addr = INADDR_ANY;
        saddr.sin_port = htons( atoi(argv['C']) );
        if(bind(sd, (struct sockaddr*)&saddr, sizeof(saddr)) < 0){
            printf("bind error, use another port\n");
                return 1;
        }
        listen(sd, 1);
        int c = sizeof(struct sockaddr_in);
        cd = accept(sd, (struct sockaddr *)&caddr, (socklen_t*)&c);
        if(cd < 0){
            printf("accept error, tell admin\n");
            return 0;
        }
        if( recv(cd, buf, 4, 0) != 4 ) return 0;
        if(memcmp(buf, "\xde\xad\xbe\xef", 4)) return 0;
        printf("Stage 5 clear!\n");
    
        // here's your flag
        system("/bin/cat flag");    
        return 0;
    }
    

    一步一步的深入

    知识储备:

    1. argc、argv、envp
      argc: 参数的个数,如 ping www.baidu.com 的 argc = 2;
      argv: 具体的参数,如 pingwww.baidu.com;
      envp: 环境变量数组
    2. execve
      函数定义:int execve(const char *filename, char *const argv[ ], char *const envp[ ]);
      返回值:函数执行成功时返回0,执行失败时的返回值为-1.
      函数说明:execve()用来执行参数filename字符串所代表的文件路径,第二个参数是利用数组指针来传递给执行文件,并且需要以空指针(NULL)结束,最后一个参数则为传递给执行文件的新环境变量数组。

    stage 1

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/socket.h>
    #include <arpa/inet.h>
    
    int main()
    {
        /* Stage 1: argv */
        char *argv[101] = {"./input", [1 ... 99] = "A", NULL};
    
        argv['A'] = "\x00";
        argv['B'] = "\x20\x0a\x0d";
    
        execve("./input", argv, NULL);
    
        return 0;
    }
    

    编译执行一下:

    $ gcc writeup.c -o writeup
    $ ./writeup
    Welcome to pwnable.kr
    Let's see if you know how to give input to program
    Just give me correct inputs then you will get the flag :)
    Stage 1 clear!
    

    相关文章

      网友评论

        本文标题:pwnable.kr input

        本文链接:https://www.haomeiwen.com/subject/orjstctx.html