executing jar with arguments Hide text of some arguments - cmd

I have a jar file that accepts the arguments, one of the argument is a password, is there a way to mask password when executing jar in CMD? maybe in Java code argument can be masked or I don't reveal sensitive information? something like there is in Linux command when typing the password noting is shown in terminal?
public static void main(String [] args) {
String username = args[0]; //=="user"
String password = args[1]; //=="pass"
}
and in cmd executing it
java -jar jarFile.jar username password
is there a way to hide that password in the second argument?

Related

How can i Print own Error Message on Java Jar CMD

how can I Print adittional information to Command line Console?
Output now is:
C:\Users\admin\Desktop\java>java -jar pdf.jar
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0
at readDataIn.main(readDataIn.java:31)
Code:
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
try {
String arg = args[0];
fileNameSource = "import/" + arg + ".xml";
fileNameTarget = "export/" + arg + ".pdf";
} catch (Exception e) {
// TODO: handle exception
**System.out.println("Personal-Number is missing");**
e.printStackTrace();
}
How can i give the information out, that the Personal Number ist Missing?
First of all, as a general rule you should check for possible exceptions before they actually occur if that is possible, which in your case it definitely is.
So instead of catching the ArrayIndexOutOfBounds insert an if statement that checks the length of the args array before accessing it.
if(args.length == 0){
// no argument has been provided
// handle error here
}
In terms of how to handle the error, there are many options available and depending of what you want to do either could be a good fit.
IllegalArgumentException
It is a common idiom in Java that whenever a function receives an invalid/ illegal argument to throw an IllegalArgumentException.
if (args.length == 0){
throw new IllegalArgumentException("Personal number is missing");
}
This will print the message that you have provided and the stack trace. However if your application should be a Command Line Interface (CLI) you should not use this kind of error handling.
Print message & exit program
if (args.length == 0){
// notice: "err" instead of "out": print to stderr instead of stdout
System.err.println("Personal number is missing");
// exit program with non-zero exit code as exit code == 0 means everything is fine
System.exit(1);
}
For more information on stdout and stderr see this StackOverflow question.
This is what many CLI applications and e.g. java itself does. When you type java fdsdfsdfs or some similar nonsense as an argument Java will give you an error message and exit with some non-zero return code ("1" in this case).
It is also common that CLI applications print an error message and following some usage information on how to correctly use the application or provide a help command so a user can get more information. This happens for example if you just enter java without any parameters.
So it is really up to you what you want to do.
If you are thinking of implementing a full featured CLI application with more (complex) commands with multiple options etc. you should consider using a CLI library like JCommander or Apache Commons CLI as parsing command line arguments can quickly get ugly. All these common things are already handled there.
Logging
In case your application is some script that will be executed in a non-interactive way logging the error to a file and exiting with a non-zero exit code might also be an option.
PS
Your code looks to me like it should not compile at all as you are not declaring a type for your variables fileNameSource and fileNameTarget.
Use String or var here (assuming you're running > Java 11).
String fileNameSource = "import/" + arg + ".xml";
var fileNameTarget = "export/" + arg + ".pdf";
You might also need to consider that your program name is part of the args array, so you might have more than 0 values in the array and therefore might need to adjust the if statements above.
You may be interested in picocli, which is a modern CLI library for Java and other JVM languages.
Picocli does some basic validation automatically, and results in very compact code that produces user-friendly applications. For example:
import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
import picocli.CommandLine.Parameters;
#Command(name = "myapp", mixinStandardHelpOptions = true, version = "1.0",
description = "This command does something useful.")
class MyApp implements Runnable {
#Parameters(description = "File name (without extension) of the file to import and export.")
private String personalNumber;
#Override
public void run() {
String fileNameSource = "import/" + personalNumber + ".xml";
String fileNameTarget = "export/" + personalNumber + ".pdf";
// remaining business logic
}
public static void main(String[] args) {
System.exit(new CommandLine(new MyApp()).execute(args));
}
}
If I run this class without any parameters, the following message is printed to the standard error stream, and the process finished with exit code 2. (Exit codes are customizable.)
Missing required parameter: '<personalNumber>'
Usage: myapp [-hV] <personalNumber>
This command does something useful.
<personalNumber> File name (without extension) of the file to import
and export.
-h, --help Show this help message and exit.
-V, --version Print version information and exit.
The usage help message is created automatically from the descriptions of the command, and the descriptions of its options and positional parameters, but can be further customized.
Note how the mixinStandardHelpOptions = true annotation adds --help and --version options to the command. These options are handled by the library without requiring any further logic in the application.
Picocli comes with an annotation processor that makes it very easy to turn your application into a native image with GraalVM. Native images have faster startup time and lower runtime memory overhead compared to a Java VM.

