junh00🌈

pwnable.kr - Linux IO

还是一道pwnable.kr上的题,总结下涉及到的知识点

ssh input2@pwnable.kr -p2222   #password: guest

第一关是组装参数,需要100个,第’A’'B’'C’个参数需要特别定义

    // argv
    
    char *argv[101];
    argv[0] = "/home/input2/input";

    for(int i = 0; i < 101; i++) {
        argv[i] = "x";
    }
    
    argv['A'] = "\x00";
    argv['B'] = "\x20\x0a\x0d";
    argv['C'] = "55555";

第二关是IO重定向,这里用pipe创建了两个管道,数组中第0个是输出口,第1个是输入口。其中一个输出口重定向到stdin,另一个输出口重定向到stderr。然后通过fork建立一个子进程,在子进程中向输入数据,最终流入stdin和stderr。

    if ((childPid = fork()) <0) { exit(-1); }
    if (childPid == 0) {
        // waiting for parent process ready to read
        sleep(1);

        // close read
        close(pipeStdin[0]);
        close(pipeStderr[0]);

        // write data
        write(pipeStdin[1], "\x00\x0a\x00\xff", 4);
        write(pipeStderr[1], "\x00\x0a\x02\xff", 4);

        return 0;

    } else {
        // close write
        close(pipeStdin[1]);
        close(pipeStderr[1]);

        // redirection output to stdin & stderr
        dup2(pipeStdin[0], 0);
        dup2(pipeStderr[0], 
	}

第三关需要设置环境变量,环境变量都是key=value的格式,所以我们在一个env的数组中,添加两个,一个是对应的value和key,一个是NULL,因为env参数需要一个NULL作为结尾。然后调用execve将env变量传入。

char *envp[2] = {"\xde\xad\xbe\xef=\xca\xfe\xba\xbe", NULL};
execve("/home/input2/input", argv, envp); //这步execve需要放在所有设置都完成后才执行。

第四关是文件读取,这个新建文件,塞入相应的数据即可

	FILE *fp = fopen("\x0a", "wb");
    if (!fp) { exit(-1); }
    fwrite("\x00\x00\x00\x00", 4, 1, fp);
    fclose(fp);
    fp = NULL;

最后是socket编程,题目代码中的意思是用第C个参数,来设置端口,然后监听,并且判断接收到的数据是不是它所需要的,如果正确就打印flag了。我们需要做的是,建立连接,并往这个端口输送相应的数据即可。可以通过python,也可以通过C编程。这里用的是python, 在服务器上运行exploit打开端口之后,我们再执行。最后获得flag。

python -c "print '\xde\xad\xbe\xef' | nc localhost 55555"

另外一个问题是ssh到服务器后因为权限问题,只能在新建的目录里操作,所以需要将原目录的flag文件软链接到自己新建的目录中。

ln -s /home/input2/flag flag