Allow remote network host filtering, courtesy of Corentin Delorme.

This commit is contained in:
Sam Hocevar
2009-08-06 21:17:00 +00:00
committed by sam
parent c586a72c73
commit 8f431fbd83
12 changed files with 295 additions and 43 deletions

View File

@@ -1,10 +1,12 @@
$Id$
main zzuf author:
Sam Hocevar <sam@zoy.org>
Sam Hocevar <sam@hocevar.net>
other contributors:
Rémi Denis-Courmont <rdenis#simphalempin:com> (readv, recvmsg)
Clément Stenac <zorglub#diwi:org> (pread)
Dominik Kuhlen <dominik.kuhlen#gmit-gmbh:de> (recvfrom)
Sami Liedes <sliedes#cc:hut:fi> (LD_PRELOAD conservation)
Corentin Delorme <codelorme@gmail.com> (remote host filtering)

View File

@@ -13,7 +13,8 @@ zzuf_LDFLAGS = $(MATH_LIBS) $(WINSOCK2_LIBS)
zzuf_DEPENDENCIES = libzzuf.la
pkglib_LTLIBRARIES = libzzuf.la
libzzuf_la_SOURCES = libzzuf.c libzzuf.h $(COMMON) debug.c debug.h sys.c sys.h \
libzzuf_la_SOURCES = libzzuf.c libzzuf.h $(COMMON) debug.c debug.h \
sys.c sys.h network.c network.h \
lib-fd.c lib-mem.c lib-signal.c lib-stream.c lib-load.h
libzzuf_la_CFLAGS = -DLIBZZUF
libzzuf_la_LDFLAGS = -avoid-version -no-undefined $(DLL_LDFLAGS)

View File

