This walk-through will guide you through building a challenge binary.
All challenge binaries should derive from the service template found in on the
CGC VM at /usr/share/cgc-cb/templates/service-template
. Begin by making a copy
of this directory.
$ cp -r /usr/share/cgc-sample-challenges/templates/service-template/ /vagrant/my-cb
$ cd /vagrant/my-cb
The Makefile
included in the service-template is already configured to work properly within the CGC development virtual machine. The only changes that are required in the Makefile
are to edit the first three lines to replace the AUTHOR_ID
, SERVICE_ID
, and TCP_PORT
with values specific to your new binary. For example
AUTHOR_ID = LUNGE
SERVICE_ID = 00001
TCP_PORT = 10000
might become
AUTHOR_ID = DDTEK
SERVICE_ID = 00005
TCP_PORT = 31336
Adding source files
The Makefile is pre-configured to compile all .c files found in both the src and lib sub directories. These directories are also added to the include file path to locate any .h header files that are part of the challenge binary. The recommended division of files is to place boiler plate code such as system call wrappers and standard library functions into the lib directory and files that implement service specific behaviors, including any vulnerabilities, into the src directory.
PATCHED_ macros
Authors must facilitate creation of both a vulnerable and patched version of the
CB. The distinction between the vulnerable and not vulnerable version is
identified by one or more instances of a preprocessor directive
#ifdef PATCHED_<n>
where the <n>
is the PoV number (beginning with 1),
followed by an optional #else
and #endif
. The purpose of this
differentiation is to allow the visualization framework to automatically
distinguish between PoVs. Patched CBs must be not be vulnerable to
associated PoVs.
The Make process will create both an unpatched, vulnerable binary and a patched,
secure binary from a single set of source files. When building the patched,
secure CB, the PATCHED_<n>
macros will be defined. When building the
vulnerable, for-release CB, the PATCHED_<n>
macros will not be defined. CB
authors must test if the PATCHED_<n>
macros are defined to determine which
code should be included in a given build. Simple examples of the use of these
macros are shown here
#ifdef PATCHED_1
fgets(buf, sizeof(buf), stdin);
#endif
#ifndef PATCHED_1
gets(buf);
#endif
#ifdef PATCHED_2
//perform some checks that ensure a vulnerability can not be triggered below
#endif
Service Pollers
All challenge binaries must include a service poller generator specification
designed to exercise the normal functionality of the challenge binary. Pollers
must be designated as "for-release" (poller/for-release
directory) for CFE
there is no "for-testing" distinction. Note that both the unpatched and patched
challenge binary must pass all provided service polls.
A poll generator must be capable of generating at least 1,000,000 unique service polls. All service polls must conform to replay.dtd. NOTE: replay.dtd
differs from cfe-pov.dtd
primarily in that cfe-pov.dtd
requires a negotiate element and supports submitting Type 2 PoV results.
Proofs of Vulnerability
All challenge binaries must include at least one proof of vulnerability (PoV) for each vulnerability contained in the CB. Each PoV must demonstrate that a Type 1 or Type 2 vulnerability may be triggered in a deterministic manner. If a CB contains more than one injected flaw, then PoVs that trigger each flaw must be provided.
XML PoVs conforming to to cfe-pov.dtd must be placed in the pov subdirectory. Source code for binary PoVs must be placed in pov_<n>
directories (numbered from n = 1
). Refer to submitting-a-cb.md for PoV naming conventions.
Building the challenge binaries
The default (all) target in the Makefile
will cause the build
, test
, and package
targets to be built. The build
target will compile and link both a patched and an unpatched version of the CB, placing the bin
directory (which is created if missing). The test
target will invoke the cb-replay
utility once for each service poller and once for each pov. In order to successfully build the test
target, the patched and unpatched binaries must successfully pass all service polls, the unpatched CB must generate a core file when replayed with each pov, and the patched binary must not generate a core file when replayed with each pov. Additionally, the test
target will cause network traffic to be captured for a replay of any poller in the for-release directory. All generated pcap
files will be placed into a pcap
directory (which is created if missing).
The provided Makefile
is properly configured to utilize the CGC specific tool chain. CGC tool chain items intended to be specifically used with CBs can be found in standard cross-build locations for i386-linux-cgc
. Specifically:
/usr/i386-linux-cgc/bin/
/usr/bin/i386-linux-cgc-*
When wishing to use these tools, you must specify the full path to the tool, use the 'long name' for the specific tool in /usr/bin
, or prepend the /usr/i386-linux-cgc/bin
directory to your path. For instance, objdump
can be used in these ways.
The full path for either location of objdump
:
$ /usr/bin/i386-linux-cgc-objdump -f bin/DDTEK_00005
$ /usr/i386-linux-cgc/bin/objdump -f bin/DDTEK_00005
Using the 'long name' which, because it is in /usr/bin
, is already in PATH
:
$ i386-linux-cgc-objdump -f bin/DDTEK_00005
Prepending the location of the i386-linux-cgc
tools to PATH
:
$ which objdump
/usr/bin/objdump
$ PATH=/usr/i386-linux-cgc/bin:$PATH
$ which objdump
/usr/i386-linux-cgc/bin/objdump
$ objdump -f bin/DDTEK_00005
SEE ALSO
For information regarding the testing a CB, see testing-a-cb.md
For information regarding the debugging a CB, see debugging-a-cb.md
For information regarding submitting a CB, see submitting-a-cb.md
For information regarding automated generation of polls, see understanding-poll-generators.md
For information regarding using the cb-server, see man cb-server(1)