arp.c
/* arm-linux-gnueabi-gcc -static -march=armv7 -o arp.arm arp.c ; chmod 700 arp.arm ./arp.arm "s" "br0" "/jffs/etc/freeradius/users" "10.0.0.20" "10.0.0.200" gcc -Wall -o arp.xes arp.c ; chmod 700 arp.xes read -p "pwd: " -s p ; echo ; echo "$p" | ./arp.xes "c" "en0" */ #include <arpa/inet.h> #include <netinet/in.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <strings.h> #include <sys/socket.h> #include <time.h> #include <unistd.h> #include "sha256.c" typedef struct userinfo { char *i; unsigned long t, l, a; } infodata; void strp(char *cstr, int clen) { cstr[clen] = '\0'; while ((clen > 0) && ((cstr[clen-1] == '\r') || (cstr[clen-1] == '\n'))) { --clen; } cstr[clen] = '\0'; } void safe(char *cstr) { char *chrs = "0123456789ABCDEFabcdef.:"; int x, y, l = strlen(cstr), m = strlen(chrs), flag; for (x = 0; x < l; ++x) { flag = 0; for (y = 0; y < m; ++y) { if (chrs[y] == cstr[x]) { flag = 1; } } if (flag == 0) { cstr[x] = '0'; } } } unsigned long ipvf(char *addr) { unsigned long i = 0; char *p = NULL, *a = strdup(addr), *t = a; while (1) { p = strchr(a, '.'); if (p != NULL) { *p = '\0'; } i = ((i << 8) + atoi(a)); a = (p + 1); if (p == NULL) { break; } } free(t); return i; } int sign(char *pmsg, int size, unsigned long pres, char *skey) { int x; char hash[SHA256_LENGTH*4]; unsigned char hout[SHA256_LENGTH]; SHA256_CTX hobj; snprintf(&(pmsg[strlen(pmsg)]), (size / 4) * sizeof(char), " %ld %s", pres, skey); SHA256_INIT(&hobj); SHA256_UPDATE(&hobj, (unsigned char *)pmsg, strlen(pmsg)); SHA256_FINAL(&hobj, hout); for (x = 0; x < SHA256_LENGTH; ++x) { sprintf(&(hash[x*2]), "%02x", hout[x]); } hash[SHA256_LENGTH*2] = '\0'; char *rptr = strrchr(pmsg, ' '); ++rptr; strcpy(rptr, hash); rptr[SHA256_LENGTH*2] = '\0'; return 0; } int vrfy(char *pmsg, int size, char *skey, char *sign, unsigned long rate, unsigned long pres, unsigned long last) { int x; char hash[SHA256_LENGTH*4]; unsigned char hout[SHA256_LENGTH]; SHA256_CTX hobj; snprintf(&(pmsg[strlen(pmsg)]), (size / 4) * sizeof(char), " %ld %s", pres, skey); SHA256_INIT(&hobj); SHA256_UPDATE(&hobj, (unsigned char *)pmsg, strlen(pmsg)); SHA256_FINAL(&hobj, hout); for (x = 0; x < SHA256_LENGTH; ++x) { sprintf(&(hash[x*2]), "%02x", hout[x]); } hash[SHA256_LENGTH*2] = '\0'; if (strcmp(hash, sign) != 0) { return -1; } if ((time(NULL) - rate) < 3) { return -1; } if (pres <= last) { return -1; } return 0; } int find(infodata *objs, int l, char *i) { int x; for (x = 0; x < l; ++x) { if (objs[x].i == NULL) { objs[x].i = strdup(i); return x; } if (strcmp(objs[x].i, i) == 0) { return x; } } return -1; } int uniq(infodata *objs, int l, int i, unsigned long a) { int x; for (x = 0; x < l; ++x) { if ((x != i) && (objs[x].a == a)) { return x; } } objs[i].a = a; return -1; } char *gnet(char *intf, char mode) { char *info = "ifconfig '%s' | sed -e 's/HWaddr/ether/g' -e 's/addr://g' -e 's/Bcast:/broadcast /g' | %s > /tmp/arp.net"; char *inet = "grep -i 'inet ' | sed -e 's/^.*inet[ ]*\\([^ ]*\\).*$/\\1/g'"; char *maca = "grep -i 'ether ' | sed -e 's/^.*ether[ ]*\\([^ ]*\\).*$/\\1/g'"; char *brod = "grep -i 'broadcast ' | sed -e 's/^.*broadcast[ ]*\\([^ ]*\\).*$/\\1/g'"; char comd[2048]; FILE *fobj; bzero(comd, 2048 * sizeof(char)); if (mode == 'i') { snprintf(comd, 1024 * sizeof(char), info, intf, inet); } if (mode == 'm') { snprintf(comd, 1024 * sizeof(char), info, intf, maca); } if (mode == 'b') { snprintf(comd, 1024 * sizeof(char), info, intf, brod); } system(comd); fobj = fopen("/tmp/arp.net", "r"); bzero(comd, 2048 * sizeof(char)); fgets(comd, 1024 * sizeof(char), fobj); strp(comd, strlen(comd)); fclose(fobj); return strdup(comd); } void serv(char **args) { /* note: 256 ip address range limit */ int x, y, rlen, sock, bron = 1; unsigned long aadr = ipvf(args[4]), badr = ipvf(args[5]), secs; char *iadr = gnet(args[2], 'i'), *madr = gnet(args[2], 'm'); char pass[2048], mesg[2048], temp[2048], sarp[2048]; infodata last[256]; FILE *fobj; socklen_t slen; struct sockaddr_in sobj, cobj; for (x = 0; x < 256; ++x) { last[x].i = NULL; last[x].a = 0; last[x].t = time(NULL); last[x].l = 0; } sock = socket(AF_INET, SOCK_DGRAM, 0); setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &bron, sizeof(bron)); bzero(&sobj, sizeof(sobj)); sobj.sin_family = AF_INET; sobj.sin_addr.s_addr = htonl(INADDR_ANY); sobj.sin_port = htons(31337); bind(sock, (struct sockaddr *)&sobj, sizeof(sobj)); while (1) { slen = sizeof(cobj); rlen = recvfrom(sock, mesg, 1024 * sizeof(char), 0, (struct sockaddr *)&cobj, &slen); strp(mesg, rlen); char *hptr = strrchr(mesg, ' '); if (hptr == NULL) { continue; } *hptr = '\0'; ++hptr; char *tptr = strrchr(mesg, ' '); if (tptr == NULL) { continue; } *tptr = '\0'; ++tptr; char *mptr = strrchr(mesg, ' '); if (mptr == NULL) { continue; } *mptr = '\0'; ++mptr; char *iptr = mesg; fobj = fopen(args[3], "r"); while (1) { bzero(pass, 2048 * sizeof(char)); if (fgets(pass, 1024 * sizeof(char), fobj) == NULL) { break; } /* note: passwords can not repeat or contain quotes */ if (strstr(pass, "Cleartext-Password") == NULL) { continue; } char *aptr = strchr(pass, '"'); if (aptr == NULL) { continue; } ++aptr; char *bptr = strchr(aptr, '"'); if (bptr == NULL) { continue; } *bptr = '\0'; y = find(last, 256, aptr); if (y < 0) { continue; } bzero(temp, 2048 * sizeof(char)); snprintf(temp, 1024 * sizeof(char), "%s %s", iptr, mptr); secs = atoi(tptr); if (vrfy(temp, 2048, aptr, hptr, last[y].t, secs, last[y].l) == 0) { last[y].t = time(NULL); last[y].l = secs; safe(iptr); safe(mptr); if (uniq(last, 256, y, ipvf(iptr)) < 0) { if ((aadr <= last[y].a) && (last[y].a <= badr)) { bzero(sarp, 2048 * sizeof(char)); snprintf(sarp, 1024 * sizeof(char), "arp -d '%s'", iptr); printf("exec=[%s]\n", sarp); system(sarp); bzero(sarp, 2048 * sizeof(char)); snprintf(sarp, 1024 * sizeof(char), "arp -s '%s' '%s'", iptr, mptr); printf("exec=[%s]\n", sarp); system(sarp); bzero(sarp, 2048 * sizeof(char)); snprintf(sarp, 1024 * sizeof(char), "%s %s", iadr, madr); sign(sarp, 2048, secs + 1, aptr); sendto(sock, sarp, strlen(sarp) * sizeof(char), 0, (struct sockaddr *)&cobj, sizeof(cobj)); printf("sent=[%s]\n", sarp); } else { printf("erro=[range: %ld <= %ld <= %ld]\n", aadr, last[y].a, badr); } } else { printf("erro=[uniq: %ld]\n", ipvf(iptr)); } } else { temp[30] = '\0'; //printf("erro=[vrfy: (%s...) (%s) (%ld) (%ld)]\n", temp, hptr, secs, last[y].l); } } fclose(fobj); } } void ahnd(int sig) { printf("No mesg\n"); } void clnt(char **args) { int sock, bron = 1; unsigned long tips, secs; char pass[2048], mesg[2048], temp[2048], sarp[2048]; socklen_t slen; struct sockaddr_in cobj; //char *brod = "255.255.255.255"; //signal(SIGALRM, ahnd); struct sigaction sact = { .sa_handler = ahnd, .sa_flags = 0 }; sigaction(SIGALRM, &sact, NULL); bzero(pass, 2048 * sizeof(char)); fgets(pass, 1024, stdin); strp(pass, strlen(pass)); while (1) { char *iadr = gnet(args[2], 'i'), *madr = gnet(args[2], 'm'), *badr = gnet(args[2], 'b'); sock = socket(AF_INET, SOCK_DGRAM, 0); setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &bron, sizeof(bron)); cobj.sin_family = AF_INET; cobj.sin_port = htons(31337); inet_aton(badr, (struct in_addr *)&cobj.sin_addr.s_addr); bzero(mesg, 2048 * sizeof(char)); snprintf(mesg, 1024 * sizeof(char), "%s %s", iadr, madr); secs = time(NULL); sign(mesg, 2048, secs, pass); sendto(sock, mesg, strlen(mesg) * sizeof(char), 0, (struct sockaddr*)&cobj, sizeof(cobj)); printf("Sent mesg %s with socket %d to %s\n", mesg, sock, badr); slen = sizeof(cobj); bzero(mesg, 2048 * sizeof(char)); alarm(1); recvfrom(sock, mesg, 1024 * sizeof(char), 0, (struct sockaddr *)&cobj, &slen); alarm(0); strp(mesg, strlen(mesg)); char *hptr = strrchr(mesg, ' '); if (hptr != NULL) { *hptr = '\0'; ++hptr; } char *tptr = strrchr(mesg, ' '); if (tptr != NULL) { *tptr = '\0'; ++tptr; } char *mptr = strrchr(mesg, ' '); char *iptr = mesg; if ((hptr != NULL) && (tptr != NULL) && (mptr != NULL)) { bzero(temp, 2048 * sizeof(char)); strcpy(temp, mesg); tips = atoi(tptr); *mptr = '\0'; ++mptr; if (vrfy(temp, 2048, pass, hptr, time(NULL) - 5, tips, secs) == 0) { safe(iptr); safe(mptr); bzero(sarp, 2048 * sizeof(char)); snprintf(sarp, 1024 * sizeof(char), "arp -d '%s'", iptr); printf("exec=[%s]\n", sarp); system(sarp); bzero(sarp, 2048 * sizeof(char)); snprintf(sarp, 1024 * sizeof(char), "arp -s '%s' '%s'", iptr, mptr); printf("exec=[%s]\n", sarp); system(sarp); } else { temp[30] = '\0'; //printf("erro=[vrfy: (%s...) (%s) (%s) (%ld) (%ld)]\n", temp, pass, hptr, tips, secs); } } close(sock); //break; sleep(5); } } int main(int argc, char **argv) { if (strcmp(argv[1], "s") == 0) { serv(argv); } if (strcmp(argv[1], "c") == 0) { clnt(argv); } return 0; }
sha256.c
#define SHA256_LENGTH 32 #define uchar unsigned char // 8-bit byte #define uint unsigned int // 32-bit word // DBL_INT_ADD treats two unsigned ints a and b as one 64-bit integer and adds c to it #define DBL_INT_ADD(a,b,c) if (a > 0xffffffff - (c)) ++b; a += c; #define ROTLEFT(a,b) (((a) << (b)) | ((a) >> (32-(b)))) #define ROTRIGHT(a,b) (((a) >> (b)) | ((a) << (32-(b)))) #define CH(x,y,z) (((x) & (y)) ^ (~(x) & (z))) #define MAJ(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) #define EP0(x) (ROTRIGHT(x,2) ^ ROTRIGHT(x,13) ^ ROTRIGHT(x,22)) #define EP1(x) (ROTRIGHT(x,6) ^ ROTRIGHT(x,11) ^ ROTRIGHT(x,25)) #define SIG0(x) (ROTRIGHT(x,7) ^ ROTRIGHT(x,18) ^ ((x) >> 3)) #define SIG1(x) (ROTRIGHT(x,17) ^ ROTRIGHT(x,19) ^ ((x) >> 10)) typedef struct { uchar data[64]; uint datalen; uint bitlen[2]; uint state[8]; } SHA256_CTX; uint k[64] = { 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5, 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174, 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da, 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967, 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85, 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070, 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3, 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 }; void SHA256_TRANSFORM(SHA256_CTX *ctx, uchar data[]) { uint a,b,c,d,e,f,g,h,i,j,t1,t2,m[64]; for (i=0,j=0; i < 16; ++i, j += 4) m[i] = (data[j] << 24) | (data[j+1] << 16) | (data[j+2] << 8) | (data[j+3]); for ( ; i < 64; ++i) m[i] = SIG1(m[i-2]) + m[i-7] + SIG0(m[i-15]) + m[i-16]; a = ctx->state[0]; b = ctx->state[1]; c = ctx->state[2]; d = ctx->state[3]; e = ctx->state[4]; f = ctx->state[5]; g = ctx->state[6]; h = ctx->state[7]; for (i = 0; i < 64; ++i) { t1 = h + EP1(e) + CH(e,f,g) + k[i] + m[i]; t2 = EP0(a) + MAJ(a,b,c); h = g; g = f; f = e; e = d + t1; d = c; c = b; b = a; a = t1 + t2; } ctx->state[0] += a; ctx->state[1] += b; ctx->state[2] += c; ctx->state[3] += d; ctx->state[4] += e; ctx->state[5] += f; ctx->state[6] += g; ctx->state[7] += h; } void SHA256_INIT(SHA256_CTX *ctx) { ctx->datalen = 0; ctx->bitlen[0] = 0; ctx->bitlen[1] = 0; ctx->state[0] = 0x6a09e667; ctx->state[1] = 0xbb67ae85; ctx->state[2] = 0x3c6ef372; ctx->state[3] = 0xa54ff53a; ctx->state[4] = 0x510e527f; ctx->state[5] = 0x9b05688c; ctx->state[6] = 0x1f83d9ab; ctx->state[7] = 0x5be0cd19; } void SHA256_UPDATE(SHA256_CTX *ctx, uchar data[], uint len) { uint i; for (i=0; i < len; ++i) { ctx->data[ctx->datalen] = data[i]; ctx->datalen++; if (ctx->datalen == 64) { SHA256_TRANSFORM(ctx,ctx->data); DBL_INT_ADD(ctx->bitlen[0],ctx->bitlen[1],512); ctx->datalen = 0; } } } void SHA256_FINAL(SHA256_CTX *ctx, uchar hash[]) { uint i; i = ctx->datalen; // Pad whatever data is left in the buffer. if (ctx->datalen < 56) { ctx->data[i++] = 0x80; while (i < 56) ctx->data[i++] = 0x00; } else { ctx->data[i++] = 0x80; while (i < 64) ctx->data[i++] = 0x00; SHA256_TRANSFORM(ctx,ctx->data); memset(ctx->data,0,56); } // Append to the padding the total message's length in bits and transform. DBL_INT_ADD(ctx->bitlen[0],ctx->bitlen[1],ctx->datalen * 8); ctx->data[63] = ctx->bitlen[0]; ctx->data[62] = ctx->bitlen[0] >> 8; ctx->data[61] = ctx->bitlen[0] >> 16; ctx->data[60] = ctx->bitlen[0] >> 24; ctx->data[59] = ctx->bitlen[1]; ctx->data[58] = ctx->bitlen[1] >> 8; ctx->data[57] = ctx->bitlen[1] >> 16; ctx->data[56] = ctx->bitlen[1] >> 24; SHA256_TRANSFORM(ctx,ctx->data); // Since this implementation uses little endian byte ordering and SHA uses big endian, // reverse all the bytes when copying the final state to the output hash. for (i=0; i < 4; ++i) { hash[i] = (ctx->state[0] >> (24-i*8)) & 0x000000ff; hash[i+4] = (ctx->state[1] >> (24-i*8)) & 0x000000ff; hash[i+8] = (ctx->state[2] >> (24-i*8)) & 0x000000ff; hash[i+12] = (ctx->state[3] >> (24-i*8)) & 0x000000ff; hash[i+16] = (ctx->state[4] >> (24-i*8)) & 0x000000ff; hash[i+20] = (ctx->state[5] >> (24-i*8)) & 0x000000ff; hash[i+24] = (ctx->state[6] >> (24-i*8)) & 0x000000ff; hash[i+28] = (ctx->state[7] >> (24-i*8)) & 0x000000ff; } }