This tool acts as a man-in-the-middle for binaries run directly or through
e.g. inetd
.
Configuration of the tool is "baked in" in the sense that a single binary is produced for a given configuration. Build with
make CONFIG=myconfig.inl
This will produce a file called inliner
. This is your bespoke wrapper copy it
somewhere (e.g. myservice-inliner
) and run it as you service.
A configuration file contains a collection of options, filters and environment
variables. Comments start on #
and run to the end of the line.
An option has the form:
set <option> <value>
If <value>
is a relative path, it will be relative to the inliner-binary.
If you need to write binary data, use \xYZ
, e.g match to match a C-string use:
/[^\x00]+/
Currently the supported options are:
The target binary. Must be set.
An optional logfile. The log
-action writes to this file (see below).
Register an alarm signal. In seconds.
Whether to put data onto the network one byte or a full buffer at a time. If this option is set TCP_NODELAY will be set on the output socket and data will be written one byte at a time. Otherwise no extra socket options are set, and data is written in chunks of up to 4096 bytes. Be aware that filters who hold on to bytes may change how many bytes are put onto the network at a time. If no filters are defined the inliner is equivalent to an input/output pump with at 4K buffer.
Whether to kill the process if the input file descriptor is closed (i.e. the
client calls shutdown(fd, SHUT_WR)
).
Switch to given user id.
Switch to given group id. Drop all secondary groups.
Set rlimit_nproc
(see setrlimit(2)
).
Set rlimit_cpu
(see setrlimit(2)
).
Wait for new input/output this amount of microseconds before forcing filters to release bytes.
Whether to randomize file descriptors. Works by dup(2)
'ing /dev/zero
to all
file descriptors, then close(2)
'ing some at random.
If random_fds
is set then this is the amount of file descriptors to
close(2)
, making them available to the wrapped program.
An environment variable has the form:
env <var> <value>
Multiple definitions of the environment variable LD_PRELOAD
are allowed. The
result will be to set LD_PRELOAD
to the concatenation all the definitions,
separated by :
. E.g. this:
env LD_PRELOAD foo.so
env LD_PRELOAD bar.so
is equivalent to this:
env LD_PRELOAD foo.so:bar.so
If <value>
is a relative path, it will be relative to the inliner-binary.
A filter has the form:
(i|o): /<regex>/
<action>
...
<action>
The /
's around <regex>
can be replaced by any character, with the exception
that if (
, {
or [
is used on the left then )
, }
or ]
should be used
on the right respectively.
An action is one of:
Kill the child but keep reading (and immediately forgetting) input. Never send output. Hopefully this will throw somebody's exploit off and waste their time.
Kill the process. No output will be sent.
Flush input/output buffers. Filters will be forced to release all bytes immediately. If no argument is given both input and output buffers will be flushed.
Replace the part of the stream that was matched by the filter's <regex>
with
<replacement>
. The format of <group>
is \x
where x
is an integer. The
given subgroup of the <regex>
will be replaced. Subgroups may be referred to
in <replacement>
with \x
. All filters in the same direction will be rewound
to the first replaced byte in the buffer, so beware of infinite loops. This
will loop:
i: /foo \S+/
patch \0 "foo baz"
but this will not:
i: /foo (\S+)/
patch \1 "baz"
If <replacement>
has the form file <file>
, then the the chosen subgroup
will be replaced with the contents of <file>
.
Call execv
on <program>
thus replacing the inliner. Example usage:
exec ./cat_30min_old_flag.sh
Write <message>
to the log file. If no log file is specified (with set logfile <path>
) this is a no-op. Subgroups of <regex>
may be referred to
with \x
:
o: /cat|dog|bird|giraffe/
log "I saw a \0!"
Send <data>
to the wrapped program. No filters will see <data>
. Subgroups
of <regex>
may be referred to.
Send <data>
to the world. No filters will see <data>
. Subgroups of
<regex>
may be referred to.
Assert that <str>
(which may refer to subgroups of <regex>
) is or is not
present somewhere in <file>
. E.g:
o: /You win: (\S+)/
guard "\1" in flag
kill
or
i: /cmd (\S+)/
guard "\1" not in allowed_commands
hang
A library which prints some stats and then _exit(2)
's can be found in
libstatus/
. It can be build with:
$ make libstatus
It can be loaded with LD_PRELOAD
, and is intended for just checking that
things are working and set up right.
A template config file when setting up a new service is thus:
set target <thetarget>
env LD_PRELOAD libstatus.so
Be aware that libstatus will _exit
, so it should be disabled once it is
confirmed that the service is working.
- Go to
example/
- Type
./run.sh
- Press
<enter>