pwn的学习7 input

pwnable.kr   第七题

PS  哪位大佬能教下我 scp怎么下载pwnable文件啊。。。我想下载就告诉我协议不通过

上传是

scp -P 2222 inputpwn.c [email protected]:/tmp  

那还是先看代码吧。


#include 
#include 
#include 
#include 
#include 

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;
}

 

这个代码是真的长啊。。。还好是分成了5个关卡。。那我就慢慢看嘛。。

先放上大佬的python payload  https://www.cnblogs.com/p4nda/p/7147572.html

from pwn import *
import os
s =  ssh(host='pwnable.kr',user='input2',password='guest',port=2222)
#set_working_directory(wd = '/tmp/')
print s.pwd();
s.write('/tmp/1.txt', "\x00\x0a\x00\xff") 
s.write('/tmp/2.txt',"\x00\x0a\x02\xff")
s.write('/tmp/\x0a',"\x00"*4)
#print hex(s.download_data('/tmp//\x0a'))
arg = list('1'*100)
#print arg[0]
arg[0] = './1'
arg[ord('A')]= "\x00"
arg[ord('B')] = "\x20\x0a\x0d" 
arg[ord('C')] = "7777" 
#print arg
#print len(arg)
dic = {"\xde\xad\xbe\xef":"\xca\xfe\xba\xbe","PWD":"/tmp/"}
#print argnput2/input', '1', '1', '1', '1', '1', '1', '1', '1', '1', '', ' \n\r', '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'])
pro = s.process(argv= arg,cwd="/tmp/",env=dic,executable='/home/input2/input',stdin="/tmp/1.txt",stderr='/tmp/2.txt')
#print pro.recv()

print pro.recv()
#time.sleep(1)
#print pro.recv()
#r = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  
time.sleep(1)
#time.sleep(10)  
#rom =remote("pwnable.kr", 7777)
s.remote("pwnable.kr", 7777)
s.send("\xde\xad\xbe\xef")
print s.recv()
#pro.interactive()
print pro.recv()

首先是第一关

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

也就是说,我们这个argv参数,需要大小为100,并且 A 位置=‘\x00’,B位置为‘’x20\x0a\x0d‘’

对应 

arg[ord('A')]= "\x00"
arg[ord('B')] = "\x20\x0a\x0d" 

然后第二关

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

也就是说

  我们需要从 stdin 里输入\x00\x0a\x00\xff stderr输入 \x00\x0a\x02\xff

所以

 s.write('/tmp/1.txt', "\x00\x0a\x00\xff") 
s.write('/tmp/2.txt',"\x00\x0a\x02\xff")
 

pro = s.process(argv= arg,cwd="/tmp/",env=dic,executable='/home/input2/input',stdin="/tmp/1.txt",stderr='/tmp/2.txt')

不过我在网上看到很多人 用的是管道方法。。

大概意思是  因为子进程有着独立的读写管道

1. 进程调用pipe创建自身的读写管道
2. 调用fork生成子进程并close父进程的写端和子进程的读端建立进程间半双工管道

也就是我读入什么,都和我输出无关

 

第3关

        if(strcmp("\xca\xfe\xba\xbe", getenv("\xde\xad\xbe\xef"))) return 0;
        printf("Stage 3 clear!\n");

就是要设置环境变量。。

dic = {"\xde\xad\xbe\xef":"\xca\xfe\xba\xbe","PWD":"/tmp/"}
#print argnput2/input', '1', '1', '1', '1', '1', '1', '1', '1', '1', '', ' \n\r', '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'])
pro = s.process(argv= arg,cwd="/tmp/",env=dic,executable='/home/input2/input',stdin="/tmp/1.txt",stderr='/tmp/2.txt')

 

第4关
     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");

本关调用fopen打开文件,读取4byte。

s.write('/tmp/\x0a',"\x00"*4)

第5关

 PS 这个因为防火墙机制,所以需要再pwnable服务器跑才可以

程序从argv['C']获取端口绑定并接受4byte,比较成功后get flag

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

#r = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  
time.sleep(1)
s.remote("pwnable.kr", 7777)
s.send("\xde\xad\xbe\xef")

你可能感兴趣的:(python,pwn)