Vortex0

Posted by rk700 on July 8, 2014

第一题就花了好久……

首先,获得密码的链接不是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。 得到密码