22
33# Function to display usage information
44usage () {
5- echo " Usage: $0 [OUTPUT_DIRECTORY] [--no-osquery]"
5+ echo " Usage: $0 [OUTPUT_DIRECTORY] [--no-osquery] [--tcp-stream IP:PORT] "
66 echo " OUTPUT_DIRECTORY: Optional. Directory where forensic artifacts will be collected."
77 echo " Default: /tmp/result"
88 echo " --no-osquery: Optional. Skip osquery collection."
9+ echo " --tcp-stream: Optional. Stream tarball to specified IP:PORT over TCP."
10+ echo " Format: IP:PORT (e.g., 192.168.1.100:8080)"
911 echo " "
1012 echo " Examples:"
1113 echo " $0 # Use default output directory (/tmp/result) and run osquery"
1214 echo " $0 /var/output # Use custom output directory and run osquery"
1315 echo " $0 --no-osquery # Use default output directory and skip osquery"
1416 echo " $0 /var/output --no-osquery # Use custom output directory and skip osquery"
17+ echo " $0 --tcp-stream 192.168.1.100:8080 # Stream artifacts over TCP"
18+ echo " $0 /var/output --no-osquery --tcp-stream 10.0.0.5:9999 # Custom dir, no osquery, TCP stream"
1519 exit 1
1620}
1721
1822# Parse command line arguments
1923SKIP_OSQUERY=false
2024TEMP_OUTPUT_DIR=" "
25+ TCP_STREAM=" "
2126
22- for arg in " $@ " ; do
23- case $arg in
27+ while [[ $# -gt 0 ]] ; do
28+ case $1 in
2429 -h|--help)
2530 usage
2631 ;;
2732 --no-osquery)
2833 SKIP_OSQUERY=true
2934 shift # Remove --no-osquery from processing
3035 ;;
36+ --tcp-stream)
37+ # Next argument should be IP:PORT
38+ shift
39+ TCP_STREAM=" $1 "
40+ if [[ ! " $TCP_STREAM " =~ ^[0-9]+\. [0-9]+\. [0-9]+\. [0-9]+:[0-9]+$ ]]; then
41+ echo " Error: Invalid TCP stream format. Expected IP:PORT (e.g., 192.168.1.100:8080)"
42+ usage
43+ fi
44+ shift
45+ ;;
46+ --tcp-stream=* )
47+ # Handle --tcp-stream=IP:PORT format
48+ TCP_STREAM=" ${1#* =} "
49+ if [[ ! " $TCP_STREAM " =~ ^[0-9]+\. [0-9]+\. [0-9]+\. [0-9]+:[0-9]+$ ]]; then
50+ echo " Error: Invalid TCP stream format. Expected IP:PORT (e.g., 192.168.1.100:8080)"
51+ usage
52+ fi
53+ shift
54+ ;;
55+ -* )
56+ echo " Error: Unknown option $1 "
57+ usage
58+ ;;
3159 * )
3260 # If an argument is not a flag, and TEMP_OUTPUT_DIR is not set, it's the output directory
33- if [[ ! " $arg " =~ ^- ]] && [ -z " $TEMP_OUTPUT_DIR " ]; then
34- TEMP_OUTPUT_DIR=" $arg "
35- # If it's an unknown flag or a second positional argument
36- elif [[ " $arg " =~ ^- ]] || [ -n " $TEMP_OUTPUT_DIR " ]; then
37- echo " Error: Too many arguments provided or invalid argument: $arg "
61+ if [ -z " $TEMP_OUTPUT_DIR " ]; then
62+ TEMP_OUTPUT_DIR=" $1 "
63+ else
64+ echo " Error: Too many arguments provided: $1 "
3865 usage
3966 fi
67+ shift
4068 ;;
4169 esac
4270done
@@ -249,6 +277,60 @@ check_if_value_in_blacklist() {
249277 return 0
250278}
251279
280+ stream_tarball_over_tcp () {
281+ # Streams tarball over TCP to specified IP:PORT
282+ # Uses /dev/tcp as primary method, falls back to nc/ncat if available
283+ local ip_port=" $1 "
284+ local tarball_path=" $2 "
285+
286+ # Extract IP and port from IP:PORT format
287+ local ip=" ${ip_port%:* } "
288+ local port=" ${ip_port#*: } "
289+
290+ write_log " INFO" " Attempting to stream tarball $tarball_path to $ip :$port "
291+
292+ # Method 1: Try /dev/tcp (built into bash)
293+ if exec 3<> " /dev/tcp/$ip /$port " 2> /dev/null; then
294+ write_log " INFO" " Connected using /dev/tcp method"
295+ if cat " $tarball_path " >&3 2> /dev/null; then
296+ write_log " INFO" " Successfully streamed tarball using /dev/tcp"
297+ exec 3>& - # Close the connection
298+ return 0
299+ else
300+ write_log " ERROR" " Failed to stream data using /dev/tcp"
301+ exec 3>& - # Close the connection
302+ fi
303+ else
304+ write_log " WARNING" " /dev/tcp connection failed, trying fallback methods"
305+ fi
306+
307+ # Method 2: Try netcat (nc)
308+ if command -v nc > /dev/null 2>&1 ; then
309+ write_log " INFO" " Attempting to use nc (netcat)"
310+ if cat " $tarball_path " | nc " $ip " " $port " 2> /dev/null; then
311+ write_log " INFO" " Successfully streamed tarball using nc"
312+ return 0
313+ else
314+ write_log " ERROR" " Failed to stream using nc"
315+ fi
316+ fi
317+
318+ # Method 3: Try ncat (from nmap)
319+ if command -v ncat > /dev/null 2>&1 ; then
320+ write_log " INFO" " Attempting to use ncat"
321+ if cat " $tarball_path " | ncat " $ip " " $port " 2> /dev/null; then
322+ write_log " INFO" " Successfully streamed tarball using ncat"
323+ return 0
324+ else
325+ write_log " ERROR" " Failed to stream using ncat"
326+ fi
327+ fi
328+
329+ # All methods failed
330+ write_log " ERROR" " All TCP streaming methods failed. Tarball remains locally at $tarball_path "
331+ return 1
332+ }
333+
252334copy_configuration_files () {
253335 # Copy configuration files from a list of configuration files.
254336 for file in " ${SYSTEM_FILES[@]} " ; do
@@ -655,7 +737,41 @@ write_log "INFO" "Artifact collection completed in $ELAPSED_TIME seconds. Artifa
655737# Create tar archive of the collected artifacts
656738OUTPUT_BASENAME=$( basename " $OUTPUT_DIR " )
657739PARENT_DIR=$( dirname " $OUTPUT_DIR " )
658- tar -czf " $ZIP_DIR /${OUTPUT_BASENAME} .tar.gz" -C " $PARENT_DIR " " $OUTPUT_BASENAME "
740+ TIMESTAMP=$( date +" %Y%m%d_%H%M%S" )
741+ HOSTNAME=$( hostname -s)
742+ TARBALL_FILENAME=" lfc_${HOSTNAME} _${TIMESTAMP} .tar.gz"
743+ TARBALL_PATH=" $ZIP_DIR /$TARBALL_FILENAME "
744+ tar -czf " $TARBALL_PATH " -C " $PARENT_DIR " " $OUTPUT_BASENAME "
659745
660746# Delete uncompressed output directory
661- rm -rf " $OUTPUT_DIR "
747+ rm -rf " $OUTPUT_DIR "
748+
749+ # Handle TCP streaming if requested
750+ if [ -n " $TCP_STREAM " ]; then
751+ # Create a temporary log file for post-processing operations since original log is now archived
752+ TEMP_LOGFILE=" $ZIP_DIR /lfc_tcp_streaming.log"
753+
754+ # Temporarily redirect write_log to the temp log file
755+ ORIGINAL_LOGFILE=" $LOGFILE "
756+ LOGFILE=" $TEMP_LOGFILE "
757+
758+ write_log " INFO" " TCP streaming requested to $TCP_STREAM "
759+
760+ if stream_tarball_over_tcp " $TCP_STREAM " " $TARBALL_PATH " ; then
761+ write_log " INFO" " Successfully streamed tarball over TCP. Removing local copy."
762+ rm -f " $TARBALL_PATH "
763+ write_log " INFO" " Forensic artifacts streamed to $TCP_STREAM and local tarball removed."
764+ echo " Forensic artifacts streamed to $TCP_STREAM and local tarball removed."
765+ echo " TCP streaming log saved at: $TEMP_LOGFILE "
766+ else
767+ write_log " ERROR" " TCP streaming failed. Tarball remains at $TARBALL_PATH "
768+ write_log " INFO" " Forensic artifacts collection completed. Local tarball saved at $TARBALL_PATH "
769+ echo " TCP streaming failed. Tarball remains at $TARBALL_PATH "
770+ echo " TCP streaming log saved at: $TEMP_LOGFILE "
771+ fi
772+
773+ # Restore original logfile variable (though it won't be used again)
774+ LOGFILE=" $ORIGINAL_LOGFILE "
775+ else
776+ echo " Forensic artifacts collection completed. Tarball saved at $TARBALL_PATH "
777+ fi
0 commit comments