Hiding password field in command line - c

I am writing a system service on FreeBSD where I need to take user credentials to verify identity, something like this:
./compression_bin -i <input_file> --type=<type> --password=<secret key>
Here, the secret key is used to authenticate user before compressing the given file. Currently, the secret key shows up in history which is bad and can be exploited. Is there a way where above can be invoked without displaying password field:
./compression_bin -i <input_file> --type=<type> --password=*********

The history will always record the text of the commands as they were issued. You could conceivably go back and modify the history file, but not only is that nasty, it still affords a window within which the password can be read.
Moreover, that's not even the easiest exploit. If the password is given on the command line then there are other ways it can be read while the command is running, such as from the output of the ps command, which is accessible to all users.
So don't take the password as a command-line argument. Read it from a file or from the standard input or from a socket, or some other such thing.

Related

Storing sensitive data within the source of compiled programs

In this example usage of libcurl the program will "log in" to an IMAP server using a user and secret password string, stored in two separate strings within the source, for the sake of brevity. Most real email clients (gnus, mutt) read from a plain text config file or an encrypted file, if I were to compile the example file with a real username and secret key, would it be possible to decompile the binary produced to parse the private key? I imagine a private key entered into a macro before compilation is more secure than reading a config file after compiling, is this understanding correct?
If the username and secret are strings and are simply included in the source, they can be extracted from the binary executable without even decompiling. See the strings command. You can take steps to include the username and secret in the source such that they are not readily findable by strings (e.g., by XORing the string with some other bit pattern in the program before adding it, then XORing in the executable to recover the original). This is "security through obscurity," however, and is not recommended.
Placing the username and secret in a configuration file lets you use the system's file permissions so that people using the binary may not necessarily have permission to read the file. You may also be able to set up a PKI authentication arrangement, or possibly use Kerberos key authorization.
The amount of effort to go to depends on the value of what you're trying to protect.

Check if program is being piped

I'm writing a program that speeds up the git push operation. Here's what it needs to do:
printf("[github-username]\n[github-password]");
I'd then use it like so:
git-autologin | git push
But I don't want there to be any chance of someone simply typing git-autologin or git-autologin > file.txt and being able to see my username and password. I know it sounds silly 'cause anyone can still automate the git commands but it's unlikely that any untrusted user will ever get on my system.
My question: How could I tell if standard output is writing to a file/terminal or if it's being piped?
Edit: The git push pipe was simply an idea, not the only reason I'm asking.
Edit: Is there any way to determine the PID or more information about the process it's being piped to?
You can detect when stdout is a terminal by using (on Linux & POSIX!) the isatty(3) function, probably as isatty(STDOUT_FILENO)
So you could guess that if isatty(STDOUT_FILENO) is false, the standard output is would be redirected or piped.
Alternatively, use fstat(2) as fstat(STDOUT_FILENO, &stdoutstat);
But you should set up ssh correctly (with credentials, STFW for any SSH tutorial!) on your system, to avoid having git asking any password.

ftp file upload fails when special character is present in password