How should ESAPI executeSystemCommand sanitise the file path properly to satisfy Veracode check?

I invoke the external command within my Java app with Runtime.getRuntime().exec() or ProcessBuilder. Works fine but Veracode complains on it with CWE-78. I'm trying to use ESAPI wrapper to sanitise the input and path the check.
The arfifact is the latest
<dependency>
<groupId>org.owasp.esapi</groupId>
<artifactId>esapi</artifactId>
<version>2.2.3.1</version>
</dependency>
ESAPI.properties are
ESAPI.Logger=org.owasp.esapi.logging.slf4j.Slf4JLogFactory
Logger.LogEncodingRequired=false
Logger.UserInfo=false
Logger.ClientInfo=false
Logger.LogApplicationName=false
Logger.ApplicationName=my-app
Logger.LogServerIP=false
IntrusionDetector.Disable=true
Executor.ApprovedExecutables=/usr/bin/less
The code is:
#Test
void esapiTest() throws ExecutorException {
Executor executor = DefaultExecutor.getInstance();
ExecuteResult executeResult = executor.executeSystemCommand(
new File("/usr/bin/less"),
new ArrayList<>(Collections.singletonList("/etc/hosts"))
);
System.out.println("out = " + executeResult.getOutput());
System.out.println("err = " + executeResult.getErrors());
}
The output is
out =
err = \/etc\/hosts: No such file or directory
As far as I got the issue is that ESAPI's UnixCodec sanitises all non-alpha character with the backslash. This is fine for the shell i.e.
/usr/bin/less \/etc\/hosts
but not for the ProcessBuilder that is under the hood.
What am I doing wrong? How to invoke the command?
I think your main "problem" is misunderstanding that the ESAPI Codecs that are used with the DefaultExecutor class are assuming that any "OS command injection" is being interpreted via a "command line interpreter", i.e., a "shell". You are not invoking a shell here. If you were, the shell would remove the (in this case) backslash escaped argument from your path for "/etc/hosts". So if this were written as (say) the command:
/bin/sh -c /usr/bin/less /etc/hosts
it would [sort of] work (except if you tried running it over HTTP, the input to 'less' my be hosed; but "/bin/cat" ought to work fine).
Instead, try writing your test something like this:
#Test
void esapiTest() throws ExecutorException {
Executor executor = ESAPI.executor();
File binSh = new File("/bin/sh").getCanonicalFile();
List params = new ArrayList();
params.add("-c");
//Use '/bin/cat' because 'less' may be troublesome
params.add("\"" + "/bin/cat" + "/etc/hosts" + "\"");
ExecuteResult executeResult = executor.executeSystemCommand(binSh, params);
System.out.println("out = " + executeResult.getOutput());
System.out.println("err = " + executeResult.getErrors());
}
Note 1: If you I'm not sure how user-friendly ProcessBuilder is with commands that eventually try to do ioctl system calls to set the tty device in 'raw' mode, like commands such as "vim" or "less", which is why I changed your "/usr/bin/less" to "/bin/cat". YMMV.
Note 2: In your ESAPI.properties file, you'd have to make sure that the property 'Executor.ApprovedExecutables' is set to whatever the canonical name of "/bin/sh" is on your system. E.g., on my system, "/bin/sh" is a symbolic link to "/bin/dash", so you would have to include something like
Executor.ApprovedExecutables=/bin/bash,/bin/dash
(or at least "/bin/dash") should work.

