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;
}
}