• PWN学习 ---- pwnable ----input


     

     

    源代码:

    #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 ");

    printf("Let's see if you know how to give input to program ");

    printf("Just give me correct inputs then you will get the flag :) ");

     

    // argv

    if(argc != 100) return 0;

    if(strcmp(argv['A'],"x00")) return 0;

    if(strcmp(argv['B'],"x20x0ax0d")) return 0;

    printf("Stage 1 clear! ");

     

    // stdio

    char buf[4];

    read(0, buf, 4);

    if(memcmp(buf, "x00x0ax00xff", 4)) return 0;

    read(2, buf, 4);

            if(memcmp(buf, "x00x0ax02xff", 4)) return 0;

    printf("Stage 2 clear! ");

     

    // env

    if(strcmp("xcaxfexbaxbe", getenv("xdexadxbexef"))) return 0;

    printf("Stage 3 clear! ");

     

    // file

    FILE* fp = fopen("x0a", "r");

    if(!fp) return 0;

    if( fread(buf, 4, 1, fp)!=1 ) return 0;

    if( memcmp(buf, "x00x00x00x00", 4) ) return 0;

    fclose(fp);

    printf("Stage 4 clear! ");

     

    // network

    int sd, cd;

    struct sockaddr_in saddr, caddr;

    sd = socket(AF_INET, SOCK_STREAM, 0);

    if(sd == -1){

    printf("socket error, tell admin ");

    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 ");

         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 ");

    return 0;

    }

    if( recv(cd, buf, 4, 0) != 4 ) return 0;

    if(memcmp(buf, "xdexadxbexef", 4)) return 0;

    printf("Stage 5 clear! ");

     

    // here's your flag

    system("/bin/cat flag");

    return 0;

    }

     

     

    这道题参考了很多网上的wp,网上很多都是用c语言

    写的exp,很少是用python编写的exp

     

    我这里写的exp是用python来编写的,

    主要使用的模块是

    Pwn  socket

     

     

    Exp:

    这个题目总体来说分成几部分

    每个部分都有一个知识点

     

    第一部分: argv

    先判断argc 的参数数量为100

    然后判断第65个参数为 x00

    66 个参数为 x20x0ax0d

    这里的 argv[‘A’] 就是 第65个参数

     

    第二部分: stdin

    这里的知识点是:

    stdoutStandardoutput)标准输出 1  

    stdinStandardinput)标准输入  0

    stderrStandarderror)标准错误 2

    可以看到这里有两个标准

    第一个if 判断 标准输入 为  x00x0ax00xff

    第二个if 判断 标准错误 为  x00x0ax02xff

     

    第三部分:env

    这里的知识点是 环境变量 

    判断 xdexadxbexef 为变量名 内容为 xcaxfexbaxbe

     

    第四部分:file

    这里的知识点是:文件的内容

    打开一个文件 x0a ,然后读4个字节到buf里面,然后内容是 x00x00x00x00

     

    第五部分:network

    这里的知识点:linux的网络编程

    这里前面的部分都不用管,这是打开一个程序的,相当于是一个服务器

    这里要求输入一个端口,然后接受一段数据,4位数 ,然后内容是 xdexadxbexef

    这里在 agrc 里面输入了端口,然后就会自动打开一个端口,生成一个进程

    这里可以用socket连接,然后发送数据

    这里我使用socket连接,不用pwntools,因为我用pwntools 的时候会出现了EOF错误,不知道是什么原因

     

    过了这一步,然后就到了读取flag

    但是这里inputs这个文件夹没有权限写文件,然后exp要放在/tmp 文件夹里面,所以这里要先生成一个软连接,然后就可以读取了

     

    这里总结一下我学这个遇到的点

    Pwntools 如果要指定executable ,那么必须要用argv

    Pwntools process 可以指定参数 stdin    stderr   env

    然后发送过去,输入返回值

     

    然后socket  连接

    如果连接成功了,是没有其他信息输出的,要再一次 print s.recv() 才回输入Stage 5 clear!

    在下面再一次  print s.recv() 得到flag

  • 相关阅读:
    Thread+Handler 线程 消息循环(转载)
    android开发之Fragment加载到一个Activity中
    Android应用程序框架之无边界设计意图
    windows系统下安装MySQL
    Java 性能优化技巧集锦
    功能完善的Java连接池调用实例
    Unicode 与 UTF 字符标准
    java内存配置
    Java Map 简介
    nginx 学习笔记(9) 配置HTTPS服务器--转载
  • 原文地址:https://www.cnblogs.com/nienie/p/9723873.html
Copyright © 2020-2023  润新知