Add password to package in gradle

I packed a zip containing a list of webapps with gradle.
At the end, I would like to add a password to the zip.
I tried to user commandLine passing the linuz command "zipcloak", then the psw in required twice and I'm not able to send it to the command line:
commandLine ("zipcloak", zip_name + ".zip")
setStandardInput ("psw")
setStandardInput ("psw")
Maybe there is a better solution to do this...
Thanks
EDIT:
I progressed by adding this lines:
commandLine "zipcloak", "zipname.zip"
ByteArrayOutputStream bytes = new ByteArrayOutputStream()
PrintWriter out = new PrintWriter(bytes)
out.println("psw")
out.println("psw")
out.flush()
ByteArrayInputStream input = new ByteArrayInputStream(bytes.toByteArray())
standardInput = input
Now the command is executed and I see on the console the request of the password, but I'm not still able to send a string to this request directly from the script, I have to add it manually on the console...
EDIT - SOLUTION FOUND:
I found the solution: instead of adding a password to an existing zip, I packed the zip WITH password
task encodeZip(type: Exec) {
workingDir path_target_workspace
commandLine "zip", "-P", "password", "-r", "zipname.zip", "file1", "file2", "fil3" .....
}
Hope it helps

connecting the setInputStream and setOutputStream of the JSch to jTextField's

I am new to java and i need help.
I use the jsch libraries to create a SHH connection to a remote linux machine. In the next code, given from a tutorial of the JSCH creator, you can see it is implemented shell communication, it is a direct communication from a cmd window. You enter a command from the cmd window and you get aback the results in the cmd window.
String user = "username";
String host = "hostname";
session session=jsch.getSession(user, host, 22);
String passwd = JOptionPane.showInputDialog("Enter password");
session.setPassword(passwd);
Channel channel=session.openChannel("shell");
session.connect();
channel.setInputStream(System.in);
channel.setOutputStream(System.out);
How i can connect the next two lines to jTextField1 and jTextField2. To give an example i want to sen the command from the jTextField1 and to get the results from the jTextField2.
channel.setInputStream(System.in);
channel.setOutputStream(System.out);
Thank you in advanced
Instead of System.in you can give your desired stream .For example
String ls = "ls \n"; // here i am passing a string to stream, you can pass as you desire
InputStream in = new ByteArrayInputStream(ls.getBytes("UTF-8"));
channel2.setInputStream(in);//you passed the string as input
ByteArrayOutputStream out = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(out);
channel2.setOutputStream(ps);
String result = out.toString();//here we get output to a string which you can add to your file.
This is one option There may be better ways.

Remote Desktop Connection by making .bat file