@@ -1,6 +1,6 @@
/*
* zzuf - general purpose fuzzer
* Copyright (c) 2006-2007 Sam Hocevar <sam@zoy.org>
* Copyright (c) 2006-2009 Sam Hocevar <sam@hocevar.net>
* All Rights Reserved
*
* $Id$
@@ -35,6 +35,7 @@
#include "libzzuf.h"
#include "fd.h"
#include "fuzz.h"
#include "network.h"
#include "ranges.h"
/* Regex stuff */
@@ -43,10 +44,6 @@ static regex_t re_include, re_exclude;
static int has_include = 0, has_exclude = 0;
#endif
/* Network port cherry picking */
static int *ports = NULL;
static int static_ports[512];
/* File descriptor cherry picking */
static int *list = NULL;
static int static_list[512];
@@ -99,11 +96,6 @@ void _zz_exclude(char const *regex)
#endif
}
void _zz_ports(char const *portlist)
{
ports = _zz_allocrange(portlist, static_ports);
}
void _zz_list(char const *fdlist)
{
list = _zz_allocrange(fdlist, static_list);
@@ -199,8 +191,6 @@ void _zz_fd_fini(void)
free(fds);
if(list != static_list)
free(list);
if(ports != static_ports)
free(ports);
}
int _zz_mustwatch(char const *file)
@@ -226,14 +216,6 @@ int _zz_iswatched(int fd)
return 1;
}
int _zz_portwatched(int port)
{
if(!ports)
return 1;
return _zz_isinrange(port, ports);
}
void _zz_register(int fd)
{
int i;

View File

@@ -1,6 +1,6 @@
/*
* zzuf - general purpose fuzzer
* Copyright (c) 2006 Sam Hocevar <sam@zoy.org>
* Copyright (c) 2006-2009 Sam Hocevar <sam@hocevar.net>
* All Rights Reserved
*
* $Id$
@@ -26,7 +26,6 @@ extern void _zz_fd_init(void);
extern void _zz_fd_fini(void);
extern int _zz_mustwatch(char const *);
extern int _zz_portwatched(int);
extern int _zz_iswatched(int);
extern void _zz_register(int);
extern void _zz_unregister(int);

View File

@@ -1,6 +1,6 @@
/*
* zzuf - general purpose fuzzer
* Copyright (c) 2006 Sam Hocevar <sam@zoy.org>
* Copyright (c) 2006-2009 Sam Hocevar <sam@hocevar.net>
* All Rights Reserved
*
* $Id$
@@ -19,7 +19,6 @@
extern void _zz_fuzzing(char const *);
extern void _zz_bytes(char const *);
extern void _zz_list(char const *);
extern void _zz_ports(char const *);
extern void _zz_protect(char const *);
extern void _zz_refuse(char const *);

View File

@@ -1,9 +1,10 @@
/*
* zzuf - general purpose fuzzer
* Copyright (c) 2006, 2007 Sam Hocevar <sam@zoy.org>
* Copyright (c) 2006-2009 Sam Hocevar <sam@hocevar.net>
* 2007 Rémi Denis-Courmont <rdenis#simphalempin:com>
* 2007 Clément Stenac <zorglub#diwi:org>
* 2007 Dominik Kuhlen <dominik.kuhlen#gmit-gmbh:de>
* 2009 Corentin Delorme <codelorme@gmail.com>
* All Rights Reserved
*
* $Id$
@@ -351,7 +352,8 @@ RECV_T NEW(recv)(int s, void *buf, size_t len, int flags)
LOADSYM(recv);
ret = ORIG(recv)(s, buf, len, flags);
if(!_zz_ready || !_zz_iswatched(s) || _zz_islocked(s) || !_zz_isactive(s))
if(!_zz_ready || !_zz_iswatched(s) || !_zz_hostwatched(s)
|| _zz_islocked(s) || !_zz_isactive(s))
return ret;
if(ret > 0)
@@ -384,7 +386,8 @@ RECV_T NEW(recvfrom)(int s, void *buf, size_t len, int flags,
LOADSYM(recvfrom);
ret = ORIG(recvfrom)(s, buf, len, flags, from, fromlen);
if(!_zz_ready || !_zz_iswatched(s) || _zz_islocked(s) || !_zz_isactive(s))
if(!_zz_ready || !_zz_iswatched(s) || !_zz_hostwatched(s)
|| _zz_islocked(s) || !_zz_isactive(s))
return ret;
if(ret > 0)
@@ -424,7 +427,8 @@ RECV_T NEW(recvmsg)(int s, struct msghdr *hdr, int flags)
LOADSYM(recvmsg);
ret = ORIG(recvmsg)(s, hdr, flags);
if(!_zz_ready || !_zz_iswatched(s) || _zz_islocked(s) || !_zz_isactive(s))
if(!_zz_ready || !_zz_iswatched(s) || !_zz_hostwatched(s)
|| _zz_islocked(s) || !_zz_isactive(s))
return ret;
fuzz_iovec(s, hdr->msg_iov, ret);
@@ -444,8 +448,8 @@ int NEW(read)(int fd, void *buf, unsigned int count)
LOADSYM(read);
ret = ORIG(read)(fd, buf, count);
if(!_zz_ready || !_zz_iswatched(fd) || _zz_islocked(fd)
|| !_zz_isactive(fd))
if(!_zz_ready || !_zz_iswatched(fd) || !_zz_hostwatched(fd)
|| _zz_islocked(fd) || !_zz_isactive(fd))
return ret;
if(ret > 0)

View File

@@ -1,6 +1,6 @@
/*
* zzuf - general purpose fuzzer
* Copyright (c) 2006 Sam Hocevar <sam@zoy.org>
* Copyright (c) 2006-2009 Sam Hocevar <sam@hocevar.net>
* All Rights Reserved
*
* $Id$
@@ -44,6 +44,7 @@
#include "libzzuf.h"
#include "debug.h"
#include "fd.h"
#include "network.h"
#include "sys.h"
#include "fuzz.h"
@@ -140,6 +141,14 @@ void _zz_init(void)
if(tmp && *tmp)
_zz_ports(tmp);
tmp = getenv("ZZUF_ALLOW");
if(tmp && *tmp)
_zz_allow(tmp);
tmp = getenv("ZZUF_DENY");
if(tmp && *tmp)
_zz_deny(tmp);
tmp = getenv("ZZUF_PROTECT");
if(tmp && *tmp)
_zz_protect(tmp);
@@ -169,6 +178,7 @@ void _zz_init(void)
_zz_network = 1;
_zz_fd_init();
_zz_network_init();
_zz_sys_init();
tmp = getenv("ZZUF_STDIN");
@@ -188,6 +198,7 @@ void _zz_init(void)
void _zz_fini(void)
{
_zz_fd_fini();
_zz_network_fini();
}
#if defined HAVE_WINDOWS_H

195
src/network.c Normal file
View File

@@ -0,0 +1,195 @@
/*
* zzuf - general purpose fuzzer
* Copyright (c) 2006-2009 Sam Hocevar <sam@hocevar.net>
* All Rights Reserved
*
* $Id$
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/
/*
* network.c: network connection helper functions
*/
#include "config.h"
#if defined HAVE_STDINT_H
# include <stdint.h>
#elif defined HAVE_INTTYPES_H
# include <inttypes.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "libzzuf.h"
#include "debug.h"
#include "ranges.h"
#include "network.h"
static unsigned int get_socket_ip(int);
static int host_in_list(unsigned int, unsigned int const *);
static unsigned int *create_host_list(char const *, unsigned int *);
/* Network IP cherry picking */
static unsigned int *allow = NULL;
static unsigned int static_allow[512];
static unsigned int *deny = NULL;
static unsigned int static_deny[512];
/* Network port cherry picking */
static int *ports = NULL;
static int static_ports[512];
void _zz_network_init(void)
{
;
}
void _zz_network_fini(void)
{
if(ports != static_ports)
free(ports);
if(allow != static_allow)
free(allow);
if(deny != static_deny)
free(deny);
}
void _zz_allow(char const *allowlist)
{
allow = create_host_list(allowlist, static_allow);
}
void _zz_deny(char const *denylist)
{
deny = create_host_list(denylist, static_deny);
}
void _zz_ports(char const *portlist)
{
ports = _zz_allocrange(portlist, static_ports);
}
int _zz_portwatched(int port)
{
if(!ports)
return 1;
return _zz_isinrange(port, ports);
}
int _zz_hostwatched(int sock)
{
int watch = 1;
unsigned int ip;
if(!allow && !deny)
return 1;
ip = get_socket_ip(sock);
if(deny && host_in_list(ip, deny))
watch = 0;
if(allow)
watch = host_in_list(ip, allow);
return watch;
}
/* XXX: the following functions are local */
static unsigned int *create_host_list(char const *list,
unsigned int *static_list)
{
int ret;
char *copy;
char *parser;
struct in_addr addr;
unsigned int i, chunks, len, *iplist;
len = strlen(list);
copy = malloc(len + 1);
if (!copy) {
// TODO better error handling
perror("malloc");
exit(EXIT_FAILURE);
}
strncpy(copy, list, len);
copy[len] = 0;
/* Count commas */
for(parser = copy, chunks = 1; *parser; parser++)
if(*parser == ',')
chunks++;
if(chunks >= 512)
iplist = malloc((chunks + 1) * sizeof(unsigned int));
else
iplist = static_list;
for(parser = copy, i = 0; i < chunks; i++)
{
char *comma = strchr(parser, ',');
if (comma)
*comma = 0;
ret = inet_aton(parser, &addr);
if (ret)
iplist[i] = addr.s_addr;
else {
i--;
chunks--;
debug("create_host_list: Invalid IP address '%s'. Skipping it.", parser);
}
parser = comma + 1;
}
iplist[i] = 0;
free(copy);
return iplist;
}
static int host_in_list(unsigned int value, unsigned int const *list)
{
unsigned int i;
if (!value || !list)
return 0;
for (i = 0; list[i]; i++)
if (value == list[i])
return 1;
return 0;
}
static unsigned int get_socket_ip(int sock)
{
int ret;
struct sockaddr_in sin;
socklen_t len = sizeof(sin);
// Probably not a socket descriptor
if (sock < 3)
return 0;
memset(&sin, 0, sizeof(sin));
ret = getsockname(sock, &sin, &len);
if (ret) {
// TODO error handling
return 0;
}
return sin.sin_addr.s_addr;
}

28
src/network.h Normal file
View File

@@ -0,0 +1,28 @@
/*
* zzuf - general purpose fuzzer
* Copyright (c) 2006-2009 Sam Hocevar <sam@hocevar.net>
* 2009 Corentin Delorme <codelorme@gmail.com>
* All Rights Reserved
*
* $Id$
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/
/*
* network.h: network connection helper functions
*/
extern void _zz_ports(char const *);
extern void _zz_allow(char const *);
extern void _zz_deny(char const *);
extern void _zz_network_init(void);
extern void _zz_network_fini(void);
extern int _zz_portwatched(int);
extern int _zz_hostwatched(int);

View File

@@ -1,6 +1,6 @@
/*
* zzuf - general purpose fuzzer
* Copyright (c) 2002, 2007 Sam Hocevar <sam@zoy.org>
* Copyright (c) 2002, 2007-2009 Sam Hocevar <sam@hocevar.net>
* All Rights Reserved
*
* $Id$
@@ -34,6 +34,7 @@
void _zz_opts_init(struct opts *opts)
{
opts->fuzzing = opts->bytes = opts->list = opts->ports = NULL;
opts->allow = opts->deny = NULL;
opts->protect = opts->refuse = NULL;
opts->seed = DEFAULT_SEED;
opts->endseed = DEFAULT_SEED + 1;

View File

@@ -1,6 +1,6 @@
/*
* zzuf - general purpose fuzzer
* Copyright (c) 2002, 2007 Sam Hocevar <sam@zoy.org>
* Copyright (c) 2002, 2007-2009 Sam Hocevar <sam@hocevar.net>
* All Rights Reserved
*
* $Id$
@@ -20,7 +20,7 @@ struct opts
{
char **oldargv;
char **newargv;
char *fuzzing, *bytes, *list, *ports, *protect, *refuse;
char *fuzzing, *bytes, *list, *ports, *protect, *refuse, *allow, *deny;
uint32_t seed;
uint32_t endseed;
double minratio;

View File

@@ -1,6 +1,6 @@
/*
* zzuf - general purpose fuzzer
* Copyright (c) 2002, 2007 Sam Hocevar <sam@zoy.org>
* Copyright (c) 2002, 2007-2009 Sam Hocevar <sam@hocevar.net>
* All Rights Reserved
*
* $Id$
@@ -175,12 +175,13 @@ int main(int argc, char *argv[])
# define OPTSTR_RLIMIT_CPU ""
#endif
#define OPTSTR "+" OPTSTR_REGEX OPTSTR_RLIMIT_MEM OPTSTR_RLIMIT_CPU \
"Ab:B:C:dD:f:F:ij:l:mnp:P:qr:R:s:St:vxhV"
"a:Ab:B:C:dD:e:f:F:ij:l:mnp:P:qr:R:s:St:vxhV"
#define MOREINFO "Try `%s --help' for more information.\n"
int option_index = 0;
static struct myoption long_options[] =
{
/* Long option, needs arg, flag, short option */
{ "allow", 1, NULL, 'a' },
{ "autoinc", 0, NULL, 'A' },
{ "bytes", 1, NULL, 'b' },
{ "max-bytes", 1, NULL, 'B' },
@@ -190,6 +191,7 @@ int main(int argc, char *argv[])
{ "max-crashes", 1, NULL, 'C' },
{ "debug", 0, NULL, 'd' },
{ "delay", 1, NULL, 'D' },
{ "deny", 1, NULL, 'e' },
#if defined HAVE_REGEX_H
{ "exclude", 1, NULL, 'E' },
#endif
@@ -225,6 +227,9 @@ int main(int argc, char *argv[])
switch(c)
{
case 'a': /* --allow */
opts->allow = myoptarg;
break;
case 'A': /* --autoinc */
setenv("ZZUF_AUTOINC", "1", 1);
break;
@@ -256,6 +261,9 @@ int main(int argc, char *argv[])
myoptarg++;
opts->delay = (int64_t)(atof(myoptarg) * 1000000.0);
break;
case 'e': /* --deny */
opts->deny = myoptarg;
break;
#if defined HAVE_REGEX_H
case 'E': /* --exclude */
exclude = merge_regex(exclude, myoptarg);
@@ -386,6 +394,24 @@ int main(int argc, char *argv[])
return EXIT_FAILURE;
}
if (opts->allow && !network)
{
fprintf(stderr, "%s: allow option (-a) requires network fuzzing (-n)\n",
argv[0]);
printf(MOREINFO, argv[0]);
_zz_opts_fini(opts);
return EXIT_FAILURE;
}
if (opts->deny && !network)
{
fprintf(stderr, "%s: deny option (-e) requires network fuzzing (-n)\n",
argv[0]);
printf(MOREINFO, argv[0]);
_zz_opts_fini(opts);
return EXIT_FAILURE;
}
_zz_setratio(opts->minratio, opts->maxratio);
_zz_setseed(opts->seed);
@@ -444,6 +470,10 @@ int main(int argc, char *argv[])
setenv("ZZUF_LIST", opts->list, 1);
if(opts->ports)
setenv("ZZUF_PORTS", opts->ports, 1);
if(opts->allow)
setenv("ZZUF_ALLOW", opts->allow, 1);
if(opts->deny)
setenv("ZZUF_DENY", opts->deny, 1);
if(opts->protect)
setenv("ZZUF_PROTECT", opts->protect, 1);
if(opts->refuse)
@@ -499,8 +529,6 @@ static void loop_stdin(struct opts *opts)
_zz_bytes(opts->bytes);
if(opts->list)
_zz_list(opts->list);
if(opts->ports)
_zz_ports(opts->ports);
if(opts->protect)
_zz_protect(opts->protect);
if(opts->refuse)
@@ -1182,13 +1210,13 @@ static void *get_entry(char const *name)
static void version(void)
{
printf("zzuf %s\n", PACKAGE_VERSION);
printf("Copyright (C) 2002, 2007-2008 Sam Hocevar <sam@zoy.org>\n");
printf("Copyright (C) 2002, 2007-2009 Sam Hocevar <sam@hocevar.net>\n");
printf("This program is free software. It comes without any warranty, to the extent\n");
printf("permitted by applicable law. You can redistribute it and/or modify it under\n");
printf("the terms of the Do What The Fuck You Want To Public License, Version 2, as\n");
printf("published by Sam Hocevar. See <http://sam.zoy.org/wtfpl/> for more details.\n");
printf("\n");
printf("Written by Sam Hocevar. Report bugs to <sam@zoy.org>.\n");
printf("Written by Sam Hocevar. Report bugs to <sam@hocevar.net>.\n");
}
static void usage(void)
@@ -1218,6 +1246,7 @@ static void usage(void)
printf("Run PROGRAM with optional arguments ARGS and fuzz its input.\n");
printf("\n");
printf("Mandatory arguments to long options are mandatory for short options too.\n");
printf(" -a, --allow <list> only fuzz network input for IPs in <list>\n");
printf(" -A, --autoinc increment seed each time a new file is opened\n");
printf(" -b, --bytes <ranges> only fuzz bytes at offsets within <ranges>\n");
printf(" -B, --max-bytes <n> kill children that output more than <n> bytes\n");
@@ -1227,6 +1256,7 @@ static void usage(void)
printf(" -C, --max-crashes <n> stop after <n> children have crashed (default 1)\n");
printf(" -d, --debug print debug messages\n");
printf(" -D, --delay delay between forks\n");
printf(" -e, --deny <list> do not fuzz network input for IPs in <list>\n");
#if defined HAVE_REGEX_H
printf(" -E, --exclude <regex> do not fuzz files matching <regex>\n");
#endif
@@ -1258,6 +1288,6 @@ static void usage(void)
printf(" -h, --help display this help and exit\n");
printf(" -V, --version output version information and exit\n");
printf("\n");
printf("Written by Sam Hocevar. Report bugs to <sam@zoy.org>.\n");
printf("Written by Sam Hocevar. Report bugs to <sam@hocevar.net>.\n");
}