网站建设资讯

NEWS

网站建设资讯

Protostarnet3

This level is at /opt/protostar/bin/net3

Source code

#include "../common/common.c"

#define NAME "net3"
#define UID 996
#define GID 996
#define PORT 2996

/*
* Extract a null terminated string from the buffer
*/

int get_string(char **result, unsigned char *buffer, u_int16_t len)
{
unsigned char byte;

byte = *buffer;

if(byte > len) errx(1, "badly formed packet");
*result = malloc(byte);
strcpy(*result, buffer + 1);

return byte + 1;
}

/*
* Check to see if we can log into the host
*/

int login(unsigned char *buffer, u_int16_t len)
{
char *resource, *username, *password;
int deduct;
int success;

if(len < 3) errx(1, "invalid login packet length");

resource = username = password = NULL;

deduct = get_string(&resource, buffer, len);
deduct += get_string(&username, buffer+deduct, len-deduct);
deduct += get_string(&password, buffer+deduct, len-deduct);

success = 0;
success |= strcmp(resource, "net3");
success |= strcmp(username, "awesomesauce");
success |= strcmp(password, "password");

free(resource);
free(username);
free(password);

return ! success;
}

void send_string(int fd, unsigned char byte, char *string)
{
struct iovec v[3];
u_int16_t len;
int expected;

len = ntohs(1 + strlen(string));

v[0].iov_base = &len;
v[0].iov_len = sizeof(len);

v[1].iov_base = &byte;
v[1].iov_len = 1;

v[2].iov_base = string;
v[2].iov_len = strlen(string);

expected = sizeof(len) + 1 + strlen(string);

if(writev(fd, v, 3) != expected) errx(1, "failed to write correct amount of bytes");

}

void run(int fd)
{
u_int16_t len;
unsigned char *buffer;
int loggedin;

while(1) {
nread(fd, &len, sizeof(len));
len = ntohs(len);
buffer = malloc(len);

if(! buffer) errx(1, "malloc failure for %d bytes", len);

nread(fd, buffer, len);

switch(buffer[0]) {
case 23:
loggedin = login(buffer + 1, len - 1);
send_string(fd, 33, loggedin ? "successful" : "failed");
break;

default:
send_string(fd, 58, "what you talkin about willis?");
break;
}
}
}

int main(int argc, char **argv, char **envp)
{
int fd;
char *username;

/* Run the process as a daemon */
background_process(NAME, UID, GID);

/* Wait for socket activity and return */
fd = serve_forever(PORT);

/* Set the client socket to STDIN, STDOUT, and STDERR */
set_io(fd);

/* Don't do this :> */
srandom(time(NULL));

run(fd);
}

乍一看,好长的代码~~~但是还是得看~~~:-)
程序先读一个长度,这个长度就是待会客户端即将发过来的字符串的长度,第二次读时获取一个字符串,首先先判断第一个字符的值是否为23,是则继续
然后分析get_string()函数,先读第一个字符,也是长度的意思,然后取出该长度的字符保存在那指针里面,如果三次取出的字符分别是net3,awesomesauce,password的话即可success。
以下是代码:

#!/usr/bin/env python


from socket import *
from struct import *
from optparse import OptionParser
import select

def main(hostname,port):
s = socket(AF_INET,SOCK_STREAM)
s.connect((hostname,port))

send_str = ("\x17"
"\x05net3\x00"
"\x0dawesomesauce\x00"
"\x09password\x00")

send_len = len(send_str)
s.send(pack(">H", send_len))
s.send(send_str)

print s.recv(1024)

s.close()


if __name__=="__main__":
parse = OptionParser("usage: %prog [options]")
parse.add_option("-H",dest="hostname",default="127.0.0.1",type="string",help="The ip of the target")
parse.add_option("-P",dest="port",default=2996,type="int",help="The port of the host")

(options,args)=parse.parse_args()

main(options.hostname,options.port)

运行结果:
Protostar net3



文章名称:Protostarnet3
URL标题:http://njwzjz.com/article/gechco.html