Fuzzing related changes
This commit is contained in:
parent
46c56b75e2
commit
ec29ee610d
11 changed files with 149 additions and 36 deletions
21
Makefile
21
Makefile
|
@ -10,6 +10,12 @@ ifeq ($(shell uname -s),Linux)
|
||||||
LIBS += $(shell pkg-config libnl-route-3.0 --libs)
|
LIBS += $(shell pkg-config libnl-route-3.0 --libs)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(shell uname -s),Darwin)
|
||||||
|
AFL=afl-clang
|
||||||
|
else
|
||||||
|
AFL=afl-gcc
|
||||||
|
endif
|
||||||
|
|
||||||
nmrpflash_OBJ = nmrp.o tftp.o ethsock.o main.o util.o
|
nmrpflash_OBJ = nmrp.o tftp.o ethsock.o main.o util.o
|
||||||
|
|
||||||
.PHONY: clean install release release/macos release/linux release/win32
|
.PHONY: clean install release release/macos release/linux release/win32
|
||||||
|
@ -23,17 +29,20 @@ tftptest:
|
||||||
%.o: %.c nmrpd.h
|
%.o: %.c nmrpd.h
|
||||||
$(CC) -c $(CFLAGS) $< -o $@
|
$(CC) -c $(CFLAGS) $< -o $@
|
||||||
|
|
||||||
fuzz: clean
|
fuzz_nmrp: tftp.c util.c nmrp.c fuzz.c
|
||||||
CC=afl-gcc CFLAGS=-DNMRPFLASH_FUZZ make nmrpflash
|
$(AFL) $(CFLAGS) -DNMRPFLASH_FUZZ $^ -o $@
|
||||||
mv nmrpflash fuzz
|
|
||||||
|
|
||||||
dofuzz: fuzz
|
fuzz_tftp: tftp.c util.c nmrp.c fuzz.c
|
||||||
|
$(AFL) $(CFLAGS) -DNMRPFLASH_FUZZ -DNMRPFLASH_FUZZ_TFTP $^ -o $@
|
||||||
|
|
||||||
|
dofuzz_tftp: fuzz
|
||||||
echo core | sudo tee /proc/sys/kernel/core_pattern
|
echo core | sudo tee /proc/sys/kernel/core_pattern
|
||||||
echo performance | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
|
echo performance | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
|
||||||
afl-fuzz -i fuzzin -o fuzzout -- ./fuzz
|
afl-fuzz -i fuzzin/nmrp -o fuzzout/nmrp -- ./fuzz_tftp
|
||||||
echo powersave | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
|
echo powersave | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f $(nmrpflash_OBJ) nmrpflash
|
rm -f $(nmrpflash_OBJ) nmrpflash fuzz_nmrp fuzz_tftp
|
||||||
|
|
||||||
install: nmrpflash
|
install: nmrpflash
|
||||||
install -m 755 nmrpflash $(PREFIX)/bin
|
install -m 755 nmrpflash $(PREFIX)/bin
|
||||||
|
|
28
ethsock.c
28
ethsock.c
|
@ -80,14 +80,6 @@ struct ethsock_ip_undo
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *mac_to_str(uint8_t *mac)
|
|
||||||
{
|
|
||||||
static char buf[18];
|
|
||||||
snprintf(buf, sizeof(buf), "%02x:%02x:%02x:%02x:%02x:%02x",
|
|
||||||
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int x_pcap_findalldevs(pcap_if_t **devs)
|
static int x_pcap_findalldevs(pcap_if_t **devs)
|
||||||
{
|
{
|
||||||
char errbuf[PCAP_ERRBUF_SIZE];
|
char errbuf[PCAP_ERRBUF_SIZE];
|
||||||
|
@ -631,26 +623,6 @@ cleanup:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int select_fd(int fd, unsigned timeout)
|
|
||||||
{
|
|
||||||
struct timeval tv;
|
|
||||||
int status;
|
|
||||||
fd_set fds;
|
|
||||||
|
|
||||||
FD_ZERO(&fds);
|
|
||||||
FD_SET(fd, &fds);
|
|
||||||
|
|
||||||
tv.tv_sec = timeout / 1000;
|
|
||||||
tv.tv_usec = 1000 * (timeout % 1000);
|
|
||||||
|
|
||||||
status = select(fd + 1, &fds, NULL, NULL, &tv);
|
|
||||||
if (status < 0) {
|
|
||||||
sock_perror("select");
|
|
||||||
}
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
ssize_t ethsock_recv(struct ethsock *sock, void *buf, size_t len)
|
ssize_t ethsock_recv(struct ethsock *sock, void *buf, size_t len)
|
||||||
{
|
{
|
||||||
struct pcap_pkthdr* hdr;
|
struct pcap_pkthdr* hdr;
|
||||||
|
|
23
fuzz.c
Normal file
23
fuzz.c
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#include "nmrpd.h"
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
struct nmrpd_args args = {
|
||||||
|
.rx_timeout = 60,
|
||||||
|
.ul_timeout = 60,
|
||||||
|
.ipmask = "255.255.255.0",
|
||||||
|
.mac = "ff:ff:ff:ff:ff:ff",
|
||||||
|
.op = NMRP_UPLOAD_FW,
|
||||||
|
.port = 69,
|
||||||
|
};
|
||||||
|
#ifdef NMRPFLASH_FUZZ_TFTP
|
||||||
|
if (argc != 2) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
args.file_local = argv[1];
|
||||||
|
|
||||||
|
return tftp_put(&args);
|
||||||
|
#else
|
||||||
|
return nmrp_do(&args);
|
||||||
|
#endif
|
||||||
|
}
|
BIN
fuzzin/tftp.bin
Normal file
BIN
fuzzin/tftp.bin
Normal file
Binary file not shown.
BIN
fuzzin/tftp/fsize_4096_blksize_1k.bin
Normal file
BIN
fuzzin/tftp/fsize_4096_blksize_1k.bin
Normal file
Binary file not shown.
BIN
fuzzin/tftp/fsize_4096_default.bin
Normal file
BIN
fuzzin/tftp/fsize_4096_default.bin
Normal file
Binary file not shown.
2
main.c
2
main.c
|
@ -23,8 +23,6 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "nmrpd.h"
|
#include "nmrpd.h"
|
||||||
|
|
||||||
int verbosity = 0;
|
|
||||||
|
|
||||||
void usage(FILE *fp)
|
void usage(FILE *fp)
|
||||||
{
|
{
|
||||||
fprintf(fp,
|
fprintf(fp,
|
||||||
|
|
65
mkfuzz.c
Normal file
65
mkfuzz.c
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
enum tftp_opcode {
|
||||||
|
RRQ = 1,
|
||||||
|
WRQ = 2,
|
||||||
|
DATA = 3,
|
||||||
|
ACK = 4,
|
||||||
|
ERR = 5,
|
||||||
|
OACK = 6
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline char *pkt_mknum(char *pkt, uint16_t n)
|
||||||
|
{
|
||||||
|
*(uint16_t*)pkt = htons(n);
|
||||||
|
return pkt + 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *pkt_mkopt(char *pkt, const char *opt, const char* val)
|
||||||
|
{
|
||||||
|
strcpy(pkt, opt);
|
||||||
|
pkt += strlen(opt) + 1;
|
||||||
|
strcpy(pkt, val);
|
||||||
|
pkt += strlen(val) + 1;
|
||||||
|
return pkt;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
if (argc != 2) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t fsize = 4096;
|
||||||
|
|
||||||
|
char pkt[1024];
|
||||||
|
char* p;
|
||||||
|
size_t len = 512;
|
||||||
|
|
||||||
|
memset(pkt, 0, sizeof(pkt));
|
||||||
|
|
||||||
|
if (argc == 2 && argv[1][0] == 'k') {
|
||||||
|
len = 1024;
|
||||||
|
|
||||||
|
p = pkt_mknum(pkt, OACK);
|
||||||
|
pkt_mkopt(p, "blksize", "1024");
|
||||||
|
} else {
|
||||||
|
p = pkt_mknum(pkt, ACK);
|
||||||
|
pkt_mknum(p, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
write(STDOUT_FILENO, pkt, 512);
|
||||||
|
|
||||||
|
size_t i = 0;
|
||||||
|
|
||||||
|
for (; i < fsize/len; ++i) {
|
||||||
|
memset(pkt, 0, len);
|
||||||
|
p = pkt_mknum(pkt, ACK);
|
||||||
|
pkt_mknum(p, i + 1);
|
||||||
|
write(STDOUT_FILENO, pkt, len);
|
||||||
|
}
|
||||||
|
}
|
1
nmrp.c
1
nmrp.c
|
@ -240,6 +240,7 @@ static void msg_mkconfack(struct nmrp_msg *msg, uint32_t ipaddr, uint32_t ipmask
|
||||||
#define ethsock_ip_add(a, b, c, d) (0)
|
#define ethsock_ip_add(a, b, c, d) (0)
|
||||||
#define ethsock_ip_del(a, b) (0)
|
#define ethsock_ip_del(a, b) (0)
|
||||||
#define ethsock_close(a) (0)
|
#define ethsock_close(a) (0)
|
||||||
|
#define ethsock_for_each_ip(a, b, c) (1)
|
||||||
#define tftp_put(a) (0)
|
#define tftp_put(a) (0)
|
||||||
|
|
||||||
static uint8_t *ethsock_get_hwaddr_fake(struct ethsock* sock)
|
static uint8_t *ethsock_get_hwaddr_fake(struct ethsock* sock)
|
||||||
|
|
16
tftp.c
16
tftp.c
|
@ -193,12 +193,20 @@ static ssize_t tftp_recvfrom(int sock, char *pkt, uint16_t* port,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef NMRPFLASH_FUZZ
|
||||||
alen = sizeof(src);
|
alen = sizeof(src);
|
||||||
len = recvfrom(sock, pkt, pktlen, 0, (struct sockaddr*)&src, &alen);
|
len = recvfrom(sock, pkt, pktlen, 0, (struct sockaddr*)&src, &alen);
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
sock_perror("recvfrom");
|
sock_perror("recvfrom");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
len = read(sock, pkt, pktlen);
|
||||||
|
if (len < 0) {
|
||||||
|
perror("read");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
*port = ntohs(src.sin_port);
|
*port = ntohs(src.sin_port);
|
||||||
|
|
||||||
|
@ -263,10 +271,14 @@ static ssize_t tftp_sendto(int sock, char *pkt, size_t len,
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef NMRPFLASH_FUZZ
|
||||||
sent = sendto(sock, pkt, len, 0, (struct sockaddr*)dst, sizeof(*dst));
|
sent = sendto(sock, pkt, len, 0, (struct sockaddr*)dst, sizeof(*dst));
|
||||||
if (sent < 0) {
|
if (sent < 0) {
|
||||||
sock_perror("sendto");
|
sock_perror("sendto");
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
sent = len;
|
||||||
|
#endif
|
||||||
|
|
||||||
return sent;
|
return sent;
|
||||||
}
|
}
|
||||||
|
@ -340,12 +352,16 @@ int tftp_put(struct nmrpd_args *args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef NMRPFLASH_FUZZ_TFTP
|
||||||
sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
if (sock < 0) {
|
if (sock < 0) {
|
||||||
sock_perror("socket");
|
sock_perror("socket");
|
||||||
ret = sock;
|
ret = sock;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
sock = STDIN_FILENO;
|
||||||
|
#endif
|
||||||
|
|
||||||
memset(&addr, 0, sizeof(addr));
|
memset(&addr, 0, sizeof(addr));
|
||||||
|
|
||||||
|
|
29
util.c
29
util.c
|
@ -28,6 +28,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
volatile sig_atomic_t g_interrupted = 0;
|
volatile sig_atomic_t g_interrupted = 0;
|
||||||
|
int verbosity = 0;
|
||||||
|
|
||||||
time_t time_monotonic()
|
time_t time_monotonic()
|
||||||
{
|
{
|
||||||
|
@ -58,6 +59,14 @@ char *lltostr(long long ll, int base)
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *mac_to_str(uint8_t *mac)
|
||||||
|
{
|
||||||
|
static char buf[18];
|
||||||
|
snprintf(buf, sizeof(buf), "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||||
|
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t bitcount(uint32_t n)
|
uint32_t bitcount(uint32_t n)
|
||||||
{
|
{
|
||||||
uint32_t c;
|
uint32_t c;
|
||||||
|
@ -72,6 +81,26 @@ uint32_t netmask(uint32_t count)
|
||||||
return htonl(count <= 32 ? 0xffffffff << (32 - count) : 0);
|
return htonl(count <= 32 ? 0xffffffff << (32 - count) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int select_fd(int fd, unsigned timeout)
|
||||||
|
{
|
||||||
|
struct timeval tv;
|
||||||
|
int status;
|
||||||
|
fd_set fds;
|
||||||
|
|
||||||
|
FD_ZERO(&fds);
|
||||||
|
FD_SET(fd, &fds);
|
||||||
|
|
||||||
|
tv.tv_sec = timeout / 1000;
|
||||||
|
tv.tv_usec = 1000 * (timeout % 1000);
|
||||||
|
|
||||||
|
status = select(fd + 1, &fds, NULL, NULL, &tv);
|
||||||
|
if (status < 0) {
|
||||||
|
sock_perror("select");
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
void xperror(const char *msg)
|
void xperror(const char *msg)
|
||||||
{
|
{
|
||||||
if (errno != EINTR) {
|
if (errno != EINTR) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue