Aww Sheezy!

tcl / expect script example

by on Nov.26, 2010, under Hacking, Tech

I’ve never been much of a teacher, but I wrote this expect script. There are examples of just about most things you can do with expect within this script. Extend via procedures. This script is run with one argument, a file containing “hostname,systemOwner”.

#!/usr/bin/expect -f
# Written by Mike Romero
set prompt "(%|#|\\$|%]) $"
set timeout 15
set file [lindex $argv 0]
set hosts [open $file r]
set user "userid"
set pass "password"
 
# This disables output to the console unless "send_user" is used..
log_user 0
# This line sends debug output to the log file name specified
exp_internal -f expssh.log 0
 
proc getSudo { prompt pass } {
  send "bash\n"
  expect {
    -re $prompt {
      send "ls\n"
      expect {
        -re $prompt {
          send_user "Login Success. "
          send "sudo -K\n"
          expect { 
            "sudo -K\r\n" { }
            default { send_user "Console lagging.... d'oh!" }
          }
          expect {
            -re $prompt {
              send "sudo su -\n"
              expect {
                "is not in the sudoers file." { 
                   send_user "\"sudo su -\" failed. Weird expect..\n"
                   send "exit\n"
                   return false
                }
                "assword:" {
                  send "$pass\n"
                  expect {
                    "is not in the sudoers file." {
                      send_user "\"sudo su -\" failed.\n"
                      send "exit\n"
                      return false
                    }
                    -re $prompt { 
                      send_user "Passworded \"sudo su -\" succesful. "
                      return true
                    }
                  }
                }
                -re "assword for(.*): " {
                  send "$pass\n"
                  expect {
                    "is not in the sudoers file" {
                      send_user "\"sudo su -\" failed.\n"
                      send "exit\n"
                      return false
                    }
                    -re $prompt { 
                      send_user "Passworded \"sudo su -\" succesful. "
                      return true
                    }
                  }
                }
                -re $prompt {
                  send_user "Passwordless \"sudo su -\" succesful. "
                  return true
                }
              } 
            }
          }
        }
      }
    } 
  }
  return true
}
 
proc testSudo { prompt pass } {
  send "bash\n"
  expect {
    -re $prompt {
      send "ls\n"
      expect {
        -re $prompt {
          send_user "Login Success. "
          send "sudo -K\n"
          expect { 
            "sudo -K\r\n" { }
            default { send_user "Console lagging.... d'oh!" }
          }
          expect {
            -re $prompt {
              send "sudo -l\n"
              expect {
                "is not in the sudoers file." { 
                   send_user "\"sudo -l\" failed. Weird expect..\n"
                   return false
                }
                "assword:" {
                  send "$pass\n"
                  expect {
                    "is not in the sudoers file." {
                      send_user "\"sudo -l\" failed.\n"
                      return false
                    }
                    -re "\(ALL\).*ALL" {
                      send_user "$expect_out(1,string) \"sudo\" SUCCESS. "
                      return true
                    }
                    -re "\(root\).*ALL" {
                      send_user "$expect_out(1,string) \"sudo\" SUCCESS."
                      return true
                    }
                    "USERADD" {
                      send_user "NON-ALL \"sudo\" SUCCESS. "
                    }
                    "/bin/mount" {
                      send_user "NON-ALL \"sudo\" SUCCESS. "
                    }
                    "may not run sudo" {
                      send_user "\"sudo\" FAILURE. "
                    }
                  }
                }
                -re "assword for(.*): " {
                  send "$pass\n"
                  expect {
                    "is not in the sudoers file" {
                      send_user "\"sudo -l\" failed.\n"
                      return false
                    }
                    -re "\(ALL\).*ALL" {
                      send_user "$expect_out(1,string) \"sudo\" SUCCESS."
                      return true
                    }
                    -re "\(root\).*ALL" {
                      send_user "$expect_out(1,string) \"sudo\" SUCCESS."
                      return true
                    }
                    "USERADD" {
                      send_user "NON-ALL \"sudo\" SUCCESS. "
                    }
                    "/bin/mount" {
                      send_user "NON-ALL \"sudo\" SUCCESS. "
                    }
                    "may not run sudo" {
                      send_user "\"sudo\" FAILURE. "
                    }
                  }
                }
                -re "\(ALL\).*ALL" {
                  send_user "$expect_out(1,string) \"sudo\" SUCCESS."
                  return true
                }
                -re "\(root\).*ALL" {
                  send_user "$expect_out(1,string) \"sudo\" SUCCESS."
                  return true
                }
                "USERADD" {
                  send_user "NON-ALL \"sudo\" SUCCESS. "
                }
                "/bin/mount" {
                  send_user "NON-ALL \"sudo\" SUCCESS. "
                }
                "may not run sudo" {
                  send_user "\"sudo\" FAILURE. "
                }
              } 
            }
          }
        }
      }
    } 
  }
  return true
}
 
