.\" $Id: signed.man,v 1.2 2012/02/24 20:31:50 ksb Exp $ .\" by Kevin Braunsdorf .\" $Compile: Display%h .\" $Display: ${groff:-groff} -Tascii -man %f | ${PAGER:-less} .\" $Display(*): ${groff:-groff} -T%s -man %f .\" $Install: %b -mDeinstall %o %f && cp %f $DESTDIR/usr/local/man/man7/signed.7 .\" $Deinstall: ${rm-rm} -f $DESTDIR/usr/local/man/[cm]a[nt]7/signed.7* .TH SIGNED 7 LOCAL .SH NAME signed - check a proposed escalation program against a known signature .SH SYNOPSIS .ds PN "signed \fI\*(PN\fP [\fB\-P\fP\~\fIpid\fP] [\fB\-C\fP\~config] [\fB\-f\fP\~\fIfile\fP] [\fB\-g\fP\~\fIgroup\fP] [\fB\-R\fP\~\fIroot\fP] [\fB\-u\fP\~\fIuser\fP] \fImnemonic\fP \fIprogram\fP \fIeuid\fP:\fIegid\fP \fIcred_type\fP:\fIcred\fP .br \fI\*(PN\fP \fB\-h\fP|\fB\-H\fP .br \fI\*(PN\fP \fB\-V\fP .SH DESCRIPTION This helmet is intended to force a review of new applications and their supporting startup scripts. It does this by assessing the output from a shell command applied to the proposed escalated program. The command is assumed to run some checksum, hash, or other consistency check against the program file. The escalation fails when any of these commands \fBexit\fP(3)s non-zero, or the output of a command fails to produce the expected output. .P By recording a hash of the file in the \fBop\fP(1) configuration file we are trying to detect unauthorized updates to the application (or start script), or both. This assumes that the unauthorized updates do not include \fBaccess.cf\fP (or the like). .SH OPTIONS This program takes all the \fBop\fP provided options, but actually doesn't look at any of them (other than \fB\-P\fP, and the program path). It does sanity check them, just the same. .SH ENVIRONMENT Like any helmet, most of the configuration is passed from \fBop\fP via the environment. .TP .nf \fBSIGNED_CMD_\fP\fIcmd\fP=\fIsignatures\fP .fi The shell command \fIcmd\fP is executed with the path to the proposed file appended. The output must match the \fIsignature\fP text with the exception that leading a trailing white-space on each line is ignored, and all internal white-space is changed to a single space. .TP .nf \fBSIGNED_FILTER_\fP\fIcmd\fP=\fIsignatures\fP .fi The shell command \fIcmd\fP is executed with the proposed file open as \fIstdin\fP. The output must match the \fIsignature\fP text as above. .TP .nf \fBSIGNED_WARN\fP=\fIsorry\fP .fi The warning message to replace the common "Sorry" denial message. .TP .nf \fBSIGNED_REVEAL\fP=\fIprefix\fP .fi The standard reveal logic, see \fBop-jacket\fP(7). .P All of these are deleted from each \fIcmd\fP's environment: \fB$IFS\fP, \fB$CDPATH\fP, \fB$ENV\fP, \fB$BASH_ENV\fP to prevent \fBperl\fP(1) from refusing to run any commands. There is no way in this jacket to set them. Code an adapter script to call the correct checksum application while installing the necessary environment. .SH EXAMPLES These are example from the command-line: .TP .nf /usr/local/libexec/jacket/signed \-V .fi Output the version of the program. .TP .nf /usr/local/libexec/jacket/signed \-H .fi Output a summary of the environment expected. .P All of these are snips from the \fBop\fP \fIaccess.cf\fP file. Note that you \fBmust\fP allow any referenced environment variables into the escalated environment, and it is a really good idea to include a \fB$PATH\fP. .sp .PD 0 .TP .nf jacket=/usr/local/libexec/jacket/signed .fi .TP .nf $SIGNED_CMD_size=text$.data$.bss$.dec$.hex$.filename$.21959$.552$.360$.22871$.5957$./bin/ls .fi Check that the program is \fBls\fP, and has the same text, data, and bss segment sizes as it did when the admin last looked at it. Any patch to the binary is quite likely to change at least one of these. .sp .TP .nf jacket=/usr/local/libexec/jacket/signed .fi .TP .nf $SIGNED_FILTER_cksum=1453696711$\es24868 .fi What ever program is proposed must match the given CRC checksum and file size. .sp .TP .nf jacket=/usr/local/libexec/jacket/signed .fi Just check that the file exists, via \fBstat\fP(2). No other check is implied. .PD .SH NOTES To build the output for a program, just run it with a filter that compresses the white-space into quoted spaces for \fBop\fP on the end. Here is an example filter: .RS .nf tr \-s ' \et' ' ' |sed \-e 's/^ //' \-e 's/ $//' \-e 's/ /$./g' .fi .RE Then copy each line into the configuration as an envrionment assignment to the correct variable, separated with \fB$.\fP to represent line-breaks. See the \fB$SIGNED_CMD_size\fP example above. Note that \fBop\fP also expands \*(lq\fB$\es\fP\*(rq to a space, which is a little longer to spell than \*(lq\fB$.\fP\*(rq. (However \fB$.\fP changes meanings in the command specifcation, we use it with care.) .P It might look like \fBls\fP(1) would be an obvious choice to use, but the date output format changes base on elapsed time. So use that with care. .SH BUGS This jacket trusts that the \fBop\fP configuration won't allow a malicious shell command through the environment filter. Any configuration that calls a helmet or jacket requires great care, but great power always comes with great responsibility. .\" thanks Spiderman .P Sometimes a small script may be required to force options to the check \fIcmd\fP. It would be clever to allow some character to stand-in for a space, but it would also be a problem because we'd have to be able to quote it as well. Just code an adapter script -- you can simplify the output as well (to just a number or string). .SH AUTHOR K S Braunsdorf, from the Non-Player Character Guild .br op at-not-a-spammer ksb dot npcguild.org.nopinks .SH "SEE ALSO" .hlm 0 op(1l), op-jacket(7l), stampctl(8l), getpeereid(3), hostname(1), size(1), cksum(1), dgst(1), md5(1)