Skip to content

Commit

Permalink
Merge pull request #161 from SasanLabs/Fix1
Browse files Browse the repository at this point in the history
Adding Command Injection Vulnerability Skeleton
  • Loading branch information
preetkaran20 authored Aug 1, 2020
2 parents f97473a + 5de1c2b commit b901450
Show file tree
Hide file tree
Showing 16 changed files with 392 additions and 25 deletions.
2 changes: 2 additions & 0 deletions src/main/java/org/sasanlabs/internal/utility/LevelEnum.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ public enum LevelEnum {
LEVEL_8,
LEVEL_9,
LEVEL_10,
LEVEL_11,
LEVEL_12,
SECURE;

public static LevelEnum getLevelEnumByName(String name) throws ServiceApplicationException {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
package org.sasanlabs.service.vulnerability.commandInjection;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.function.Supplier;
import java.util.regex.Pattern;
import org.sasanlabs.internal.utility.LevelEnum;
import org.sasanlabs.internal.utility.annotations.AttackVector;
import org.sasanlabs.internal.utility.annotations.VulnerabilityLevel;
import org.sasanlabs.internal.utility.annotations.VulnerableServiceRestEndPoint;
import org.sasanlabs.service.bean.ResponseBean;
import org.sasanlabs.service.exception.ServiceApplicationException;
import org.sasanlabs.service.vulnerability.ICustomVulnerableEndPoint;
import org.sasanlabs.service.vulnerability.ParameterBean;
import org.sasanlabs.service.vulnerability.bean.GenericVulnerabilityResponseBean;
import org.sasanlabs.vulnerability.types.VulnerabilitySubType;
import org.sasanlabs.vulnerability.types.VulnerabilityType;

/**
* This class contains vulnerabilities related to Command Injection. <a
* href="https://owasp.org/www-community/attacks/Command_Injection">For More information</a>
*
* @author KSASAN [email protected]
*/
@VulnerableServiceRestEndPoint(
descriptionLabel = "COMMAND_INJECTION_VULNERABILITY",
value = "CommandInjection",
type = {VulnerabilityType.COMMAND_INJECTION})
public class CommandInjection implements ICustomVulnerableEndPoint {

private static final String IP_ADDRESS = "ipaddress";
private static final Pattern SEMICOLON_SPACE_LOGICAL_AND_PATTERN = Pattern.compile("[;& ]");
private static final Pattern IP_ADDRESS_PATTERN =
Pattern.compile("\\b((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\\.|$)){4}\\b");

private StringBuilder getResponseFromPingCommand(String ipAddress, Supplier<Boolean> predicate)
throws IOException {
boolean isWindows = System.getProperty("os.name").toLowerCase().startsWith("windows");
StringBuilder stringBuilder = new StringBuilder();
if (predicate.get()) {
Process process;
if (!isWindows) {
process =
new ProcessBuilder(new String[] {"bash", "-c", "ping -c 2 " + ipAddress})
.redirectErrorStream(true)
.start();
} else {
process =
new ProcessBuilder(new String[] {"cmd", "/c", "ping -n 2 " + ipAddress})
.redirectErrorStream(true)
.start();
}
try (BufferedReader bufferedReader =
new BufferedReader(new InputStreamReader(process.getInputStream()))) {
bufferedReader.lines().forEach(val -> stringBuilder.append(val).append("\n"));
}
}
return stringBuilder;
}

@AttackVector(
vulnerabilityExposed = VulnerabilitySubType.COMMAND_INJECTION,
description = "COMMAND_INJECTION_URL_PARAM_DIRECTLY_EXECUTED")
@VulnerabilityLevel(
value = LevelEnum.LEVEL_1,
descriptionLabel = "COMMAND_INJECTION_URL_CONTAINING_IPADDRESS",
htmlTemplate = "LEVEL_1/CI_Level1",
parameterName = IP_ADDRESS,
sampleValues = {"localhost"})
public ResponseBean<GenericVulnerabilityResponseBean<String>> getVulnerablePayloadLevel1(
ParameterBean parameterBean) throws ServiceApplicationException, IOException {
String ipAddress = parameterBean.getQueryParamKeyValueMap().get(IP_ADDRESS);
Supplier<Boolean> condition = () -> ipAddress != null;
return new ResponseBean<GenericVulnerabilityResponseBean<String>>(
new GenericVulnerabilityResponseBean<String>(
this.getResponseFromPingCommand(ipAddress, condition).toString(), true));
}

@AttackVector(
vulnerabilityExposed = VulnerabilitySubType.COMMAND_INJECTION,
description =
"COMMAND_INJECTION_URL_PARAM_DIRECTLY_EXECUTED_IF_SEMICOLON_SPACE_LOGICAL_AND_NOT_PRESENT")
@VulnerabilityLevel(
value = LevelEnum.LEVEL_2,
descriptionLabel = "COMMAND_INJECTION_URL_CONTAINING_IPADDRESS",
htmlTemplate = "LEVEL_1/CI_Level1",
parameterName = IP_ADDRESS,
sampleValues = {"localhost"})
public ResponseBean<GenericVulnerabilityResponseBean<String>> getVulnerablePayloadLevel2(
ParameterBean parameterBean) throws ServiceApplicationException, IOException {
String ipAddress = parameterBean.getQueryParamKeyValueMap().get(IP_ADDRESS);
Supplier<Boolean> condition =
() ->
ipAddress != null
&& !SEMICOLON_SPACE_LOGICAL_AND_PATTERN
.matcher(parameterBean.getUrl())
.find();
return new ResponseBean<GenericVulnerabilityResponseBean<String>>(
new GenericVulnerabilityResponseBean<String>(
this.getResponseFromPingCommand(ipAddress, condition).toString(), true));
}

// Case Insensitive
@AttackVector(
vulnerabilityExposed = VulnerabilitySubType.COMMAND_INJECTION,
description =
"COMMAND_INJECTION_URL_PARAM_DIRECTLY_EXECUTED_IF_SEMICOLON_SPACE_LOGICAL_AND_%26_%3B_NOT_PRESENT")
@VulnerabilityLevel(
value = LevelEnum.LEVEL_3,
descriptionLabel = "COMMAND_INJECTION_URL_CONTAINING_IPADDRESS",
htmlTemplate = "LEVEL_1/CI_Level1",
parameterName = IP_ADDRESS,
sampleValues = {"localhost"})
public ResponseBean<GenericVulnerabilityResponseBean<String>> getVulnerablePayloadLevel3(
ParameterBean parameterBean) throws ServiceApplicationException, IOException {
String ipAddress = parameterBean.getQueryParamKeyValueMap().get(IP_ADDRESS);
Supplier<Boolean> condition =
() ->
ipAddress != null
&& !SEMICOLON_SPACE_LOGICAL_AND_PATTERN
.matcher(parameterBean.getUrl())
.find()
&& !parameterBean.getUrl().contains("%26")
&& !parameterBean.getUrl().contains("%3B");
return new ResponseBean<GenericVulnerabilityResponseBean<String>>(
new GenericVulnerabilityResponseBean<String>(
this.getResponseFromPingCommand(ipAddress, condition).toString(), true));
}

// e.g Attack
// http://localhost:9090/vulnerable/CommandInjectionVulnerability/LEVEL_3?ipaddress=192.168.0.1%20%7c%20cat%20/etc/passwd
@AttackVector(
vulnerabilityExposed = VulnerabilitySubType.COMMAND_INJECTION,
description =
"COMMAND_INJECTION_URL_PARAM_DIRECTLY_EXECUTED_IF_SEMICOLON_SPACE_LOGICAL_AND_%26_%3B_CASE_INSENSITIVE_NOT_PRESENT")
@VulnerabilityLevel(
value = LevelEnum.LEVEL_4,
descriptionLabel = "COMMAND_INJECTION_URL_CONTAINING_IPADDRESS",
htmlTemplate = "LEVEL_1/CI_Level1",
parameterName = IP_ADDRESS,
sampleValues = {"localhost"})
public ResponseBean<GenericVulnerabilityResponseBean<String>> getVulnerablePayloadLevel4(
ParameterBean parameterBean) throws ServiceApplicationException, IOException {
String ipAddress = parameterBean.getQueryParamKeyValueMap().get(IP_ADDRESS);
Supplier<Boolean> condition =
() ->
ipAddress != null
&& !SEMICOLON_SPACE_LOGICAL_AND_PATTERN
.matcher(parameterBean.getUrl())
.find()
&& !parameterBean.getUrl().toUpperCase().contains("%26")
&& !parameterBean.getUrl().toUpperCase().contains("%3B");
return new ResponseBean<GenericVulnerabilityResponseBean<String>>(
new GenericVulnerabilityResponseBean<String>(
this.getResponseFromPingCommand(ipAddress, condition).toString(), true));
}

@AttackVector(
vulnerabilityExposed = VulnerabilitySubType.COMMAND_INJECTION,
description =
"COMMAND_INJECTION_URL_PARAM_DIRECTLY_EXECUTED_IF_SEMICOLON_SPACE_LOGICAL_AND_%26_%3B_%7C_CASE_INSENSITIVE_NOT_PRESENT")
@VulnerabilityLevel(
value = LevelEnum.LEVEL_5,
descriptionLabel = "COMMAND_INJECTION_URL_CONTAINING_IPADDRESS",
htmlTemplate = "LEVEL_1/CI_Level1",
parameterName = IP_ADDRESS,
sampleValues = {"localhost"})
public ResponseBean<GenericVulnerabilityResponseBean<String>> getVulnerablePayloadLevel5(
ParameterBean parameterBean) throws ServiceApplicationException, IOException {
String ipAddress = parameterBean.getQueryParamKeyValueMap().get(IP_ADDRESS);
Supplier<Boolean> condition =
() ->
ipAddress != null
&& !SEMICOLON_SPACE_LOGICAL_AND_PATTERN
.matcher(parameterBean.getUrl())
.find()
&& !parameterBean.getUrl().toUpperCase().contains("%26")
&& !parameterBean.getUrl().toUpperCase().contains("%3B")
& !parameterBean.getUrl().toUpperCase().contains("%7C");
return new ResponseBean<GenericVulnerabilityResponseBean<String>>(
new GenericVulnerabilityResponseBean<String>(
this.getResponseFromPingCommand(ipAddress, condition).toString(), true));
}

@VulnerabilityLevel(
value = LevelEnum.LEVEL_6,
descriptionLabel = "COMMAND_INJECTION_URL_CONTAINING_IPADDRESS",
htmlTemplate = "LEVEL_1/CI_Level1",
parameterName = IP_ADDRESS,
sampleValues = {"localhost"})
public ResponseBean<GenericVulnerabilityResponseBean<String>> getVulnerablePayloadLevel6(
ParameterBean parameterBean) throws ServiceApplicationException, IOException {
String ipAddress = parameterBean.getQueryParamKeyValueMap().get(IP_ADDRESS);
return new ResponseBean<GenericVulnerabilityResponseBean<String>>(
new GenericVulnerabilityResponseBean<String>(
this.getResponseFromPingCommand(
ipAddress,
() ->
ipAddress != null
&& (IP_ADDRESS_PATTERN
.matcher(ipAddress)
.matches()
|| ipAddress.contentEquals(
"localhost")))
.toString(),
true));
}
}
Loading

0 comments on commit b901450

Please sign in to comment.