代码如下
#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;
}
好吧,这道题考的是linux编程,神烦……
没有太多要说的,socket那块,开始parent没有sleep
,结果总是Connection refused。于是后来让他先等一会再去连,就好了。
另外,由于我的程序是在/tmp
下面,这里可以写。但到最后读flag内容时,flag并不在当前目录/tmp
下。所以我们需要首先把flag文件链接到这里
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
int main () {
char *argv[101] = {[0 ... 99] = "A"};
argv['A'] = "\x00";
argv['B'] = "\x20\x0a\x0d";
argv['C'] = "55555";
char *envp[2] = {"\xde\xad\xbe\xef=\xca\xfe\xba\xbe"};
int pipe1[2], pipe2[2];
if(pipe(pipe1)==-1 || pipe(pipe2)==-1) {
printf("error pipe\n");
exit(1);
}
FILE *fp = fopen("\x0a", "w");
fwrite("\x00\x00\x00\x00", 4, 1, fp);
fclose(fp);
if(fork() == 0) {
dup2(pipe1[0], 0);
close(pipe1[0]);
close(pipe1[1]);
dup2(pipe2[0], 2);
close(pipe2[0]);
close(pipe2[1]);
execve("/home/input/input", argv, envp);
}
else {
write(pipe1[1], "\x00\x0a\x00\xff", 4);
write(pipe2[1], "\x00\x0a\x02\xff", 4);
sleep(5);
struct sockaddr_in servaddr;
int sock = socket(AF_INET, SOCK_STREAM, 0);
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(atoi(argv['C']));
servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
connect(sock, (struct sockaddr *)&servaddr, sizeof(servaddr));
send(sock, "\xde\xad\xbe\xef", 4, 0);
close(sock);
int stat;
wait(&stat);
unlink("\x0a");
return 0;
}
}