I want to connect my pc to another pc by making .bat file. When i run that file it should connect to the other pc. I wrote "mstsc /v:192.168.15.102" command when i execute this file it opens remote desktop window and demands username and password. How can i avoid that window and pass the credential in .bat file.
I found this
cmdkey /generic:TERMSRV/$server /user:$user /pass:$Password
mstsc /v:$Server
from archive (or original)
But I think that's for powershell only and I'm inexperienced with windows.
Along the comments I also saw this one:
For people that were looking for this idea but want to use batch instead I created the following. Save this a mstscup.cmd from notepad (don’t forget to remove the .txt at the end!)
Call it from the command line as follows:
mstscup “servername” “user” “pass”
I didn’t like the idea of leaving the user and pass in the password vault so it clears it after 120 seconds (leaves a command prompt window opened).
Feel free to modify at will!
#echo off
setlocal
:: Check if the user passed at least 1 argument
if “%1%” == “” (
echo Remoted Desktop connection with user and password
echo.
echo Missing arguments. Syntax:
echo %~nx0% “servername” “username” “password”
echo.
echo Jean Morin, v0.1, 2013-02-23
pause
goto :eof
)
:: Next line removes surrounding quotes from server name
set sServer=%~1%
:: Keep the quotes for the username and password (in case spaces exists)
set sUser=%2%
set sPass=%3%
:: Seconds to wait before clearing the newly added password from the vault (see control panel, manage your credentials)
:: You may want to modify this if the server takes longer to connect (WAN). You could add this as a fourth argument.
set sSeconds=120
:: Add a new connection definition method to the vault
cmdkey /generic:TERMSRV/%sServer% /user:%sUser% /pass:%sPass%
:: Connect to the server as a new task
start mstsc /v:%sServer%
:: ping ourselves for x seconds (acts like a pause) then removes the newly added password from the vault
ping -n %sSeconds% 127.0.0.1 >nul:
cmdkey /delete:TERMSRV/%sServer%
Best solution I could find was saving an rdp config.
Relatively much simpler than these options.
So open Remote Desktop Connection through start menu or win+r mstsc.exe.
Then select advanced options, change everything you want, and Save As.
This will create an .rdp file that can be clicked to run or run in command prompt.
:)
Remote Login using java and batch file by double click
Create batch file Remote.bat and write the following code,
#echo off
java Remote DEV
Create a java file Remote.java and write following code,
also change the IP address of your remote computer in code.
import java.awt.MouseInfo;
import java.awt.Robot;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.util.concurrent.TimeUnit;
public class Remote
{
public static void main(String args[])
{
try
{
//showPosition();
System.out.println("Remote Desktop for-->"+args[0]);
String IP = "";
if("DEV".equalsIgnoreCase(args[0]))
{
IP = "mstsc /v:10.0.41.101";
}
else if("UAT".equalsIgnoreCase(args[0]))
{
IP = "mstsc /v:10.0.45.43";
}
else if("PRE-PROD".equalsIgnoreCase(args[0]))
{
IP = "mstsc /v:10.0.45.209";
}
Process p = Runtime. getRuntime(). exec(IP);
Robot bot = new Robot();
long mask = InputEvent.MOUSE_EVENT_MASK;
TimeUnit.SECONDS.sleep((long) 2.5);
bot.mouseMove(607, 290);
bot.mousePress((int) mask);
bot.mouseRelease((int) mask);
bot.keyPress(KeyEvent.VK_SHIFT);
bot.keyPress(KeyEvent.VK_Y);
bot.keyRelease(KeyEvent.VK_SHIFT);
bot.keyPress(KeyEvent.VK_E);
bot.keyPress(KeyEvent.VK_S);
bot.keyPress(KeyEvent.VK_B);
bot.keyPress(KeyEvent.VK_A);
bot.keyPress(KeyEvent.VK_N);
bot.keyPress(KeyEvent.VK_K);
bot.keyPress(KeyEvent.VK_1);
bot.mouseMove(765, 508);
bot.mousePress((int) mask);
bot.mouseRelease((int) mask);
}
catch (Exception e)
{
System.out.println("Exception send--->"+e.getMessage());
e.printStackTrace();
}
}
public static void showPosition() throws InterruptedException
{
try
{
while(true == true)
{
TimeUnit.SECONDS.sleep(1/2);
double mouseX = MouseInfo.getPointerInfo().getLocation().getX();
double mouseY = MouseInfo.getPointerInfo().getLocation().getY();
System.out.println("X:" + mouseX);
System.out.println("Y:" + mouseY);
//make sure to import
}
}
catch(Exception e)
{
System.out.println("Excpetion inside showPosition-->"+e.getMessage());
}
}
}
Now save the code and double click on Remote.bat.
it will automatically open your remote computer.
Enjoyyyyyyy

Resources