第一题就花了好久……
首先,获得密码的链接不是ssl。我开始想用命令行来完成,即用netcat。查了下可以通过fifo来交互:
$ rm -f /tmp/f; mkfifo /tmp/f $ cat /tmp/f | /bin/sh -i 2>&1 | nc -l 127.0.0.1 1234 > /tmp/f
但问题是怎样取出4个数字相加。我对shell还是不熟,试了半天都没好。
根据题目提示,要用socket编程。于是有下面的代码:
#include <sys/socket.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netdb.h>
#include <string.h>
#include <stdlib.h>
int main (int argc, char *argv[]) {
if(argc != 3) {
printf("usage: %s <dest> <port>\n", argv[0]);
exit(1);
}
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in servAddr;
struct hostent *he = gethostbyname(argv[1]);
servAddr.sin_family = AF_INET;
servAddr.sin_port = htons((uint16_t)atoi(argv[2]));
servAddr.sin_addr = *((struct in_addr *)he->h_addr);
bzero(&(servAddr.sin_zero), 8);
if(connect(sockfd, (struct sockaddr *)&servAddr, sizeof(struct sockaddr)) == -1) {
printf("connect error\n");
exit(1);
}
char buf[128];
ssize_t numRead;
unsigned int sum = 0;
ssize_t totalRead = 0;
ssize_t i;
while(totalRead < 16) {
if((numRead=recv(sockfd, buf+totalRead, sizeof(buf)-totalRead, 0))==-1) {
printf("error recv\n");
exit(1);
}
printf("read %u bytes\n", numRead);
totalRead += numRead;
}
unsigned int *number = buf;
for(i=0; i<4; ++i) {
printf("get 0x%x\n", number[i]);
sum += number[i];
}
printf("send 0x%x\n", sum);
send(sockfd, &sum, sizeof sum, 0);
numRead = recv(sockfd, buf, sizeof buf, 0);
buf[numRead] = 0;
printf("received %s\n", buf);
close(sockfd);
return 0;
}
实际上对方在发送4个整数时,似乎是分两次发的,先发一个,再发3个……于是就一直读直到读了16bytes。 得到密码