I'm using an .id_rsa file to access a user account, and I don't need it as soon as it accesses it. but I need it to keep accessing the account. I want to hide the console but don't know how. how do you do it?
#include <Windows.h>
using namespace std;
int main() {
FreeConsole();
system("ssh -L0000:proxy.com:0000 -i example.id_rsa user#00.00.0.000");
return 0;
}
It asks for a passphrase for key 'example.id_rsa':
then, it stays on console as example:~user$
Your question is vague, but if I understood your question correctly, you want to keep the ssh connection open because of the port-forwarding that it does, but don't want it to run any shell.
The solution in such is to use the "-f" and "-N" options together, i.e., "ssh -fN -L ...". The "-f" ensures that ssh goes to the background but only after asking you for the password. The "-N" asks not to execute any command remotely (not the shell and not anything else) - and just do the port forwarding.
Related
for my work I need to connect to a lot of different servers every day: telnet ti the host, enter username, enter password - commence work.
Now I wanted to make life easier by automatically entering the username - I managed to do that, but telnet quits afterwards, that's obviously not what I wanted.
I work from a system with BASH and I can't install any programs there, so please don't give answers like "Use expect, that solves your problem easily..."
My tries led me to this:
function tn() { (echo "user"
sleep 1) | telnet $1 23
}
Calling the function with tn 123.45.67.89 connects to the server at 123.45.67.89, where the username is asked, which is entered automatically - great!
But then the password is asked, and instead of letting me enter it and begin my work, the connection is closed.
I really hope someone knows a solution for this!
Thanks in advance!
You might want to look at the expect command to script interactions with telnet:
#!/usr/bin/env bash
function tn() {
expect -f <<EOF
spawn telnet $1
expect "login"
send "${2}\r"
interact
EOF
}
telnetis designed for interactive usage. Use netcat, ncat, nc, socat or any other tool of this family.
Example:
( echo "user"; sleep 1) | ncat $1 23
But if you want to simulate interactive behavior, use socat and redirect stdin+stdout to a script:
Example:
socat TCP:$1:23 EXEC:my-shell.sh
In this case, a TCP connection for address $1 port 23 is established and stdin+stdout are redirected to stdout+stdin of the script. See man socat for details and more options.
my-shell.sh look for example like:
#!/bin/sh
read line
do_domething "$line"
printf "reply\n"
read line
do_domething "$line"
printf "reply\n"
btw, I have tested nothing (just written down)
so im trying to make an if statement to tell me if an sftp connection was sucessfull or failed, and if its a sucess i want to run a piece of code that automates an sftp download that ive already made.
My problem is that this if statement executes this sftp connection, and then prompts me for a password and stalls the rest of the code.
i wanted to do something like this
if ( sftp -oPort=23 user#server )
then
expect <<-EOF
spawn sftp -oPort=23 user#server
.....
I want to know if its possible for me to make the if statement not execute the sftp connection and then not prompt me , maybe execute it on the background or something.
I would appreciate if someone could tell me if what im asking is possible, or propose a better solution to what im trying to do, thanks
You cannot not-execute a command and then react on the return value of the executed command (because this is what you really want to do: check if you can run sftp successful, and if so do a "proper" run; but you'll never know whether it can run successfull without running it).
So the main question is, what it is what you actually want to test.
If you want to test whether you can do a full sftp connection (with all the handshaking and what not), you could try running sftp in batch-mode (which is handily non-interactive).
E.g. the following runs an sftp session, only to terminate it immediately with a bye command:
if echo bye | sftp -b - -oPort=23 user#server ; then
echo "sftp succeeded"
fi
This will only succeed if the entire sftp session works (that is: you pass any key checks; you can authenticate, ...).
If the server asks you for a password, it will fail to authenticate (being non-interactive), and you won't enter the then body.
If you only want to check whether something is listening on port 23, you can use netcat for this:
if netcat -z server 23; then
echo "port:32 is open"
fi
This will succeed whenever it can successfully bind to port 23 on the server. It doesn't care whether there's an sftp daemon running, or (more likely) a telnet daemon.
You could also do some minimal test whether the remote server looks like an SSH/SFTP server: ssh servers usually greet you with a string indicating that they indeed speak ssh: something like "SSH-2.0-OpenSSH_7.2p2 Ubuntu-4ubuntu2.4".
With this information you can then run:
if echo QUIT | netcat server 23 | grep SSH; then
echo "found an ssh server"
fi
So, I've established a connection via ssh to a remote machine; and now what I would like to do is to execute few commands, grab some files and copy them back to my host machine.
I am aware that I can run
ssh user#host "command1; command2;....command_n"
and then close the connection, but how can I do the same without use the aforememtioned syntax? I have a lot of complex commands that has a bunch of quote and characters that would be a mess to escape.
Thanks!
My immediate thought is why not create a script and push it over to the remote machine to have it run locally in a text file? If you can't for whatever reason, I fiddled around with this and I think you could probably do well with a HEREDOC:
ssh -t jane#stackoverflow.com bash << 'EOF'
command 1 ...
command 2 ...
command 3 ...
EOF
and it seems to do the right thing. Play with your heredoc to keep your quotes safe, but it will get tricky. The only other thing I can offer (and I totally don't recomend this) is you could use a toy like perl to read and write to the ssh process like so:
open S, "| ssh -i ~/.ssh/host_dsa -t jane#stackoverflow.com bash";
print S "date\n"; # and so on
but this is a really crummy way to go about things. Note that you can do this in other languages.
Instead of the shell use some scripting language (Perl, Python, Ruby, etc.) and some module that takes care of the ugly work. For example:
#!/usr/bin/perl
use Net::OpenSSH;
my $ssh = Net::OpenSSH->new($host, user => $user);
$ssh->system('echo', 'Net::Open$$H', 'Quot%$', 'Th|s', '>For', 'You!');
$ssh->system({stdout_file => '/tmp/ls.out'}, 'ls');
$ssh->scp_put($local_path, $remote_path);
my $out = $ssh->capture("find /etc");
From here: Can I ssh somewhere, run some commands, and then leave myself a prompt?
The use of an expect script seems pretty straightforward... Copied from the above link for convenience, not mine, but I found it very useful.
#!/usr/bin/expect -f
spawn ssh $argv
send "export V=hello\n"
send "export W=world\n"
send "echo \$V \$W\n"
interact
I'm guessing a line like
send "scp -Cpvr someLocalFileOrDirectory you#10.10.10.10/home/you
would get you your files back...
and then:
send "exit"
would terminate the session - or you could end with interact and type in the exit yourself..
I've a script that launches inside of itself a command with a parameter that is a secret. For example:
#!/bin/bash
command-name secret
While running the command I can read through ps -ef | grep command-name which is the secret.
Is there any way of hiding the secret in a way that through ps -ef, the command line parameter is obfuscated?
First, you can NOT hide command line arguments. They will still be visible to other users via ps aux and cat /proc/$YOUR_PROCESS_PID/cmdline at the time of launching the program (before the program has a chance to do run-time changes to arguments). Good news is that you can still have a secret by using alternatives:
Use standard input:
mySecret='hello-neo' printenv mySecret | myCommand
Use a dedicated file if you want to keep the secret detached from the main script (note that you'd be recommended to use full disc encryption and make sure the file has correct chmod permissions):
cat /my/secret | myCommand
Use environment variables (with caveats). If your program can read them, do this:
mySecret='hello-neo' myCommand
Use temporary file descriptor:
myCommand <( mySecret='hello-neo' printenv mySecret )
In the last case your program will be launched like myCommand /dev/fd/67, where the contents of /dev/fd/67 is your secret (hello-neo in this example).
In all of the above approaches, be wary of leaving the command in bash command history (~/.bash_history). You can avoid this by either running the command from a script (file), or by interactively prompting yourself for password each time:
read -s secret
s=$secret printenv s | myCommand # approach 2
myCommand <( s=$secret printenv s ) # approach 3
secret=$secret myCommand # approach 4
export secret && myCommand # another variation of approach 4
If the secret doesn't change between executions, use a special configuration file, ".appsecrets". Set the permissions of the file to be read-only by owner. Inside the file set an environment variable to the secret. The file needs to be in the home directory of the user running the command.
#!/bin/bash
#filename: .appsecrets
set SECRET=polkalover
Load the config file so the environment variable gets set.
. ~/.appsecrets
What I've seen done:
1)
echo $SECRET | command
works if the command prompts for the password from stdin AND if 'echo' is a builtin of your shell. We were using Korn.
2)
password=$ENV{"SECRET"};
works if you have control of the code (e.g. in perl or C++)
3)
. ./.app.config #sets the environment variables
isql -host [host] -user [user] -password <<SECRET
${SQLPASSWORD}
SECRET
works if the command can accept the secret from std-in. One limitation is that the <<string has to be the last argument given to the command. This might be troublesome if there is a non-optional arg that has to appear after -password
The benefit of this approach is you can arrange it so the secret can be hidden in production. Use the same filename in production but it will be in the home directory of the account that runs the command in production. You can then lock down access to the secret like you would access to the root account. Only certain people can 'su' to the prod account to view or maintain the secret while developers can still run the program because they use their own '.appsecret' file in their home directory.
You can use this approach to store secured information for any number of applications, as long as they use different environment variable names for their secrets.
(WRONG WAY)
One old method I saw the DBAs use was to set SYBASE to "/opt/././././././././././././././././././././././././././././././././././sybase/bin". So their commandlines were so long the ps truncated it. But in linux I think you might be able to sniff out the full commandline from /proc.
I saw it on another post. This is the easiest way under Linux.
This modifies the memory part of command line that all other programs see.
strncpy(argv[1], "randomtrash", strlen(argv[1]));
You can also change the name of the process, but only when read from the command line. Programs like top will show the real process name:
strncpy(argv[0], "New process name", strlen(argv[0]));
Don't forget to copy maximum strlen(argv[0]) bytes because probably there's no more space allocated.
I think that arguments can only be found in the portion of the memory that we modify so I think that this works like a charm. If someone knows something accurate about this, please comment.
VasyaNovikov note: The password can still be intercepted after the program has invoked but before it started doing the changes you described.
The only way to conceal your secret argument from ps is not to provide the secret as an argument. One way of doing that is to place the secret in a file, and to redirect file descriptor 3 to read the file, and then remove the file:
echo secret > x.$$
command 3<x.$$
rm -f x.$$
It isn't entirely clear that this is a safe way to save the secret; the echo command is a shell built-in, so it shouldn't appear in the 'ps' output (and any appearance would be fleeting). Once upon a very long time ago, echo was not a built-in - indeed, on MacOS X, there is still a /bin/echo even though it is a built-in to all shells.
Of course, this assumes you have the source to command and can modify it to read the secret from a pre-opened file descriptor instead of from the command line argument. If you can't modify the command, you are completely stuck - the 'ps' listing will show the information.
Another trick you could pull if you're the command owner: you could capture the argument (secret), write it to a pipe or file (which is immediately unlinked) for yourself, and then re-exec the command without the secret argument; the second invocation knows that since the secret is absent, it should look wherever the first invocation hid the secret. The second invocation (minus secret) is what appears in the 'ps' output after the minuscule interval it takes to deal with hiding the secret. Not as good as having the secret channel set up from the beginning. But these are indicative of the lengths to which you have to go.
Zapping an argument from inside the program - overwriting with zeroes, for example - does not hide the argument from 'ps'.
The expect library was created partially for these kind of things, so you can still provide a password / other sensitive information to a process without having to pass it as an argument. Assuming that when 'secret' isn't given the program asks for it of course.
There's no easy way. Take a look at this question I asked a while ago:
Hide arguments from ps
Is command your own program? You could try encrypting the secret and have the command decrypt it before use.
You can use LD_PRELOAD to have a library manipulate the command line arguments of some binary within the process of that binary itself, where ps does not pick it up. See this answer of mine on Server Fault for details.
Per the following article:
https://www.cyberciti.biz/faq/linux-hide-processes-from-other-users/
you can configure the OS to hide / separate the processes from each other with the hidepid mount option for the /proc, requires Linux kernel 3.2+.
may be you can do like this:
#include <boost/algorithm/string/predicate.hpp>
void hide(int argc, char** argv, std::string const & arg){
for(char** current = argv; current != argv+ argc ;++current){
if(boost::algorithm::starts_with(*current, "--"+arg)){
bzero(*current, strlen(*current));
}
}
}
int main(int argc, char** argv){
hide(argc, argv, "password");
}
Here is one way to hide a secret in an environment variable from ps:
#!/bin/bash
read -s -p "Enter your secret: " secret
umask 077 # nobody but the user can read the file x.$$
echo "export ES_PASSWORD=$secret" > x.$$
. x.$$ && your_awesome_command
rm -f x.$$ # Use shred, wipe or srm to securely delete the file
In the ps output you will see something like this:
$ps -ef | grep your_awesome_command
root 23134 1 0 20:55 pts/1 00:00:00 . x.$$ && your_awesome_command
Elastalert and Logstash are examples of services that can access passwords via environment variables.
If the script is intended to run manually, the best way is to read it in from STDIN
#!/bin/bash
read -s -p "Enter your secret: " secret
command "$secret"
I always store sensitive data in files that I don't put in git and use the secrets like this:
$(cat path/to/secret)
I have a tcl script that calls a lot of functions from bash including ssh. The part I'm struggling with looks like this:
proc connect {where} {
set bash c:/cygwin/bin/bash
catch {exec $bash -c "ssh $where"} result
puts $result
}
connect user#localhost
I get the authentication failed message:
Pseudo-terminal will not be allocated because stdin is not a terminal.
Permission denied, please try again.
Permission denied, please try again.
Permission denied (publickey,password,keyboard-interactive).
I can't figure out how to prompt (either showing the console or a tk window, doesn't really matter) the user for the password so the authentication goes through.
The reason I'm using bash to ssh is because eventually I want to connect to a github with the script (need to prompt for a passkey).
Try this:
puts -nonewline "enter your passphrase: "
flush stdout
gets stdin passphrase
exec $bash -c "ssh $where" << $passphrase
The << argument to exec passes the given value to the command on its stdin
If that doesn't work, you'll have to try Expect, or use a key with no passphrase.
One important alternative (which I advise) is to set up a local key-handling agent (e.g., ssh-agent or pageant) to hold the decrypted key so that your code doesn't need to handle passwords at all. I find that's a much simpler method overall because it stops a lot of code from having to understand anything about passwords (which are harder to handle correctly than you might thinkā¦)