#!/bin/sh ## ## this should be rewritten in perl, now that we're depending on perl ## to get data out of dams. and maybe (gasp) dams should use dams.pm! ## DAMSDIR=`dirname $0` A0=`basename $0` WORKDIR=${TMPDIR:-/tmp}/$A0.tmp.$$ TEMPLATE=$DAMSDIR/$A0.template MODEL=any-binary KEEP=false usage () { echo >&2 "usage: $A0 [-k] [-d workdir] [-m model] file1 file2 [...]" } while getopts hkd:m: c; do case "$c" in h) usage; exit 2;; k) KEEP=true;; d) WORKDIR="$OPTARG"; KEEP=true;; m) MODEL=$OPTARG;; \?) usage; exit 4;; esac done shift `expr $OPTIND - 1` if [ ! -d "${WORKDIR}/." ]; then mkdir "${WORKDIR}" 2>/dev/null || { echo >&2 "$A0: cannot create work directory" exit 10 } fi BOUNDARY= for f in "$@"; do base=`basename $f` ## extract the executable content into a tmp dir $DAMSDIR/dams2 -o $WORKDIR/bin.$base -i $f check -- $MODEL >/dev/null ## Remove the elements that were decoded into something else. ## This should leave only executable code, if it's present. if [ -f "$WORKDIR/bin.$base,b64,zip" ]; then rm "$WORKDIR/bin.$base,b64" "$WORKDIR/bin.$base" elif [ -f "$WORKDIR/bin.$base,b64" ]; then rm "$WORKDIR/bin.$base" fi # append boundary data to BOUNDARY tmp=`$DAMSDIR/dams2 -i $f dump | perl -e 'undef $/; $m = eval(); print $m->{mime}->{boundary};'` # (the newline is important) BOUNDARY="${BOUNDARY}boundary=> '$tmp',@NL@" # really we should examine the MIME and figure out the parts[] # array, but that's vaguely complicated and I'm short on time. # We'll leave this to user discretion for now. done unset LANG LC_ALL LC_CTYPE mask -o "$WORKDIR/mask" "$WORKDIR"/bin.* DATE=`date +%Y-%m-%d` DATELONG=`date` cat "${TEMPLATE}" \ | sed -e "s!@LOGNAME@!$LOGNAME!g" \ -e "s!@DATE@!$DATE!g" \ -e "s!@DATELONG@!$DATELONG!g" \ -e "s!@A0@!$A0!g" \ -e "s!@BOUNDARY@!$BOUNDARY!g" \ -e "s!@DAMSDIR@!$DAMSDIR!g" \ -e "s!@NL@!!g" \ | tr '\001' '\012' echo '## Autogenerated segment list. Please hand-tune for the elements' echo '## most likely to uniquely identify all variants of the virus.' echo 'segments=> [' WORKDIR="$WORKDIR" perl <<'XXX' open(PIPE, "strings -6 -tx '$ENV{WORKDIR}/mask' |"); while () { chomp; $_ =~ /^\s+([0-9a-fA-F]+)\s+(.*)/; $off = $1; $text = $2; $text =~ s!(['\\])!\\$1!go; print " {\n"; print " start => 0x$off,\n"; print " text => '$text',\n"; print " },\n"; } close(PIPE); XXX echo ']' if $KEEP; then : else rm -rf "$WORKDIR" fi