Skip to content

Commit

Permalink
Fix multi-params injection and various bugs
Browse files Browse the repository at this point in the history
- Vendor MemSQL: change ending comment to empty
- New i18n language: Korean (ko)
- Add new payload paths
- Joined UML class diagram
- Change Chinese fonts to Ubuntu Regular
- Change while:readLine() to while:read(buffer) to read page sources
- Fix bug preventing multi-params injection (* erased)
- Test ErrorStream for null before using it

- Fix ron190#53774: null SimpleEntry parameters replaced by empty String
- Fix ron190#53778: Catch any Exception on getSource() from a connection
- Fix ron190#53776: Remove decoding character %xy in URL parameters
- Fix ron190#54320: Update i18n for French
- Fix ron190#53699, Fix ron190#53637, Fix ron190#53632: adding new items to Scan List
using context menu 'New Value(s)'
- Fix ron190#53736: ArrayIndexOutOfBoundsException on setText()
- Fix ron190#54575: NullPointerException on setSelectedIndex()
- Fix ron190#54573: NullPointerException on setText()
- Fix ron190#54572: NullPointerException on setText()
  • Loading branch information
ron190 committed Sep 23, 2017
1 parent d222031 commit ea21e38
Show file tree
Hide file tree
Showing 55 changed files with 522 additions and 380 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ If you are using Kali Linux then get the latest release using command `sudo apt-
`New SQL Structure: Dump In One Shot and Zipped, Database: MemSQL Couchbase, Dump to a file, Load from/to no. of row/char, User Agent configuration.`

## Since last release
`-`
`Fix bug preventing multi-params injection, Fix adding items to Scan list`

## Change log

Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>jsql-injection</groupId>
<artifactId>jsql-injection</artifactId>
<version>v0.80</version>
<version>v0.81</version>

<repositories>
<repository>
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/jsql/i18n/jsql.properties

Large diffs are not rendered by default.

22 changes: 21 additions & 1 deletion src/main/java/com/jsql/i18n/jsql_fr.properties
Original file line number Diff line number Diff line change
Expand Up @@ -481,4 +481,24 @@ LOG_FETCHING_DATABASES=R
LOG_DONE=Fait
SCANLIST_TAB=Scan par lot
SCANLIST_TAB=Scan par lot
RENAME_NODE=Renommer...
SQLENGINE_STANDARD=Standard
SQLENGINE_ZIPPED=Zippé
SQLENGINE_DIOS=DIOS
SQLENGINE_NORMAL=Normal
SQLENGINE_ERROR=Erreur
SQLENGINE_BOOLEAN=Booléen
SQLENGINE_ORDER_BY=Trier par
LOG_DATABASE_TYPE_FORCED_BY_USER=Type de base de données forcé par l'utilisateur à

LOG_DATABASE_TYPE_NOT_FOUND=Type de base de données indéterminé, forcé à
90 changes: 45 additions & 45 deletions src/main/java/com/jsql/i18n/jsql_zh.properties

Large diffs are not rendered by default.

83 changes: 30 additions & 53 deletions src/main/java/com/jsql/model/InjectionModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public class InjectionModel extends AbstractModelObservable {
/**
* Current version of application.
*/
private static final String VERSION_JSQL = "0.80";
private static final String VERSION_JSQL = "0.81";

public static final String STAR = "*";

Expand Down Expand Up @@ -168,14 +168,6 @@ public void resetModel() {

ThreadUtil.reset();
}

private static String decode(final String encoded) {
try {
return encoded == null ? "" : URLDecoder.decode(encoded, "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Impossible: UTF-8 is a required encoding", e);
}
}

/**
* Prepare the injection process, can be interrupted by the user (via shouldStopAll).
Expand Down Expand Up @@ -292,10 +284,10 @@ private boolean testParameters(MethodInjection methodInjection, String paramsAsS
ConnectionUtil.setMethodInjection(methodInjection);
if (!methodInjection.isCheckingAllParam() && !paramsAsString.contains(InjectionModel.STAR)) {
params.stream().reduce((a, b) -> b).ifPresent(e -> e.setValue(e.getValue() + InjectionModel.STAR));
hasFoundInjection = this.testStrategies(true, false, params.stream().reduce((a, b) -> b).get());
hasFoundInjection = this.testStrategies(IS_CHECKING_ALL_PARAMETERS, !IS_JSON, params.stream().reduce((a, b) -> b).get());
} else if (paramsAsString.contains(InjectionModel.STAR)) {
LOGGER.info("Checking single "+ methodInjection.name() +" parameter with injection point at *");
hasFoundInjection = this.testStrategies(false, false, null);
hasFoundInjection = this.testStrategies(!IS_CHECKING_ALL_PARAMETERS, !IS_JSON, null);
} else {
for (SimpleEntry<String, String> paramBase: params) {

Expand Down Expand Up @@ -323,7 +315,7 @@ private boolean testParameters(MethodInjection methodInjection, String paramsAsS

try {
LOGGER.info("Checking JSON "+ methodInjection.name() +" parameter "+ parentXPath.getKey() +"="+ parentXPath.getValue().replace(InjectionModel.STAR, ""));
hasFoundInjection = this.testStrategies(true, true, paramBase);
hasFoundInjection = this.testStrategies(IS_CHECKING_ALL_PARAMETERS, IS_JSON, paramBase);
break;
} catch (JSqlException e) {
LOGGER.warn("No "+ methodInjection.name() +" injection found for JSON "+ methodInjection.name() +" parameter "+ parentXPath.getKey() +"="+ parentXPath.getValue().replace(InjectionModel.STAR, ""), e);
Expand All @@ -336,7 +328,7 @@ private boolean testParameters(MethodInjection methodInjection, String paramsAsS

try {
LOGGER.info("Checking "+ methodInjection.name() +" parameter "+ paramBase.getKey() +"="+ paramBase.getValue().replace(InjectionModel.STAR, ""));
hasFoundInjection = this.testStrategies(true, false, paramBase);
hasFoundInjection = this.testStrategies(IS_CHECKING_ALL_PARAMETERS, !IS_JSON, paramBase);
break;
} catch (JSqlException e) {
LOGGER.warn("No "+ methodInjection.name() +" injection found for parameter "+ paramBase.getKey() +"="+ paramBase.getValue().replace(InjectionModel.STAR, ""), e);
Expand All @@ -349,6 +341,7 @@ private boolean testParameters(MethodInjection methodInjection, String paramsAsS
}
}
if (hasFoundInjection) {
paramBase.setValue(paramBase.getValue().replace("*", "") +"*");
break;
}

Expand All @@ -359,6 +352,9 @@ private boolean testParameters(MethodInjection methodInjection, String paramsAsS
return hasFoundInjection;
}

private static final boolean IS_CHECKING_ALL_PARAMETERS = true;
private static final boolean IS_JSON = true;

private boolean testStrategies(boolean checkAllParameters, boolean isJson, SimpleEntry<String, String> parameter) throws JSqlException {
// Define insertionCharacter, i.e, -1 in "[..].php?id=-1 union select[..]",
LOGGER.trace(I18n.valueByKey("LOG_GET_INSERTION_CHARACTER"));
Expand Down Expand Up @@ -595,38 +591,11 @@ public String inject(String newDataInjection, boolean isUsingIndex) {
}

msgHeader.put(Header.RESPONSE, HeaderUtil.getHttpHeaders(connection));

// Request the web page to the server
StringBuilder sb = new StringBuilder();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
char[] buffer = new char[4096];
while (reader.read(buffer) > 0) {
sb.append(buffer);
}

pageSource = sb.toString();
} catch (IOException e) {
// Ignore connection errors like 403, 406
// Http status code already logged in Network tab

InputStream inputErrorStream = connection.getErrorStream();

if (inputErrorStream != null) {
String line;
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputErrorStream))) {
while ((line = reader.readLine()) != null) {
sb.append(line + "\r\n");
}
} catch (Exception e2) {
// Ignore
throw e2;
}
pageSource = sb.toString();
}

// Ignore
IgnoreMessageException exceptionIgnored = new IgnoreMessageException(e);
LOGGER.trace(exceptionIgnored, exceptionIgnored);

try {
pageSource = ConnectionUtil.getSource(connection);
} catch (Exception e) {
LOGGER.error(e, e);
}

// Calling connection.disconnect() is not required, further calls will follow
Expand All @@ -640,7 +609,7 @@ public String inject(String newDataInjection, boolean isUsingIndex) {
this.sendToViews(request);

} catch (
// Exception for Block Opening Connection
// Exception for General and Spnego Opening Connection
IOException | LoginException | GSSException | PrivilegedActionException e
) {
LOGGER.warn("Error during connection: "+ e.getMessage(), e);
Expand Down Expand Up @@ -798,7 +767,7 @@ public void controlInput(
ParameterUtil.setQueryString(
Pattern.compile("&").splitAsStream(regexSearch.group(2))
.map(s -> Arrays.copyOf(s.split("="), 2))
.map(o -> new SimpleEntry<String, String>(decode(o[0]), decode(o[1])))
.map(o -> new SimpleEntry<String, String>(o[0], o[1] == null ? "" : o[1]))
.collect(Collectors.toList())
);
}
Expand All @@ -807,14 +776,22 @@ public void controlInput(
}

// Define other methods
ParameterUtil.setRequest(Pattern.compile("&").splitAsStream(dataRequest)
ParameterUtil.setRequest(
Pattern
.compile("&")
.splitAsStream(dataRequest)
.map(s -> Arrays.copyOf(s.split("="), 2))
.map(o -> new SimpleEntry<String, String>(decode(o[0]), decode(o[1])))
.collect(Collectors.toList()));
ParameterUtil.setHeader(Pattern.compile("\\\\r\\\\n").splitAsStream(dataHeader)
.map(o -> new SimpleEntry<String, String>(o[0], o[1] == null ? "" : o[1]))
.collect(Collectors.toList())
);
ParameterUtil.setHeader(
Pattern
.compile("\\\\r\\\\n")
.splitAsStream(dataHeader)
.map(s -> Arrays.copyOf(s.split(":"), 2))
.map(o -> new SimpleEntry<String, String>(decode(o[0]), decode(o[1])))
.collect(Collectors.toList()));
.map(o -> new SimpleEntry<String, String>(o[0], o[1] == null ? "" : o[1]))
.collect(Collectors.toList())
);
ConnectionUtil.setMethodInjection(methodInjection);
ConnectionUtil.setTypeRequest(typeRequest);

Expand Down
44 changes: 17 additions & 27 deletions src/main/java/com/jsql/model/accessible/RessourceAccess.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@
import com.jsql.util.PropertiesUtil;
import com.jsql.view.scan.ScanListTerminal;
import com.jsql.view.swing.MediatorGui;
import com.jsql.view.swing.list.ListItem;
import com.jsql.view.swing.list.ListItemScan;
import com.jsql.view.swing.list.ItemList;
import com.jsql.view.swing.list.ItemListScan;

/**
* Ressource access object.
Expand Down Expand Up @@ -121,7 +121,7 @@ private RessourceAccess() {
* @param pageNames List of admin pages ot test
* @throws InterruptedException
*/
public static void createAdminPages(String urlInjection, List<ListItem> pageNames) throws InterruptedException {
public static void createAdminPages(String urlInjection, List<ItemList> pageNames) throws InterruptedException {
String urlWithoutProtocol = urlInjection.replaceAll("^https?://[^/]*", "");
String urlProtocol = urlInjection.replace(urlWithoutProtocol, "");
String urlWithoutFileName = urlWithoutProtocol.replaceAll("[^/]*$", "");
Expand All @@ -140,7 +140,7 @@ public static void createAdminPages(String urlInjection, List<ListItem> pageName
StringBuilder urlPart = new StringBuilder();
for (String segment: directoryNames) {
urlPart.append(segment);
for (ListItem pageName: pageNames) {
for (ItemList pageName: pageNames) {
taskCompletionService.submit(new CallableHttpHead(urlProtocol + urlPart.toString() + pageName.toString()));
}
}
Expand Down Expand Up @@ -335,24 +335,14 @@ private static String runCommandShell(String urlCommand) throws IOException {
connection.setReadTimeout(ConnectionUtil.getTimeout());
connection.setConnectTimeout(ConnectionUtil.getTimeout());

StringBuilder pageSource = new StringBuilder();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
String line;
while ((line = reader.readLine()) != null) {
pageSource.append(line + "\n");
}
} catch (IOException e) {
String line;
try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getErrorStream()))) {
while ((line = reader.readLine()) != null) {
pageSource.append(line + "\r\n");
}
} catch (Exception e2) {
throw e2;
}
String pageSource = null;
try {
pageSource = ConnectionUtil.getSource(connection);
} catch (Exception e) {
pageSource = "";
}

Matcher regexSearch = Pattern.compile("(?s)<"+ DataAccess.LEAD +">(.*)<"+ DataAccess.TRAIL +">").matcher(pageSource.toString());
Matcher regexSearch = Pattern.compile("(?s)<"+ DataAccess.LEAD +">(.*)<"+ DataAccess.TRAIL +">").matcher(pageSource);
regexSearch.find();

String result;
Expand All @@ -370,7 +360,7 @@ private static String runCommandShell(String urlCommand) throws IOException {
msgHeader.put(Header.POST, "");
msgHeader.put(Header.HEADER, "");
msgHeader.put(Header.RESPONSE, HeaderUtil.getHttpHeaders(connection));
msgHeader.put(Header.SOURCE, pageSource.toString());
msgHeader.put(Header.SOURCE, pageSource);

Request request = new Request();
request.setMessage(Interaction.MESSAGE_HEADER);
Expand Down Expand Up @@ -829,7 +819,7 @@ public static boolean isReadingAllowed() throws JSqlException {
* @throws InterruptedException if the current thread was interrupted while waiting
* @throws ExecutionException if the computation threw an exception
*/
public static void readFile(List<ListItem> pathsFiles) throws JSqlException, InterruptedException, ExecutionException {
public static void readFile(List<ItemList> pathsFiles) throws JSqlException, InterruptedException, ExecutionException {
if (!RessourceAccess.isReadingAllowed()) {
return;
}
Expand All @@ -838,7 +828,7 @@ public static void readFile(List<ListItem> pathsFiles) throws JSqlException, Int
ExecutorService taskExecutor = Executors.newFixedThreadPool(10, new ThreadFactoryCallable("CallableReadFile"));
CompletionService<CallableFile> taskCompletionService = new ExecutorCompletionService<>(taskExecutor);

for (ListItem pathFile: pathsFiles) {
for (ItemList pathFile: pathsFiles) {
CallableFile callableFile = new CallableFile(pathFile.toString());
taskCompletionService.submit(callableFile);
RessourceAccess.callablesReadFile.add(callableFile);
Expand Down Expand Up @@ -907,7 +897,7 @@ public static void readFile(List<ListItem> pathsFiles) throws JSqlException, Int
* At the end of the scan it plugs again the normal view.
* @param urlList contains a list of String URL
*/
public static void scanList(List<ListItem> urlList) {
public static void scanList(List<ItemList> urlList) {
// Erase everything in the view from a previous injection
Request requests = new Request();
requests.setMessage(Interaction.RESET_INTERFACE);
Expand All @@ -928,8 +918,8 @@ public static void scanList(List<ListItem> urlList) {
MediatorModel.model().setIsScanning(true);
RessourceAccess.isScanStopped = false;

for (ListItem url: urlList) {
ListItemScan urlurl = (ListItemScan) url;
for (ItemList url: urlList) {
ItemListScan urlurl = (ItemListScan) url;
if (MediatorModel.model().isStoppedByUser() || RessourceAccess.isScanStopped) {
break;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.jsql.model.exception;


// Instancier qu'une fois static
@SuppressWarnings("serial")
public class IgnoreMessageException extends Exception {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ public String inject(String inj, AbstractSuspendable<String> suspendable) throws
&& countAsciiCode255 > 9
&& (countAsciiCode255 * 100 / submittedTasks) > 50
) {
LOGGER.warn("Numerous Boolean false positives detected");
LOGGER.warn("Boolean false positives detected, stopping...");
break;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ rpad(
)
</calibrator>
<limitBoundary>1</limitBoundary>
<endingComment></endingComment>
<fingerprint>
<errorMessage>Non-terminated string</errorMessage>
</fingerprint>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ from (
<failsafe>select cast(x.rrr as char)rr from (select 1337${INDICE}7330%2b1 rrr)x</failsafe>
<calibrator>'%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23'</calibrator>
<limitBoundary>1</limitBoundary>
<endingComment></endingComment>
<fingerprint>
<errorMessage>mckoi</errorMessage>
</fingerprint>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ concat(
<failsafe>1337${INDICE}7330%2b1</failsafe>
<calibrator>rpad('${CALIBRATOR_SQL}',1024,'${CALIBRATOR_SQL}')</calibrator>
<limitBoundary>0</limitBoundary>
<endingComment></endingComment>
<fingerprint>
<errorMessage>memsql</errorMessage>
</fingerprint>
Expand Down
Loading

0 comments on commit ea21e38

Please sign in to comment.