bash pipe inside loop vs piping after loop - bash

I'm doing some challenge online. The lvl asked us to do some brute forcing.
SO now what's the difference between this 2 solutions :
## Solution 1
for i in $(seq -w 9999); do
  echo "password_previous_lvl $i"
done | nc localhost 30002
## Solution 2
for i in $(seq -w 9999); do
  echo "password_previous_lvl $i" | nc localhost 30002
done
The only things that is changing here is the piping.
I try to execute just the command in the shell. The output is :
bandit24#bandit:~$ echo "password_previous_lvl 2525" | nc localhost 30002
I am the pincode checker for user bandit25. Please enter the password for user bandit24 and the secret pincode on a single line, separated by a space.
Wrong! Please enter the correct pincode. Try again.
Timeout. Exiting.
There is a timeout.
If I try again directly in the shell with an other password the output is :
bandit24#bandit:~$ echo "password_previous_lvl 2525" | nc localhost 30002
I am the pincode checker for user bandit25. Please enter the password for user bandit24 and the secret pincode on a single line, separated by a space.
Wrong! Please enter the correct pincode. Try again.
password_previous_lvl 2526
Timeout. Exiting.
Just the timeout at then end just like before and no error message.
So I don't understand why when I use the solution number 1 with the piping at the end of the loop I got this result properly :
bandit24#bandit:/tmp$ ./b.sh
I am the pincode checker for user bandit25. Please enter the password for user bandit24 and the secret pincode on a single line, separated by a space.
Wrong! Please enter the correct pincode. Try again.
Wrong! Please enter the correct pincode. Try again.
......
Wrong! Please enter the correct pincode. Try again.
Correct!
The password of user bandit25 is XXXXXXXXXXXXXXX
Exiting.
Can someone explaining me the why ?
Another question is : Why does it ends when the good pin has been found and does not continue ?
Thanks a lot for your help.

Thanks for the comment #Raman Sailopal
In the first solution you are opening the connection only once and sending the echo statement 9999 times. In the second, you set up the connection 9999 times and then send the echo statement once for each connection.

Related

reuse numerical value from a text entry in subsequent entries

I'm trying to automate a procedure and to create the output file that I need. So far everything is going well, but I cannot figure out how to take the number at the end of one row and fill it in for rows after it.
I've tried solutions using awk, sed, etc, but so far, I can't seem to figure this out even with the helps of many googles.
POP-Test-01
10.10.10.10
User: User
Pass: Pass
POP-Test-02
10.10.10.11
User: User
Pass: Pass
POP-Test-03
10.10.10.12
User: User
Pass: Pass
But I want it to take the numerical values from the first line, and append it to the user and pass lines. But for the pass line, I'd like to add it twice.
POP-Test-01
10.10.10.10
User: User01
Pass: Pass0101
POP-Test-02
10.10.10.11
User: User02
Pass: Pass0202
POP-Test-03
10.10.10.12
User: User03
Pass: Pass0303
These are only examples, but the last two digits of the hostname(ex. POP-Test-03) will always be numerical digits.
Edit:
I've had some requests for more details. Sorry about that guys, so here is the skinny. Please note that all values are fake, these come from an input file. I just used the most generic values I could think of.
The input is a text file with only the values in the top example.
So I run a script that deploys instances and the only output I get from the deployment script is the Hostname and the IP address. I know it's not clean, but below is how I'm adding the user and password. But the user and pass are always the same between each batch of servers with only the number of the server being appended to the user and the password(twice). I'm doing this because an application we use requires the input of:
HOSTNAME
IP
User: (username)
Pass: (password)
(empty line)
Normally I have to enter these manually which is time consuming and I was hoping not necessary since I've started it with the commands below in a script I am trying to build to automate the process.
So I start with this:
POP-Test-01
10.10.10.10
And I'm trying to get to this:
POP-Test-01
10.10.10.10
User: User01
Pass: Pass0101
awk '/([0-9]{1,3}[\.]){3}[0-9]{1,3}/{print;print "User\:
Train";next}1' DeploymentDetails2.txt | tee DeploymentDetails2.txt<br/>
awk '/User/{print;print "Pass\: Training";next}1'
DeploymentDetails2.txt | tee DeploymentDetails2.txt<br/>
awk '/Pass/{print;print "\n";next}1' DeploymentDetails2.txt | tee
DeploymentDetails.txt<br/>
This appears to produce what you are looking for:
#!/bin/bash
HOST="POP-Test-"
IP=10
for i in {01..99} ; do
echo ${HOST}${i}
echo "10.0.10.${IP}"
echo "User: User${i}"
echo "Pass: Pass${i}${i}"
echo
let IP++
done
As you did not specify that there was an input file, I took the liberty of generating the ending number in the script, and reusing it in the user and pass lines.

Bash commands putting out extra information which results into issues with scripts

