├── README.md └── rce-finder.py /README.md: -------------------------------------------------------------------------------- 1 | # RCE-finder-extension 2 | A tool to find good RCE 3 | From my series: A powerful Burp extension to make bounties rain 4 | 5 | # Are you sad ? 6 | # Do you have trouble populating you burp dashboard with fancy issues? 7 | # Well ... 8 | Well i got exactly what you need this burpsuite extension powered by a powerful AI engine, find good RCE and report it, all you need is to install it and browse sites like normal unsuspecting users (how cool is that). 9 | 10 | Download and install 11 | 12 | -------------------------------------------------------------------------------- /rce-finder.py: -------------------------------------------------------------------------------- 1 | from burp import IBurpExtender 2 | from burp import IScannerCheck 3 | from burp import IScanIssue 4 | from array import array 5 | import random 6 | 7 | GREP_STRING = "html" 8 | GREP_STRING_BYTES = bytearray(GREP_STRING) 9 | INJ_TEST = bytearray("|") 10 | INJ_ERROR = "Unexpected pipe" 11 | INJ_ERROR_BYTES = bytearray(INJ_ERROR) 12 | 13 | very_secure_random = random.SystemRandom() 14 | class BurpExtender(IBurpExtender, IScannerCheck): 15 | 16 | # 17 | # implement IBurpExtender 18 | # 19 | 20 | def registerExtenderCallbacks(self, callbacks): 21 | # keep a reference to our callbacks object 22 | self._callbacks = callbacks 23 | 24 | # obtain an extension helpers object 25 | self._helpers = callbacks.getHelpers() 26 | 27 | # set our extension name 28 | callbacks.setExtensionName("RCE-Finder") 29 | 30 | # register ourselves as a custom scanner check 31 | callbacks.registerScannerCheck(self) 32 | print ('I will make you a millionaire') 33 | # helper method to search a response for occurrences of a literal match string 34 | # and return a list of start/end offsets 35 | 36 | def _get_matches(self, response, match): 37 | matches = [] 38 | start = 0 39 | reslen = len(response) 40 | matchlen = len(match) 41 | while start < reslen: 42 | start = self._helpers.indexOf(response, match, True, start, reslen) 43 | if start == -1: 44 | break 45 | matches.append(array('i', [start, start + matchlen])) 46 | start += matchlen 47 | 48 | return matches 49 | 50 | # 51 | # implement IScannerCheck 52 | # 53 | 54 | def doPassiveScan(self, baseRequestResponse): 55 | # look for matches of our passive check grep string 56 | matches = self._get_matches(baseRequestResponse.getResponse(), GREP_STRING_BYTES) 57 | if (len(matches) == 0): 58 | return None 59 | 60 | # report the issue 61 | return [CustomScanIssue( 62 | baseRequestResponse.getHttpService(), 63 | self._helpers.analyzeRequest(baseRequestResponse).getUrl(), 64 | [self._callbacks.applyMarkers(baseRequestResponse, None, matches)], 65 | "RCE finder has found a reverse code execution issue, open your terminal and type whoami", 66 | "Reverse Code Execution", 67 | "High")] 68 | 69 | # def doActiveScan(self, baseRequestResponse, insertionPoint): 70 | # # make a request containing our injection test in the insertion point 71 | # checkRequest = insertionPoint.buildRequest(INJ_TEST) 72 | # checkRequestResponse = self._callbacks.makeHttpRequest( 73 | # baseRequestResponse.getHttpService(), checkRequest) 74 | 75 | # # look for matches of our active check grep string 76 | # matches = self._get_matches(checkRequestResponse.getResponse(), INJ_ERROR_BYTES) 77 | # if len(matches) == 0: 78 | # return None 79 | 80 | # # get the offsets of the payload within the request, for in-UI highlighting 81 | # requestHighlights = [insertionPoint.getPayloadOffsets(INJ_TEST)] 82 | 83 | # # report the issue 84 | # return [CustomScanIssue( 85 | # baseRequestResponse.getHttpService(), 86 | # self._helpers.analyzeRequest(baseRequestResponse).getUrl(), 87 | # [self._callbacks.applyMarkers(checkRequestResponse, requestHighlights, matches)], 88 | # "Pipe injection", 89 | # "Submitting a pipe character returned the string: " + INJ_ERROR, 90 | # "High")] 91 | 92 | def consolidateDuplicateIssues(self, existingIssue, newIssue): 93 | # This method is called when multiple issues are reported for the same URL 94 | # path by the same extension-provided check. The value we return from this 95 | # method determines how/whether Burp consolidates the multiple issues 96 | # to prevent duplication 97 | # 98 | # Since the issue name is sufficient to identify our issues as different, 99 | # if both issues have the same name, only report the existing issue 100 | # otherwise report both issues 101 | if existingIssue.getIssueName() == newIssue.getIssueName(): 102 | return -1 103 | 104 | return 0 105 | 106 | # 107 | # class implementing IScanIssue to hold our custom scan issue details 108 | # 109 | class CustomScanIssue (IScanIssue): 110 | def __init__(self, httpService, url, httpMessages, name, detail, severity): 111 | self._httpService = httpService 112 | self._url = url 113 | self._httpMessages = httpMessages 114 | self._name = name 115 | self._detail = detail 116 | self._severity = severity 117 | 118 | def getUrl(self): 119 | return self._url 120 | 121 | def getIssueName(self): 122 | return self._name 123 | 124 | def getIssueType(self): 125 | return 0 126 | 127 | def getSeverity(self): 128 | return self._severity 129 | 130 | def getConfidence(self): 131 | return "Certain" 132 | 133 | def getIssueBackground(self): 134 | pass 135 | 136 | def getRemediationBackground(self): 137 | pass 138 | 139 | def getIssueDetail(self): 140 | return self._detail 141 | 142 | def getRemediationDetail(self): 143 | pass 144 | 145 | def getHttpMessages(self): 146 | return self._httpMessages 147 | 148 | def getHttpService(self): 149 | return self._httpService 150 | --------------------------------------------------------------------------------