Saturday, November 3, 2007

Password Cracker

Password Cracker
Do you know these hacking movies where they push some buttons, then the evil hacker script window turns up and a percentage bar is showing how far the password cracking has gone?

0%....10%....20%....30%....40%....50%....60%....70%....80%....90%....100% password cracked!

Ever wanted to do it yourself? Here is your chance.

This level implements a weakness in the authentication scheme used by M$ win95 and win98 for the netbios shares.

There is a TCP daemon on brebera port 24019. It authenticates your password.
Once you send the correct password, it echoes it back.
Well, let the source speak for itself.

#define _GNU_SOURCE
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

#define LISTENPORT 24019
#define REALPWD "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
#define OLDPWD "XXXXXXXXXXXXXXXX"
#define DROPUID 1998
#define DROPGID 1998

struct query
{
unsigned char oldpass[20+1];
unsigned char pass[100+1];
unsigned int len;
} qry;

struct response
{
unsigned int result;
unsigned char pass[100+1];
} rsp;

int main(int argc, char *argv[])
{
int listenfd, connfd;
struct sockaddr_in localaddr;
struct sockaddr_in remoteaddr;
int sin_size;
int port=LISTENPORT;

setresgid(DROPGID, DROPGID, DROPGID);
setresuid(DROPUID, DROPUID, DROPUID);
signal(SIGPIPE, SIG_IGN);
daemon(0,0);
if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("socket");
exit(EXIT_FAILURE);
}

localaddr.sin_family = AF_INET;
localaddr.sin_port = htons(port);
localaddr.sin_addr.s_addr = INADDR_ANY;
bzero(&(localaddr.sin_zero), 8);
if (bind(listenfd, (struct sockaddr *)&localaddr, sizeof(struct sockaddr)) == -1)
{
perror("bind");
exit(EXIT_FAILURE);
}

if (listen(listenfd, 20) == -1)
{
perror("listen");
exit(EXIT_FAILURE);
}

for (;;)
{
sin_size = sizeof(struct sockaddr_in);
if ((connfd = accept(listenfd, (struct sockaddr *)&remoteaddr, &sin_size)) == -1)
{
perror("accept");
continue;
}

// printf("connection from %s\n", inet_ntoa(remoteaddr.sin_addr));

if (!fork()) //child
{
close(listenfd);

for (;;)
{
memset(&qry, 0, sizeof(struct query));
memset(&rsp, 0, sizeof(struct response));

if (recv(connfd, &qry, sizeof(struct query), 0)!=sizeof(struct query))
{
perror("recv");
close(connfd);
exit(EXIT_FAILURE);
}

if (strncmp(qry.oldpass, OLDPWD, strlen(OLDPWD)))
{
close(connfd);
exit(EXIT_FAILURE);
}

// validate
if (!strncmp(qry.pass, REALPWD, qry.len))
rsp.result=1;

if (rsp.result && (qry.len==strlen(REALPWD)))
strcpy(rsp.pass, REALPWD);

// printf("-> result=%s\n", rsp.result?"CORRECT":"WRONG");
if (send(connfd, &rsp, sizeof(struct response), 0)!=sizeof(struct response))
{
perror("send");
close(connfd);
exit(EXIT_FAILURE);
}
}
}

while(waitpid(-1,NULL,WNOHANG) > 0);

close(connfd);
}

}