I was trying to upload a file through application i wrote in c.
As i did not find any API, i decided to go through commands.
Input command line looked like this.
ftp -u ftp://ftpuser:password#123#x.x.x.x/test.txt /tmp/test.txt
Whenever a special character is present, login will fail. when i tried with different user without any special characters in the password upload works.
How this issue can be resolved or is there any another method available like API which can be made use of.
If any sample code available then it will be of great help.
Special character means #, $, # (Ex : password#123, password$123)
code snippet:
RunCommandWithPipe(PSTRING CmdLine)
{
FILE *fp;
int status;
fp = popen(CmdLine, "r");
if (fp == NULL)
{
ErrGen(constErrOpenFile);
}
status = pclose(fp);
if (status == -1)
{
ErrGen(constErrCloseFile);
}
}
The reason why this doesn't work is because you are passing unfiltered meta characters into the shell. This is very dangerous. If someone untrustworthy gets to decide the value of any of the parameters to your ftp command, such as the username, password, ftp server, or file name, then that person will be able to run arbitrary shell commands.
You can see what's going on by putting an "echo" in front of your ftp command:
echo ftp -u ftp://ftpuser:password$123#x.x.x.x/test.txt /tmp/test.txt
You'll get this result:
ftp -u ftp://ftpuser:password23#x.x.x.x/test.txt /tmp/test.txt
The shell is trying to evaluate $1 as a variable, leaving an empty result.
There's a couple of things you can do.
1) Make the command safe by escaping all the meta characters. Here you need to be very careful, using a whitelist approach rather than just trying to get rid of the special characters you've thought of. In the whitelist approach you accept that some set of characters are safe, such as [A-Za-z0-9:_-]. Every other character you either strip out or escape by preceding it with a backslash. (eg. "foo:bar$baz&abc" becomes "foo:bar\$bazabc") If you do this way don't try to think of all the characters you know of that are special and escape those. You will most likely forget some, and not handle input this like:
ftp -u ftp://ftpuser:; rm -rf /;echo #x.x.x.x/test.txt /tmp/test.txt
2) Don't pass arguments on the shell, instead control the FTP client through fread()/fwrite() on the pipe that popen() gave you.
In this case what you do is launch the ftp client with no arguments. Then you write "OPEN 192.168.1.1" or wherever you want to connect. Then you write the username. Then you write the password. Then you write the GET or PUT command want. Then you write "EXIT" or write an EOF. You should read the result codes from the server. You'll get 200 series results on success. You'll get a 500 series result if the login is bad, etc.
You still have to watch out when piping into the FTP command because it will take shell escapes like "!rm -rf /", but there is much less opportunity for that than on the shell. You just need to make sure the strings you get to build your FTP commands are one line and that you always precede them with a valid FTP command. You should also watch out for any funny business with untrustworthy filenames. (eg. don't allow absolute paths, "..", and so forth)
You propably using a wrong charset to send the password

Passing value to prompt open by an exe via batch file

I'm trying to use OpenGPG and when trying to decrypt something It opens up a prompt for the password. Now I'm trying to run this automatically therefore none to enter password. So My question is how do you pass in the password to this new prompt opened up by the exe I'm running form the batch file. Ive looked in gpg2.exe -help and there is no way to pass in the password as a parameter if anyone is familiar with OpenGPG or if there is a command I can run to pass the password into the new prompt, that would be great.
gpg2.exe -o output.txt -d series.txt.gpg
After many attempts at trying to get this working I, finally checked out the manual for gpg2.exe at http://linux.die.net/man/1/gpg2 and after adding the command line argument --batch the --passphrase is accepted by the application.
Not doing so results in the user being prompted.
Hope this helps anyone in the future attempting to do this hack.
echo password | gpg2.exe -o output.txt -d series.txt.gpg
GnuPG offers multiple ways to pass the passphrase non-interactively. Using the parameter --passphrase [password] is probably the most simple one, depending on your use case the others also could be of interest (for example if you do not want to store the passphrase within your application code).
From man gpg:
--passphrase-fd n
Read the passphrase from file descriptor n. Only the first line will be read
from file descriptor n. If you use 0 for n, the passphrase will be read from
STDIN. This can only be used if only one passphrase is supplied.
--passphrase-file file
Read the passphrase from file file. Only the first line will be read from
file file. This can only be used if only one passphrase is supplied. Obvi-
ously, a passphrase stored in a file is of questionable security if other
users can read this file. Don't use this option if you can avoid it.
--passphrase string
Use string as the passphrase. This can only be used if only one passphrase
is supplied. Obviously, this is of very questionable security on a multi-
user system. Don't use this option if you can avoid it.

How to verify password on Unix (HPUX)

I'm writing a user daemon and when the user logs on, I want to make sure that the user is the one who started the daemon. Reason is, that I need some way of running commands which can take a lot of time. Using nohup for this has some drawbacks, like I can not interact with the process anymore, so the daemon should watch these processes and allow me to interact with them.
The problem now is, how can I verify the password, as the user will not have permission to read the shadowfile and the /etc/passwd passwort is not set.
You could use the PAM to check the user / passwd. It's also present in Unix systems. You should check the interfaces which are implemented in HPUX.
https://www.ibm.com/developerworks/linux/library/l-pam/
Im not sure on how to do daemons, but I do know that in C, all you would have to do is, create a string and check whether or not that is what the user types in.
have it accept what the user sets:
// accept
printf("1. login \n 2. create information ");
this gives them the option, then switch the options, case 1 being the information for logging in, and then case 2 being the option that allows them to type in the information, and you saving it in something to be read later, and determining if it already created or not.
Hope this helps!

Resources