Okay, hopefully I can explain this correctly as I have no idea what's causing this or how to resolve this.
For some reason bash commands (on a CentOS 6.x server) are displaying more information than "normally" and that causes issues with certain scripts. I have no clue if there is a name for this, but hopefully someone knows a solution for this.
First example.
Correct / good server:
[root#goodserver ~]# vzctl enter 3567
entered into CT 3567
[root#example /]#
(this is the correct behaviour)
Incorrect / bad server:
[root#badserver /]# vzctl enter 3127
Entering CT
entered into CT 3127
Open /dev/pts/0
[root#example /]#
With the "bad" server it will display more information as usual, like:
Entering CT
Open /dev/pts/0
It's like it parsing extra information on what it's doing.
Ofcourse the above is purely something cosmetic, however with several bash scripts we use, these issues are really issues.
A part of the script we use, uses the following command (there are more, but this is mainly a example of what's wrong):
DOMAIN=`vzctl exec $VEID 'hostname -d'`
The result of the above information is parsed in /etc/named.conf.
On the GOOD server it would be added in the named.conf like this:
zone "example.com" {
type master;
file "example.com";
allow-transfer {
200.190.100.10;
200.190.101.10;
common-allow-transfer;
};
};
The above is correct.
On the BAD server it would be added in the named.conf like this:
zone "Executing command: hostname -d
example.com" {
type master;
file "Executing command: hostname -d
example.com";
allow-transfer {
200.190.100.10;
200.190.101.10;
common-allow-transfer;
};
};
So it's add stuff of the action it does, in this example "Executing command: hostname -d"
Another example here when I run the command on a good server and on the bad server.
Bad server:
[root#bad-server /]# DOMAIN=`vzctl exec 3333 'hostname -d'`
[root#bad-server /]# echo $DOMAIN
Executing command: hostname -d example.com
Good server:
[root#good-server ~]# DOMAIN=`vzctl exec 4444 'hostname -d'`
[root#good-server ~]# echo $DOMAIN
example.com
My knowledge is limited, but I have tried several things checking rsyslog and the grub.conf, but nothing seems out of the ordinary.
I have no clue why it's displaying the extra information.
Probably it's something simple / stupid, but I have been trying to solve this for hours now and I really have no clue...
So any help is really appreciated.
Added information:
Both servers use: kernel.printk = 7 4 1 7
(I don't know if that's useful)
Well (thanks to Aaron for pointing me in the right direction) I finally found the little culprit which was causing all the issues I experienced with this script (which worked for every other server, so no need to change that obviously).
The issues were caused by the VERBOSE leven set in vz.conf (located in /etc/vz/ directory). There is an option in there called "VERBOSE" and in my case it was set to 3.
According to OpenVZ's website it does the following:
Increments logging level up from the default. Can be used multiple times.
Default value is set to the value of VERBOSE parameter in the global
configuration file vz.conf(5), or to 0 if not set by VERBOSE parameter.
After I changed VERBOSE=3 to VERBOSE=0 my script worked fine once again (as it did for every other server). :-)
So a big shoutout to Aaron for pointing me in the right direction. The answer is easy when you know where to look!
Sorry to say, but I am kinda disappointed by ndim's reaction. This is the 2nd time he was very unhelpful and rude in his response after that. He clearly didn't read the issue I posted correctly. Oh well.
I would make sure to properly parse the output of the command. In this case, we are only interested in lines of the form
entered into CT 12345
One way of doing this would be to pipe everything through sed and having sed print only the number when the line looks as above (untested, and I always forget which braces/brackets/parens need a backslash in front of them):
whateverthecommand | sed -n 's/^entered into CT ([0-9]{1,})$/\1/p'

How to grab 'show tech' with bash and expect?

I'm using 2 scripts. A bash and an expect script. the bash is just a for loop with a set of IPs. If I can, I would use the expect script to create a variable near the beginning, right after login. It would look for the hostname, assign it to a variable, then use that variable as the 'match' after show tech output.
Also, the IPs are example. I'm not actually expecting (no pun intended) this to operate on public DNS IPs. Ok ok, you got me, I put this disclaimer here just so I could 'not' make that pun.
#!/bin/bash
arrayHOST+=( '8.8.8.8' '8.8.4.4' '4.2.2.2' '4.2.2.1' )
username="user1"; password="pass1"
for host in ${arrayHOST[#]}; do
./expect.sh $host $username $password >> $host.txt
done
and the expect script:
#!/usr/bin/expect -f
#log_user 0
set timeout -1
set varIP1 [lindex $argv 0]
set varUSER [lindex $argv 1]
set varPASS [lindex $argv 2]
spawn telnet $varIP1
expect "Username:"
send "$varUSER\r"
expect "Password:"
send "$varPASS\n"
expect "#"
send "term leng 0\r"
expect "#"
send "term wid 0\r"
expect "#"
send "show tech\r"
expect "#"
puts $expect_out(buffer);
Problem is that there are '#' characters that match before the command finishes so I don't get to capture the whole thing. Points to consider:
The end of the output from 'show tech' isn't the same on every device in the IP list unless you consider the hostname of the device itself.
Yes, I know I can "show tech | redirect tftp:// etc". This wont help me achieve the desired results.
I've tried 'not expecting anything' but this causes expect to not capture anything. (sending show tech without following with a new line containing expect "#" or anything else)
spawn telnet 8.8.8.8
Trying 8.8.8.8...
Connected to 8.8.8.8.
Escape character is '^]'.
User Access Verification
Username: benjamin
Password:
rowtar#term leng 0
rowtar#term wid 0
rowtar#term wid 0
rowtar#
I really like the idea of trying to regex/match an expect variable to the output that matches the hostname of the device but I don't how to do that. In my example, I would try to match "rowtar#" but without per-defining that ahead of time or before the expect script is called.
The solution was looking me right in the face.
Simply:
expect -re #$
matching any line ending with #
I still encourage someone to help/answer with hostname matching to a variable

need to read IP from a text and set manually on centos

i have 10 IP which have been listed on a CSV or text file , i need to read each time one line and get the IP and set on eth0 interface of the server, i found the bellow script which some how show me how to create new network setting but i do not know how i could read one line from CSV and put it on variable to use with bellow script . i would be greatly thankful if you give me some hint , thanks
https://wiki.gogrid.com/index.php/Customer:Automatically_convert_your_Linux_server_to_a_static_IP
May something like this:
#!/bin/sh
lineNumber=1
ip=`head -n $lineNumber test.csv | tail -n 1 | line`
echo $ip

shell script display grep results

I need some help with displaying how many times two strings are found on the same line! Lets say I want to search the file 'test.txt', this file contains names and IP's, I want to enter a name as a parameter when running the script, the script will search the file for that name, and check if there's an IP-address there also. I have tried using the 'grep' command, but I don't know how I can display the results in a good way, I want it like this:
Name: John Doe IP: xxx.xxx.xx.x count: 3
The count is how many times this line was found, this is how my grep script looks like right now:
#!/bin/bash
echo "Searching $1 for the Name '$2'"
result=$(grep "$2" $1 | grep -E "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)")
echo $result
I will run the script like 'sh search test.txt John'.
I'm having trouble displaying the information I get from the grep command, maybe there's a better way to do this?
EDIT:
Okey, I will try to explain a little better, let's say I want to search a .log file, I want a script to search that file for a string the user enters as a parameter. i.e if the user enters 'sh search test.log logged in' the script will search for the string "logged in" within the file 'test.log'. If the script finds this line on the same line as a IP-address the IP address is printed, along with how many times this line was found.
And I simply don't know how to do it, I'm new to shell scripting, and was hoping I could use grep along with regular expressions for this! I will keep on trying, and update this question with an answer if I figure it out.
I don't have said file on my computer, but it looks something like this:
Apr 25 11:33:21 Admin CRON[2792]: pam_unix(cron:session): session opened for user 192.168.1.2 by (uid=0)
Apr 25 12:39:01 Admin CRON[2792]: pam_unix(cron:session): session closed for user 192.168.1.2
Apr 27 07:42:07 John CRON[2792]: pam_unix(cron:session): session opened for user 192.168.2.22 by (uid=0)
Apr 27 14:23:11 John CRON[2792]: pam_unix(cron:session): session closed for user 192.168.2.22
Apr 29 10:20:18 Admin CRON[2792]: pam_unix(cron:session): session opened for user 192.168.1.2 by (uid=0)
Apr 29 12:15:04 Admin CRON[2792]: pam_unix(cron:session): session closed for user 192.168.1.2
Here is a simple Awk script which does what you request, based on the log snippet you posted.
awk -v user="$2" '$4 == user { i[$11]++ }
END { for (a in i) printf ("Name: %s IP: %s count: %i\n", user, a, i[a]) }' "$1"
If the fourth whitespace-separated field in the log file matches the requested user name (which was passed to the shell script as its second parameter), add one to the count for the IP address (from field 11).
At the end, loop through all non-zero IP addresses, and print a summary for each. (The user name is obviously whatever was passed in, but matches your expected output.)
This is a very basic Awk script; if you think you want to learn more, I urge you to consult a simple introduction, rather than follow up here.
If you want a simpler grep-only solution, something like this provides the information in a different format:
grep "$2" "$1" |
grep -o -E '(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)' |
sort | uniq -c | sort -rn
The trick here is the -o option to the second grep, which extracts just the IP address from the matching line. It is however less precise than the Awk script; for example, a user named "sess" would match every input line in the log. You can improve on that slightly by using grep -w in the first grep -- that still won't help against users named "pam" --, but Awk really gives you a lot more control.
My original answer is below this line, partly becaus it's tangentially useful, partially because it is required in order to understand the pesky comment thread below.
The following
result=$(command)
echo $result
is wrong. You need the second line to be
echo "$result"
but in addition, the detour over echo is superfluous; the simple way to write that is simply
command

Resources