proc createAccount { prompt pass } {
  send "cat /etc/passwd | grep mromero | awk -F\":\" '{ print \$1 }'\n"
  expect {
    "\r\nmromero\r\n" {
      send_user "Local \"mromero\" account exists...\n"
    }
    -re $prompt { 
      send_user "Local \"mromero\" does NOT exist. " 
      # check to see if system is using LDAP authentication
      send "sudo cat /etc/pam.d/system-auth | grep pam_ldap.so | wc -l\n"
      expect {
        "\r\n0\r\n" {
          send_user "NON-LDAP Client. "
          send "sudo useradd -m -u 42778 -g 60032 -c \"Michael Romero\" -d \"/home/mromero\" -s /bin/bash mromero\n"
          expect -re $prompt
          send "sudo passwd mromero\n"
          expect {
            -re "New.*assword:" {
              send "temporary!\n"
              expect {
                -re "Retype new.*assword:" {
                  send "temporary!\n"
                  expect {
                    "tokens updated successfully." {
                      send_user "Account Created.  Password set.\n"
                    }
                  }
                }
              }
            }
          }
        } 
        -re $prompt {
          send_user "LDAP Client\n"
        } 
      }
    }
  }
}
 
proc passwd { prompt pass newpass host user } {
  send "passwd\n"
  expect {
    -re ".*assword:.*" {
      send "$pass\n"
      expect {
        -re "New.*assword:.*" {
          send_user "Entering new pass.."
          send "$newpass\n"
          expect {
            "already used" {
               send_user "BAD PASSWORD: has been already used"
               send ""
             }
             -re "Retype new.*assword:" {
               send_user "Confirming new pass.."
               send "$newpass\n"
               expect {
                 "authentication tokens updated successfully" {
                    send_user "Password changed to $newpass successfully.\n"
                  }
                 default {
                   send_user "Unknown passwd error.  Examine logs for $host.\n"
                 }
               } 
             }
          } 
        }
        -re "try again.*password:.*" {
          send_user "Password failure during \"passwd\" change attempt.\n"  
          send ""
        } 
        "wait longer to change your password" {
          send_user "You must wait longer to change your password.\n"
        }
        "Authentication token manipulation error" {
          send_user "Token manipulation error.  Trying via sudo. "
          if {[testSudo $prompt $pass] == true} {
            send "sudo passwd $user\n"
            expect {
              -re "New.*assword:.*" {
                send_user "Entering new pass.."
                send "$newpass\n"
                expect {
                  "already used" {
                     send_user "BAD PASSWORD: has been already used.\n"
                     send ""
                  }
                  -re "Retype new.*assword:" {
                    send_user "Confirming new pass.."
                    send "$newpass\n"
                    expect {
                      "authentication tokens updated successfully" {
                         send_user "Password changed to $newpass successfully.\n"
                       }
                      default {
                        send_user "Unknown passwd error.  Examine logs for $host.\n"
                      }
                    } 
                  }
                  "Reenter New Password:" {
                    send_user "Confirming new pass.."
                    send "$newpass\n"
                    expect {
                      "Password changed." {
                         send_user "Password changed to $newpass successfully.\n"
                       }
                      default {
                        send_user "Unknown passwd error.  Examine logs for $host.\n"
                      }
                    } 
                  }
                } 
              }
            }
            send "exit\n"
          } else {
            send_user "Authentication token manipulation error.\n"
          }
        } 
        default {
         send_user "Unknown or missing response during \"passwd\" dialog.  Examine logs for $host.\n"
        }
      }
    }
    default {
      send_user "Unknown or missing response during \"passwd\" dialog.  Examine logs for $host.\n"
    }
  }
}
 
