working version, for release

This commit is contained in:
2019-07-09 10:17:00 +03:00
parent da5c54017c
commit 97070ebe30
12 changed files with 200 additions and 111 deletions

288
src/qolop
View File

@@ -1,288 +0,0 @@
#!/bin/bash
_qColVersion() { echo Version 2019.06.21.0; }
_qColHelp() {
_qColVersion
echo 'Quick shell COLOrizer Package
Source me in BASH!
Why the name qolop? Place a mirror next to it!
Functions:
- _qCol: Print ANSI color codes by letter codes.
Can export all letter codes as varibles.
- _qCode: Print ANSI color codes by number sequence
- _qParse: Print ANSI color by english words ex. "red", "lightgreen", "gray on blue"
- _qPos: Move cursor
- _qClr: Clear screen
- _qReset: Reset terminal
Examples:
source qolop # load functions
- As functions:
_title(){ _qClr; _qCol z G; echo "$@"; _qCol z; }
_text(){ _qCol z; _qCode 1 34; echo "$@"; _qCol z; }
_title Title; _text Colored;
- As variables
TITLE=$( _qCol z G; )
Z=$( _qCol z; )
echo ${TITLE}Title${Z}
- Export to variables (prefixed with _c. Also the default)
_qCol export _c
echo -e ${_cG}Title${_cZ}
Run qolop as script to print ANSI code table, or evaluate commands
qolop eval "_qCol G; printf hello; _qCol z" | qolop escape
The first command produces string with ANSI commands, the
second will escape the escape characters, so you can copy/paste
it in to another echo -e command.
qolop c G
qolop p green
produce the same output, just the color code
'
}
_qClr() {
# Clear screen
_qCol "CLR"
_qPos abs 0 0
}
_qCol() {
# print "easier" mapping of ANSI colors and controls
local K="\033[1;30m"
local R="\033[1;31m"
local G="\033[1;32m"
local B="\033[1;34m"
local Y="\033[1;33m"
local M="\033[1;35m"
local C="\033[1;36m"
local W="\033[1;37m"
local k="\033[2;30m"
local r="\033[2;31m"
local g="\033[2;32m"
local b="\033[2;34m"
local y="\033[2;33m"
local m="\033[2;35m"
local c="\033[2;36m"
local w="\033[2;37m"
local bk="\033[40m"
local br="\033[41m"
local bg="\033[42m"
local by="\033[43m"
local bb="\033[44m"
local bm="\033[45m"
local bc="\033[46m"
local bw="\033[47m"
local S='\033[1m' #strong
local s='\033[2m' #strong off
local U='\033[4m' #underline
local u='\033[24m' #underline off
local z='\033[0m' #zero colors
local Z='\033[0m' #zero colors
local ic='\033[7m' #inverse colors
local io='\033[27m' #inverse off
local st='\033[9m' #strike on
local so='\033[29m' #strike off
local CLR='\033[2J' # Clear screen
local CLREND='\033[K' # Clear to end of line
local CLRBEG='\033[1K' # Clear to beginning of line
local CLRSCR="$CLR"'\033[0;0H' # Clear screen, reset cursor
local color_keys=" K R G B Y M C W k r g b y m c w S s U u z Z \
ic io st so bk br bg by bb bm bc bw \
CLR CLREND CLRBEG CLRSCR "
[[ "$1" = "export" ]] && {
local key
local prefix="$2"
[[ -z "$2" ]] && prefix=_c
for key in $color_keys; do
eval export ${prefix}${key}=\'${!key}\'
done
return
}
local arg val
for ((arg=1;arg<=$#;arg++)) {
val=${!arg}
[[ ${color_keys} = *" $val "* ]] || { echo "No such color code '${val}'" >&2; return 1; }
printf ${!val}
}
}
_qCode() {
# Enter numerical ANSI colors directly
local arg val
for ((arg=1;arg<=$#;arg++)) {
val=${!arg}
printf '\033['"${val}m"
}
}
_qParse() {
# Parse written colors to codes: 'help' to get help
local val codes
val="${@,,}"
if [[ ${#val} -lt 3 ]]; then
continue
fi
if [[ ${val} = *"help"* ]]; then
echo "Parse format [light][colorname], or '[light][colorname] on [colorcolorname]'" >&2
return
fi
if [[ ${val} = "light"* ]]; then
codes="${codes} S"
val=${val#light}
fi
case "$val" in
"black"*) codes="${codes} k";;
"red"*) codes="${codes} r";;
"green"*) codes="${codes} g";;
"yellow"*) codes="${codes} y";;
"blue"*) codes="${codes} b";;
"magenta"*) codes="${codes} m";;
"cyan"*) codes="${codes} c";;
"gray"*) codes="${codes} w";;
"white"*) codes="${codes} W";;
esac
if [[ ${val} = *" on "* ]]; then
case "$val" in
*"black") codes="${codes} bk";;
*"red") codes="${codes} br";;
*"green") codes="${codes} bg";;
*"yellow") codes="${codes} by";;
*"blue") codes="${codes} bb";;
*"magenta") codes="${codes} bm";;
*"cyan") codes="${codes} bc";;
*"gray") codes="${codes} bk";;
*"white") codes="${codes} bw";;
esac
fi
_qCol $codes
}
_qPos() {
# Cursor position control
local n="$2"
local x="$3"
[[ -z "$n" ]] && n=1
[[ -z "$x" ]] && x=1
[[ "$1" = "save" ]] && { printf '\033[s'; return; }
[[ "$1" = "restore" ]] && { printf '\033[u'; return; }
[[ "$1" = "up" ]] && { printf '\033['${n}'A'; return; }
[[ "$1" = "down" ]] && { printf '\033['${n}'B'; return; }
[[ "$1" = "right" ]] && { printf '\033['${n}'C'; return; }
[[ "$1" = "left" ]] && { printf '\033['${n}'D'; return; }
[[ "$1" = "lineup" ]] && { printf '\033['${n}'E'; return; }
[[ "$1" = "linedown" ]] && { printf '\033['${n}'F'; return; }
[[ "$1" = "col" ]] && { printf '\033['${n}'G'; return; }
[[ "$1" = "abs" ]] && { printf '\033['${n}';'${x}'H'; return; }
echo "Command missing: save, restore, up, down, right, left, lineup, linedown, col, abs" >&2
echo "Directional commands take one argument, abs uses two (row, col)" >&2
return 1
}
_qReset() {
# Reset terminal
printf '\033c'
}
if [[ "$0" = "${BASH_SOURCE[0]}" ]]; then
[[ "$1" = "update" ]] && {
set -e
case $OSTYPE in
darwin*)
MYPATH=$( realpath "$0" )
;;
*)
MYPATH=$( readlink -f "$0" )
;;
esac
MYDIR=$( dirname "$MYPATH" )
QTOOLS=0
if [[ -f "$MYDIR/../rc" ]]; then if grep -q QTOOLS "$MYDIR/../rc"; then
QTOOLS=1
fi;fi;
if [[ "$QTOOLS" -eq 1 ]]; then
echo "Update qolop with _q-tools-update"
exit 1
fi
TMPFILE=$( mktemp )
rm -f "$TMPFILE"
echo "Checking for newer version"
wget -q -O "$TMPFILE" https://bitbucket.org/MoonQ/tools/raw/tip/reporting/qolop
diff "$TMPFILE" "$MYPATH" || {
mv -v "$TMPFILE" "$MYPATH"
chmod +x "$MYPATH"
echo Updated
source "$MYPATH"
_qColVersion
}
rm -f "$TMPFILE"
exit 0
} # end update
[[ "$1" = "eval" ]] && {
set -e
eval "$@"
exit
}
[[ "$1" = "escape" ]] && {
cat - | sed s/$'\e'/\\\\033/g
echo ''
exit
}
[[ "$1" = "c" ]] && {
shift 1
_qCol "$@"
exit
}
[[ "$1" = "p" ]] && {
shift 1
_qParse "$@"
exit
}
_qColHelp
[[ "$1" = *"help" ]] && exit
[[ "$1" = "-h" ]] && exit
_qCol export "_"
printf "${_S}ANSI CODES AND QOLOP VARIABLES FOR _qCol FUNCTION
=================================================${_Z}
${_R}Co${_G}lo${_B}rs${_W} and ${_S}Mo${_U}di${_st}fi${_u}er${_ic}s${_Z} \\\033[Xm or \\\033[X;Y;Zm
${_S}====================${_Z}
0 z Z Clear format
1 S ${_S}Strong/Bold ${_Z} 30 k ${_k}Black ${_Z}30;1 K ${_K}Black ${_Z}40 bk ${_w}${_bk}Black ${_Z}
2 s ${_s}Weak/Bold off ${_Z} 31 r ${_r}Red ${_Z}31;1 R ${_R}Red ${_Z}41 br ${_k}${_br}Red ${_Z}
4 U ${_U}Underline ${_Z} 32 g ${_g}Green ${_Z}32;1 G ${_G}Green ${_Z}42 bg ${_k}${_bg}Green ${_Z}
24 u ${_u}Underline off ${_Z} 33 y ${_y}Yellow ${_Z}33;1 Y ${_Y}Yellow ${_Z}43 by ${_k}${_by}Yellow ${_Z}
7 ic ${_ic}Inverse color ${_Z} 34 b ${_b}Blue ${_Z}34;1 B ${_B}Blue ${_Z}44 bb ${_k}${_bb}Blue ${_Z}
27 of ${_io}Inverse off ${_Z} 35 m ${_m}Magenta ${_Z}35;1 M ${_M}Magenta ${_Z}45 bm ${_k}${_bm}Magenta ${_Z}
9 st ${_st}Strike ${_Z} 36 c ${_c}Cyan ${_Z}36;1 C ${_C}Cyan ${_Z}46 bc ${_k}${_bc}Cyan ${_Z}
29 so ${_so}Strike off ${_Z} 37 w ${_w}White ${_Z}37;1 W ${_W}White ${_Z}47 bw ${_k}${_bw}White ${_Z}
Enter raw color code sequence with _qCode function
${_S}Clearing and movement${_Z} ESC[X or ESC[1X
${_S}=====================${_Z}
2J CLR Clear screen
2J ;H CLRSCR _qClr() Clear screen, move cursor to origo
K CLREND Clear to end of line
1K CLRBEG Clear to beginning of line
_qReset() Reset terminal
s _qPos save Save location u _qPos restore Restore location
A _qPos up Up E _qPos lineup Up line
B _qPos down Down F _qPos linedown Down line
C _qPos left Left y;xH _qPos abs y x Absolute Position
D _qPos right Right
"
fi

View File

@@ -6,6 +6,7 @@ import psutil
import random
import sqlite3
import time, os, sys
import subprocess
def setup_options():
''' Setup the command line options '''
@@ -20,44 +21,6 @@ def setup_options():
type = str,
help = "Sqlite file for database: %(default)s"
)
# TODO --connect (replace ssh-local-connect)
parser.add_argument(
"--clear",
action = 'store_true',
dest = 'clear',
default = False,
help = "Clear the database of everything, first"
)
parser.add_argument(
"--kill",
action = 'store',
dest = 'kill',
default = None,
type = str,
help="Kill processes of given ID"
)
parser.add_argument(
"--list","-l",
action = 'store_true',
dest = 'list',
default = False,
help = "List ports"
)
parser.add_argument(
"--list-names",
action = 'store_true',
dest = 'list_names',
default = False,
help = "List alive host names only"
)
parser.add_argument(
"--query",
action = 'store',
dest = 'query',
default = None,
type = str,
help="Query port for an id"
)
parser.add_argument(
"--quiet", "-q",
action = 'store_true',
@@ -65,22 +28,78 @@ def setup_options():
default = False,
help = "Quiet operation: %(default)s"
)
parser.add_argument(
"--wait", "-w",
action = 'store_true',
dest = 'wait',
default = False,
help = "Enter infinite loop"
subparsers = parser.add_subparsers(
help = "Help for subcommand",
dest = 'command'
)
parser.add_argument(
parser_clear = subparsers.add_parser(
'clear',
help = "Clear the database of everything"
)
parser_connect = subparsers.add_parser(
'connect',
help = "Connect to a backdoor"
)
parser_connect.add_argument(
dest = "id",
help = "Backdoor ID to connect to"
)
parser_kill = subparsers.add_parser(
'kill',
help = "Kill a backdoor"
)
parser_kill.add_argument(
dest = "id",
help = "Backdoor ID to kill"
)
parser_list = subparsers.add_parser(
"list",
help = "List ports"
)
parser_list_names = subparsers.add_parser(
"list-names",
help = "List alive host names only"
)
parser_query = subparsers.add_parser(
"query",
help="Query port for an id"
)
parser_query.add_argument(
dest = "id",
help = "Backdoor ID to query"
)
parser_open = subparsers.add_parser(
"open",
help = "Open a new port. Returns the port number"
)
parser_open.add_argument(
action = 'store',
dest = 'id',
default = None ,
type = str,
nargs = '?',
help="Id name for port"
help="Id name for backdoor"
)
parser_wait = subparsers.add_parser(
"keep",
help = "Keep updating alive status (for 1 hour)"
)
parser_wait.add_argument(
action = 'store',
dest = 'id',
type = str,
help="Id name for backdoor"
)
options=parser.parse_args()
if options.command == None:
parser.print_help(sys.stderr)
sys.exit(1)
return options
@@ -254,52 +273,83 @@ class DataBase:
if len(result) == 0:
return port
def connect_backdoor(self, id):
self.db = self.conn.cursor()
self.db.execute("SELECT port,pid FROM ports WHERE id = ?", (id,))
result = self.db.fetchall()
if len(result) == 0:
eprint("No such ID")
return
port = result[0][0]
pid = result[0][1]
if not self.is_running(pid):
eprint("Backdoor not open")
return
user = id.split("@")[0]
os.execlp(
"ssh",
"ssh",
"-o", "UserKnownHostsFile=/dev/null",
"-o", "StrictHostKeyChecking=no",
"-tt", "-XYC",
"-p", str(port),
"%s@localhost"%( user, )
)
if __name__ == "__main__":
opts=setup_options()
db = DataBase(opts.DB)
start_time = time.time()
if opts.clear:
if opts.command == "clear":
db.clear()
if opts.list_names:
if opts.command == "list-names":
for row in db.list():
if row[5]:
if row[-1]:
print(row[0])
sys.exit(0)
if opts.list:
if opts.command == "list":
print(tabulate(
db.list(),
headers = ['Id','Port','Host','Age','PID','Die','Alive']
))
if opts.query != None:
port = db.get_port(opts.query)
if opts.command == "query":
port = db.get_port(opts.id)
if port == None:
sys.exit(1)
print(port)
sys.exit(0)
if opts.kill:
db.set_to_die(opts.kill)
if opts.command == "kill":
db.set_to_die(opts.id)
sys.exit(0)
if opts.id != None:
if opts.command == "connect":
db.connect_backdoor(opts.id)
if opts.command == "open":
print(db.update(opts.id))
if opts.wait:
ewrite(
" Connected\r"
)
while True:
if time.time() - start_time > 3600:
sys.exit(0)
db.check_die()
db.update(opts.id)
for i in range(10):
time.sleep(10 * random.random())
ewrite(
" " +
time.strftime("%c") +
"\r"
)
if opts.command == "keep":
print(db.update(opts.id))
ewrite(
" Connected\r"
)
while True:
# Run 1 hour, then exit to reconnect
if time.time() - start_time > 3600:
sys.exit(0)
db.check_die()
db.update(opts.id)
for i in range(10):
time.sleep(10 * random.random())
ewrite(
" " +
time.strftime("%c") +
"\r"
)

View File

@@ -15,8 +15,8 @@ BACKDOORHOST={{BACKDOORHOST}}
BACKDOORPORT={{BACKDOORPORT}}
_list() {
echo 'usage: [-auto] user@host'
_ssh bin/ssh-backdoor -l
ids=( $( _ssh bin/ssh-backdoor --list-names ) )
_ssh bin/ssh-backdoor list
ids=( $( _ssh bin/ssh-backdoor list-names ) )
if [[ ${#ids[@]} -eq 0 ]]; then
exit
fi
@@ -33,6 +33,8 @@ _ssh() {
-o UserKnownHostsFile=/dev/null \
-o StrictHostKeyChecking=no \
-o ConnectTimeout=10 \
-o ServerAliveInterval=15 \
-o ServerAliveCountMax=3 \
-p ${BACKDOORPORT} ${BACKDOORHOST} \
"$@"
#~ -o "ExitOnForwardFailure yes" \
@@ -48,17 +50,15 @@ for (( i=1; i<=$#; i++ )); do
host="${!i}"
done
port=$( _ssh bin/ssh-backdoor --query "$host" )
port=$( _ssh bin/ssh-backdoor query "$host" )
[[ $? -ne 0 ]] && {
echo No such id
_list
}
login=(${host//@/ })
while :; do
_ssh \
-tt \
ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \
-tt -XYC -p $port ${login[0]}@localhost
bin/ssh-backdoor connect "$host"
[[ $? -eq 0 ]] && exit
[[ "$auto_reconnect" -ne 1 ]] && { exit $?; }
echo Auto-reconnect

View File

@@ -1,21 +0,0 @@
#!/bin/bash
_list() {
echo usage: user@host
ssh-backdoor -l
exit
}
[[ -z "$1" ]] && _list
port=$( ssh-backdoor --query "$1" )
[[ $? -ne 0 ]] && {
echo No such id
_list
}
login=(${1//@/ })
set -x
exec ssh \
-o UserKnownHostsFile=/dev/null \
-o StrictHostKeyChecking=no \
-tt -XYC -p $port ${login[0]}@localhost

View File

@@ -31,13 +31,13 @@ USER=$( id -u -n )
echo use of ssh-add is encouraged
( sleep 3; printf "%d\r" $SECONDS ) &
while true; do
port=$( _ssh bin/ssh-backdoor $USER@$HOSTNAME )
port=$( _ssh bin/ssh-backdoor open $USER@$HOSTNAME )
[[ -z "$port" ]] && { sleep 2; continue; }
echo "$port port assigned"
#~ _ssh pkill -a -f $USER@$HOSTNAME
_ssh \
-R $port:localhost:22 \
bin/ssh-backdoor -w $USER@$HOSTNAME || {
bin/ssh-backdoor keep $USER@$HOSTNAME || {
true
# failed
#_ssh bin/ssh-kill $USER@$HOSTNAME $port || true

View File

@@ -1,37 +0,0 @@
#/bin/bash
PATH=$PATH:$HOME/bin
pppid=$( ps --no-header o ppid $PPID )
ppcom=$( ps --no-header o comm $pppid )
if [[ $ppcom = sshd ]]; then
pgrep -u $USER -x sshd | while read pid; do
row=$( ps --no-header o pid,start,comm $pid )
printf "%s%s%s\r" $( qolop c Y ) "$row" $( qolop c Z )
sleep 0.5
if [[ $pid -eq $pppid ]]; then
printf "%s%s%s\r" $( qolop c G ) "$row" $( qolop c Z )
else
kill -9 $pid &> /dev/null
printf "%s%s%s\r" $( qolop c R ) "$row" $( qolop c Z )
fi
printf "\n"
done
pgrep -u $USER -x ssh | while read pid; do
row=$( ps --no-header o pid,start,comm $pid )
printf "%s%s%s\r" $( qolop c Y ) "$row" $( qolop c Z )
sleep 0.5
kill -9 $pid &> /dev/null
printf "%s%s%s\r" $( qolop c R ) "$row" $( qolop c Z )
printf "\n"
done
pgrep -u $USER -x python3 | while read pid; do
row=$( ps --no-header o pid,start,comm $pid )
printf "%s%s%s\r" $( qolop c Y ) "$row" $( qolop c Z )
sleep 0.5
kill -9 $pid &> /dev/null
printf "%s%s%s\r" $( qolop c R ) "$row" $( qolop c Z )
printf "\n"
done
fi

View File

@@ -1,4 +0,0 @@
#!/bin/bash
ps axuw | grep -e [s]sh -e [p]ython3