1+ /*
2+ * Burp Suite HTTP Smuggler
3+ *
4+ * Released as open source by NCC Group - https://www.nccgroup.trust/
5+ *
6+ * Developed by:
7+ * Soroush Dalili (@irsdl)
8+ *
9+ * Project link: https://github.com/nccgroup/BurpSuiteHTTPSmuggler/
10+ *
11+ * Released under AGPL v3.0 see LICENSE for more information
12+ *
13+ * */
14+
15+ package burp ;
16+
17+ import java .awt .Component ;
18+ import java .io .PrintWriter ;
19+ import java .io .UnsupportedEncodingException ;
20+ import java .net .URL ;
21+ import java .util .regex .Matcher ;
22+ import java .util .regex .Pattern ;
23+
24+ import javax .swing .JPanel ;
25+ import javax .swing .JTabbedPane ;
26+ import javax .swing .SwingUtilities ;
27+
28+ import mutation .HTTPEncodingObject ;
29+
30+ public class BurpExtender implements IBurpExtender , ITab , IHttpListener
31+ {
32+
33+ private PrintWriter _stdout ;
34+ private PrintWriter _stderr ;
35+ private JTabbedPane _topTabs ;
36+ private IBurpExtenderCallbacks _callbacks ;
37+ private JTabbedPane topTabs ;
38+
39+ public void registerExtenderCallbacks (IBurpExtenderCallbacks callbacks )
40+ {
41+ _callbacks = callbacks ;
42+ // obtain our output stream
43+ _stdout = new PrintWriter (_callbacks .getStdout (), true );
44+ _stderr = new PrintWriter (_callbacks .getStderr (), true );
45+
46+ // set our extension name
47+ _callbacks .setExtensionName ("HTTP Smuggler" );
48+
49+ // register ourselves as an HTTP listener
50+ callbacks .registerHttpListener (BurpExtender .this );
51+
52+ // create our UI
53+ SwingUtilities .invokeLater (new Runnable ()
54+ {
55+ @ Override
56+ public void run ()
57+ {
58+ topTabs = new JTabbedPane ();
59+
60+ topTabs .addTab ("Scope" , null , new myui .ScopeTab (callbacks , _stdout , _stderr ), null );
61+ topTabs .addTab ("Encoding" , null , new myui .EncodingTab (callbacks , _stdout , _stderr ), null );
62+ topTabs .addTab ("About" , null , new myui .AboutTab (callbacks , _stdout , _stderr ), null );
63+
64+ // customize our UI components
65+ callbacks .customizeUiComponent (topTabs );
66+ helper .UIStuff .updateJCheckBoxBackground (topTabs );
67+
68+ // add the custom tab to Burp's UI
69+ callbacks .addSuiteTab (BurpExtender .this );
70+ }
71+ });
72+
73+ }
74+
75+ @ Override
76+ public String getTabCaption ()
77+ {
78+ return "HTTP Smuggler Settings" ;
79+ }
80+
81+ @ Override
82+ public void processHttpMessage (int toolFlag , boolean messageIsRequest , IHttpRequestResponse messageInfo ) {
83+ if (messageIsRequest ) {
84+ /* to calculate the scope, OR has not been implemented yet*/
85+ boolean isDisabled = false ;
86+ boolean isInScope = false ;
87+ boolean isTargetInScope = true ;
88+ boolean isURLPathInScope = true ;
89+ boolean isHeaderInScope = true ;
90+
91+ IRequestInfo analyzedReq = _callbacks .getHelpers ().analyzeRequest (messageInfo );
92+ URL uUrl = analyzedReq .getUrl ();
93+ /* find the right scope based on the settings*/
94+ int targetScopeOption =(int ) loadExtensionSettingHelper ("targetScopeOption" ,"int" ,0 );
95+ int pathRegExOption =(int ) loadExtensionSettingHelper ("pathRegExOption" ,"int" ,0 );
96+ String pathRegEx =(String ) loadExtensionSettingHelper ("pathRegEx" ,"string" ,"" );
97+ int headerRegExOption =(int ) loadExtensionSettingHelper ("headerRegExOption" ,"int" ,0 );
98+ String headerRegEx =(String ) loadExtensionSettingHelper ("headerRegEx" ,"string" ,"" );
99+
100+ boolean chckbxAllTools =(boolean ) loadExtensionSettingHelper ("chckbxAllTools" ,"bool" ,false );
101+ boolean chckbxProxy =(boolean ) loadExtensionSettingHelper ("chckbxProxy" ,"bool" ,false );
102+ boolean chckbxScanner =(boolean ) loadExtensionSettingHelper ("chckbxScanner" ,"bool" ,false );
103+ boolean chckbxIntruder =(boolean ) loadExtensionSettingHelper ("chckbxIntruder" ,"bool" ,false );
104+ boolean chckbxRepeator =(boolean ) loadExtensionSettingHelper ("chckbxRepeator" ,"bool" ,true );
105+ boolean chckbxExtender =(boolean ) loadExtensionSettingHelper ("chckbxExtender" ,"bool" ,false );
106+ boolean chckbxTarget =(boolean ) loadExtensionSettingHelper ("chckbxTarget" ,"bool" ,false );
107+ boolean chckbxSequencer =(boolean ) loadExtensionSettingHelper ("chckbxSequencer" ,"bool" ,false );
108+ boolean chckbxSpider =(boolean ) loadExtensionSettingHelper ("chckbxSpider" ,"bool" ,false );
109+
110+ if (targetScopeOption ==1 && pathRegExOption ==1 && headerRegExOption ==1 ) {
111+ //evrything is disabled
112+ isDisabled = true ;
113+ }
114+
115+ if (!isDisabled ) {
116+ if (targetScopeOption < 1 && !_callbacks .isInScope (uUrl )) {
117+ isTargetInScope = false ;
118+ }
119+
120+
121+ if (isTargetInScope && pathRegExOption < 1 && !pathRegEx .isEmpty ()){
122+ // AND rule for path/url regex
123+ Pattern pathPattern = Pattern .compile (pathRegEx );
124+ Matcher matcher_pathURL = pathPattern .matcher (uUrl .toString ());
125+ if (!matcher_pathURL .find ())
126+ {
127+ isURLPathInScope = false ;
128+ }
129+ }
130+
131+ if (isTargetInScope && isURLPathInScope && headerRegExOption < 1 && !headerRegEx .isEmpty ()){
132+ // AND rule for header regex
133+ Pattern headerPattern = Pattern .compile (headerRegEx );
134+
135+ StringBuilder sb = new StringBuilder ();
136+ for (String headerLine : analyzedReq .getHeaders ())
137+ {
138+ sb .append (headerLine );
139+ sb .append ("\r \n " );
140+ }
141+ Matcher matcher_header = headerPattern .matcher (sb .toString ());
142+ if (!matcher_header .find ())
143+ {
144+ isHeaderInScope = false ;
145+ }
146+ }
147+
148+
149+
150+ if (isTargetInScope && isURLPathInScope && isHeaderInScope ){
151+ // check the tool!
152+ if (chckbxAllTools ){
153+ isInScope = true ;
154+ }else if (chckbxProxy && toolFlag ==_callbacks .TOOL_PROXY ){
155+ isInScope = true ;
156+ }else if (chckbxIntruder && toolFlag ==_callbacks .TOOL_INTRUDER ){
157+ isInScope = true ;
158+ }else if (chckbxRepeator && toolFlag ==_callbacks .TOOL_REPEATER ){
159+ isInScope = true ;
160+ }else if (chckbxScanner && toolFlag ==_callbacks .TOOL_SCANNER ){
161+ isInScope = true ;
162+ }else if (chckbxSequencer && toolFlag ==_callbacks .TOOL_SEQUENCER ){
163+ isInScope = true ;
164+ }else if (chckbxSpider && toolFlag ==_callbacks .TOOL_SPIDER ){
165+ isInScope = true ;
166+ }else if (chckbxExtender && toolFlag ==_callbacks .TOOL_EXTENDER ){
167+ isInScope = true ;
168+ }else if (chckbxTarget && toolFlag ==_callbacks .TOOL_TARGET ){
169+ isInScope = true ;
170+ }
171+ }
172+
173+
174+ if (isInScope ){
175+ //logIt(toolFlag, messageIsRequest, messageInfo, null);
176+ mutation .HttpEncoding httpEcnoding = new mutation .HttpEncoding (_callbacks ,_stdout ,_stderr ,true );
177+ try {
178+ String newHTTPMessage = httpEcnoding .encodeHTTPMessage (messageInfo .getRequest (), loadHTTPEncodingObjectFromExtensionSetting ());
179+ if (newHTTPMessage .isEmpty ()) {
180+ _stdout .println ("Message was not encoded - perhaps it was not eligible or there was an error (see the error tab)" );
181+ _stdout .println ("Enable the debug mode to see more details" );
182+ }else {
183+ byte [] requestByte = newHTTPMessage .getBytes ("ISO-8859-1" );
184+ messageInfo .setRequest (requestByte );
185+ }
186+ } catch (UnsupportedEncodingException e ) {
187+ _stderr .println (e .getMessage ());
188+ }
189+ }
190+ }
191+ }
192+ }
193+
194+ @ Override
195+ public Component getUiComponent () {
196+ return topTabs ;
197+ }
198+
199+ private Object loadExtensionSettingHelper (String name , String type , Object defaultValue ) {
200+ Object value = null ;
201+ try {
202+ String temp_value = _callbacks .loadExtensionSetting (name );
203+ if (temp_value !=null && !temp_value .equals ("" )) {
204+ switch (type .toLowerCase ()){
205+ case "int" :
206+ case "integer" :
207+ value = Integer .valueOf (temp_value );
208+ break ;
209+ case "bool" :
210+ case "boolean" :
211+ value = Boolean .valueOf (temp_value );
212+ break ;
213+ default :
214+ value = temp_value ;
215+ break ;
216+ }
217+ }
218+ }catch (Exception e ) {
219+ _stderr .println (e .getMessage ());
220+ }
221+
222+ if (value ==null ) {
223+ value = defaultValue ;
224+ }
225+ return value ;
226+ }
227+
228+ private HTTPEncodingObject loadHTTPEncodingObjectFromExtensionSetting () {
229+ HTTPEncodingObject currentHTTPEncodingObject = new HTTPEncodingObject ();
230+ currentHTTPEncodingObject .setPreventReEncoding ((boolean ) loadExtensionSettingHelper ("preventReEncoding" , "bool" , true ));
231+ currentHTTPEncodingObject .setEncodeMicrosoftURLEncode ((boolean ) loadExtensionSettingHelper ("encodeMicrosoftURLEncode" , "bool" , false ));
232+ currentHTTPEncodingObject .setEncodeDespiteErrors ((boolean ) loadExtensionSettingHelper ("encodeDespiteErrors" , "bool" , false ));
233+ currentHTTPEncodingObject .setAddACharToEmptyBody ((boolean ) loadExtensionSettingHelper ("addACharToEmptyBody" , "bool" , true ));
234+ currentHTTPEncodingObject .setReplaceGETwithPOST ((boolean ) loadExtensionSettingHelper ("replaceGETwithPOST" , "bool" , false ));
235+ currentHTTPEncodingObject .setEncodable_QS ((boolean ) loadExtensionSettingHelper ("isEncodable_QS" , "bool" , true ));
236+ currentHTTPEncodingObject .setEncodable_body ((boolean ) loadExtensionSettingHelper ("isEncodable_body" , "bool" , true ));
237+ currentHTTPEncodingObject .setEncodable_QS_delimiter ((boolean ) loadExtensionSettingHelper ("isEncodable_QS_delimiter" , "bool" , false ));
238+ currentHTTPEncodingObject .setEncodable_urlencoded_body_delimiter ((boolean ) loadExtensionSettingHelper ("isEncodable_urlencoded_body_delimiter" , "bool" , false ));
239+ currentHTTPEncodingObject .setEncodable_QS_equal_sign ((boolean ) loadExtensionSettingHelper ("isEncodable_QS_equal_sign" , "bool" , false ));
240+ currentHTTPEncodingObject .setEncodable_urlencoded_body_equal_sign ((boolean ) loadExtensionSettingHelper ("isEncodable_urlencoded_body_equal_sign" , "bool" , false ));
241+ currentHTTPEncodingObject .setURLEncoded_incoming_QS ((boolean ) loadExtensionSettingHelper ("isURLEncoded_incoming_QS" , "bool" , true ));
242+ currentHTTPEncodingObject .setURLEncoded_incoming_body ((boolean ) loadExtensionSettingHelper ("isURLEncoded_incoming_body" , "bool" , true ));
243+ currentHTTPEncodingObject .setURLEncoded_outgoing_QS ((boolean ) loadExtensionSettingHelper ("isURLEncoded_outgoing_QS" , "bool" , true ));
244+ currentHTTPEncodingObject .setURLEncoded_outgoing_body ((boolean ) loadExtensionSettingHelper ("isURLEncoded_outgoing_body" , "bool" , true ));
245+ currentHTTPEncodingObject .setAllChar_URLEncoded_outgoing_QS ((boolean ) loadExtensionSettingHelper ("isAllChar_URLEncoded_outgoing_QS" , "bool" , true ));
246+ currentHTTPEncodingObject .setAllChar_URLEncoded_outgoing_body ((boolean ) loadExtensionSettingHelper ("isAllChar_URLEncoded_outgoing_body" , "bool" , true ));
247+ currentHTTPEncodingObject .setTrimSpacesInContentTypeHeaderValues ((boolean ) loadExtensionSettingHelper ("trimSpacesInContentTypeHeaderValues" , "bool" , true ));
248+ currentHTTPEncodingObject .setEncodeNameValueOnlyMultipart ((boolean ) loadExtensionSettingHelper ("encodeNameValueOnlyMultipart" , "bool" , false ));
249+ currentHTTPEncodingObject .setUse_incoming_charset_for_request_encoding ((boolean ) loadExtensionSettingHelper ("use_incoming_charset_for_request_encoding" , "bool" , true ));
250+
251+ currentHTTPEncodingObject .setDelimiter_QS ((String ) loadExtensionSettingHelper ("delimiter_QS" , "string" , "?" ));
252+ currentHTTPEncodingObject .setDelimiter_QS_param ((String ) loadExtensionSettingHelper ("delimiter_QS_param" , "string" , "&" ));
253+ currentHTTPEncodingObject .setQS_equalSign ((String ) loadExtensionSettingHelper ("QS_equalSign" , "string" , "=" ));
254+ currentHTTPEncodingObject .setDelimiter_urlencoded_body_param ((String ) loadExtensionSettingHelper ("delimiter_urlencoded_body_param" , "string" , "&" ));
255+ currentHTTPEncodingObject .setBody_param_equalSign ((String ) loadExtensionSettingHelper ("body_param_equalSign" , "string" , "=" ));
256+ currentHTTPEncodingObject .setOutgoing_request_encoding ((String ) loadExtensionSettingHelper ("outgoing_request_encoding" , "string" , "ibm500" ));
257+ currentHTTPEncodingObject .setIncoming_request_encoding ((String ) loadExtensionSettingHelper ("incoming_request_encoding" , "string" , "utf-8" ));
258+
259+ return currentHTTPEncodingObject ;
260+ }
261+
262+ }
0 commit comments