Making Expect scripts for SSH Authentication and Privilege Elevation. Expect can help you to automate interactive console applications. For example, expect script can go to some Linux host via SSH with password authentication, make additional authentication procedures (su, sudo) to elevate privileges and execute some commands. Like Vulnerability and Compliance management products do during the active Linux scanning, right? 🙂 For example you can get the list of installed packages and make Vulnerability Assessment without Vulnerability Scanner.
Actually, the tool is pretty old. It was presented more than 20 years ago! And perhaps now it makes more sense to use python scripts, for example paramiko with paramiko-expect. Or even use some software provisioning tool, like Ansible. But my fun was in creating (generating?) a small old-school scripts that could be sent to any remote host (with expect installed) to gather information from the accessible hosts.
So, the installation is trivial:
# yum install expect
Expect scripting language is an extension to the Tcl. In this language you can set the variables, commands that you want to ran, the lines that you expect from the server response and the commands that will be sent back. I will not show it here, but you can set the timeouts flexibly and initialize the variables from command line (e.g. argv[1]).
Here is a sample ssh_exec.exp script for password-based and authentication and privilege elevation using sudo:
#!/usr/bin/expect
## Parameters
set user "username"
set host "server.corporation.com"
set password "Password123"
set command "cat /etc/shadow"
## Commands
spawn ssh -o StrictHostKeyChecking=no $user@$host
expect "password:" {send "$password\r"}
expect "\$ " {send "sudo su\r"}
expect "password" {send "$password\r"}
expect "\# " {send "$command >temp_file 2>temp_file_error; chown $user temp_file; chown $user temp_file_error;\r"}
expect "\# " {send "exit;\r"}
expect "\$ " {send "exit;\r"}
Here I want to connect to server.corporation.com
using credentials username/Password123
. When the scripts connects to server, server asks for password. The script expects the line with “password:
” and sends the password value. Note the option “-o StrictHostKeyChecking=no
” that helps to avoid checking host key against known_hosts file and related questions.
On the host I want to read /etc/shadow
file. But I can’t do it with the rights of a normal user, root access is required. So, in the same manner script expects the line with “$
“, sends “sudo su
” and repeats the password to elevate privileges.
Then the script expects the line with “#
” and executes the necessary command. The output of the “cat /etc/shadow
” will be saved in “temp_file
” and the possible errors will be saved in “temp_file_error
“. It is also necessary to change permissions on the files, so it will be easier to get them from the server.
Output:
$ expect ssh_exec.exp
spawn ssh -o StrictHostKeyChecking=no username@server.corporation.com
username@server.corporation.com's password:
Last login: Fri Sep 9 19:40:23 2018 from desktop12.corporation.com
[username@server.corporation.com ~]$ sudo su
[sudo] password for username:
[root@server.corporation.com username]# cat /etc/passwd >temp_file 2>temp_file_error; chown username temp_file; chown username temp_file_error;
[root@server.corporation.com username]# exit;
exit
Here is a script for retrieving files from the server with password authentication. It works similar, but with scp tool:
#!/usr/bin/expect
## Parameters
set user "username"
set host "server.corporation.com"
set password "Password123"
set remotefilepath "~/temp_file"
set localfilepath "temp_file"
## Commands
spawn scp -o StrictHostKeyChecking=no $user@$host:$remotefilepath $localfilepath
expect "password:" {send "$password\r"}
expect "\$ " {send "sudo su\r"}
Output:
$ expect scp_get_file.exp
spawn scp -o StrictHostKeyChecking=no username@server.corporation.com:~/temp_file temp_file
username@server.corporation.com's password:
temp_file 100% 2390 203.9KB/s 00:00
In the same manner you can get the temp_file_error
file.
Hi! My name is Alexander and I am a Vulnerability Management specialist. You can read more about me here. Currently, the best way to follow me is my Telegram channel @avleonovcom. I update it more often than this site. If you haven’t used Telegram yet, give it a try. It’s great. You can discuss my posts or ask questions at @avleonovchat.
А всех русскоязычных я приглашаю в ещё один телеграмм канал @avleonovrus, первым делом теперь пишу туда.
Hi Alexander,
thank you very much for your help with except. It’s really helping.
I am working on a scrip and I like to ask you for an advice related to ssh login. The script should be used to log on a Linux server which may and may not require RSA token.
If a Linux server does not requires RSA token the script works fine.
spawn ssh [lindex $argv 1]@[lindex $argv 0]
expect “yes/no” {
send “yes\r”
expect “*?assword” { send “[lindex $argv 2]\r”}
} “*?assword” { send “[lindex $argv 2]\r” }
expect “$ ” { send “hostname -i\r” }
expect “$ ” { send “sudo passwd -S my_usr_id\r” }
expect “$ ” { send “echo \r” }
exit
But If requires RSA I would like to enter it using key board and proceed with the rest of the commands.
Can you please help?
I really appreciate your time and help.
Thank you,
Sakib Mesalic
Pingback: Linux Expect Ssh? The 6 Detailed Answer - Ar.taphoamini.com