proc acctList { prompt host } {
  send "echo HIHI && cat /etc/passwd && echo LALA\n"
  expect {
    "echo LALA\r\n" {
      expect {
        -re "HIHI\r(\n.*\r)\nLALA\r" {
          set output $expect_out(1,string)
          foreach entry [ split $output "\r.*\n" ] {
            if [ string match "*:*" $entry ] {
              set groups ""
              regexp (.*):(.*):(.*):(.*):(.*):(.*):(.*) $entry ignore username blank uid gid comment homedir shell
              send "echo HIHI && cat /etc/group | grep -e .*:.*:$gid | awk -F\":\" '{ print \"RA\"\$1\"LA\" }' && echo LALA\n"
              expect "echo LALA\r\n" {
                expect {
                  -re "HIHI\r(\n.*\r)\nLALA\r" {
                    set outputg $expect_out(1,string)
                    foreach entryg [ split $outputg "\r.*\n" ] {
                      if [ string match "RA*LA" $entryg ] {
                        regexp RA(.*)LA $entryg ignore group
                        append groups "$group "
                      }
                    }
                  }
                  -re $prompt { send "\n"  }
                }
              }
              send "echo HIHI && cat /etc/group | grep -e .*:.*:.*:*$username | awk -F\":\" '{ print \"RA\"\$1\"LA\" }' && echo LALA\n"
              expect "echo LALA\r\n" {
                expect {
                  -re "HIHI\r(\n.*\r)\nLALA\r" {
                    set outputg $expect_out(1,string)
                    foreach entryg [ split $outputg "\r.*\n" ] {
                      if [ string match "RA*LA" $entryg ] {
                        regexp RA(.*)LA $entryg ignore group
                        append groups "$group "
                      }
                    }
                  }
                  -re $prompt { send "\n"  }
                }
              }
              send_user "$host,$username,$uid,$gid,$comment,$homedir,$shell,Local Account,$groups\n"
            }
          }
          expect -re $prompt { } 
 
        }
      }
    }
  } 
}
 
while {[gets $hosts line] != -1} {
  regexp ^(.*),(.*)$ $line ignore host generalist
  set login "false" 
  #send_user "$host,$generalist - "
  if {$host != ""} {
    spawn -noecho ssh -o ConnectTimeout=10 $user@$host
    expect {
      -re $prompt {
        set login "true"
      }
      "assword: " {
        send "$pass\n"
        expect {
          -re $prompt {
            set login "true"
          }
          "assword:" { 
            send_user "Login failed / Invalid Pass\n" 
          }
          default {
            send_user "Pass Response Timeout\n"
          }
        }
      }
      "(yes/no)? " {
        send "yes\n"
        expect {
          -re $prompt { 
            set login "true"
          }
          "assword: " {
            send "$pass\n"
            expect {
              -re $prompt {
                set login "true"
              }
              "assword:" { 
                send_user "Login failed / Invalid Pass\n" 
              }
              default {
                send_user "Pass Response Timeout\n"
              }
            }
          }
          default {
            send_user "Login failed\n"
          }
        }
      }
      "Connection timed out" {
        send_user "Connection timed out\n"
      }
      "Name or service not known" { 
        send_user "Name or service not known\n" 
      }
      "Connection refused" { 
        send_user "Connection refused\n" 
      }
      default {
        send_user "Login failed / Timeout\n"
      }
    }
    if { $login == "true" } {
      #if {[testSudo $prompt $pass] == true} {
        # this is where a bunch of good stuff can happen......
        #createAccount $prompt $pass
        #send_user "\n"
      #}
      #passwd $prompt $pass $newpass $host $user
      acctList $prompt $host
      send "exit\n"
    } 
  } 
} 
close $hosts
Share