Tags: #security #hack #pentesting #traversal #path #encoding
Path Traversal Tips
Always try path traversal sequences using both forward slashes and backslashes.
Many input filters check for only one of these, when the filesystem may support both.
- Try simple URL-encoded representations of traversal sequences using the following encodings. Be sure to encode every single slash and dot within your input:
- Dot — %2e
- Forward slash — %2f
- Backslash — %5c
- Try using 16-bit Unicode encoding:
- Dot — %u002e
- Forward slash — %u2215
- Backslash — %u2216
- Try double URL encoding:
- Dot — %252e
- Forward slash — %252f
- Backslash — %255c
- Try overlong UTF-8 Unicode encoding:
- Dot — %c0%2e, %e0%40%ae, %c0ae, and so on
- Forward slash — %c0%af, %e0%80%af, %c0%2f, and so on
- Backslash — %c0%5c, %c0%80%5c, and so on You can use the illegal Unicode payload type within Burp Intruder to generate a huge number of alternate representations of any given character and submit this at the relevant place within your target parameter. These representations strictly violate the rules for Unicode representation but nevertheless are accepted by many implementations of Unicode decoders, particularly on the Windows platform.
- If the application is attempting to sanitize user input by removing traversal sequences and does not apply this filter recursively, it may be possible to bypass the filter by placing one sequence within another.
For example:
....//
....\/
..../\
....\\
package main
import (
"fmt"
"os"
"path"
"path/filepath"
"regexp"
)
func cleanup(input string) string {
switch input {
case "%2e":
return "."
case "%2f":
return "/"
default:
return input
}
}
func main() {
re := regexp.MustCompile(`(?i)%2(?:e|f)`)
paths := []string{
"../",
"%2e./",
".%2e/",
"..%2f",
"%2e%2e/",
"%2e%2e%2f",
"foo/../bar",
"/static-assets/example/pages[...slug].js",
}
for _, p := range paths {
fmt.Println("\ninput path:", p)
p = re.ReplaceAllStringFunc(p, cleanup)
fmt.Println("replace path:", p)
if !filepath.IsAbs(p) {
p = path.Clean(string(os.PathSeparator) + p)
fmt.Println("clean path:", p)
}
}
}
// services that include this shared VCL should ensure they do not utilize the
// same error code, otherwise they may end up sending the wrong response.
//
sub security_recv {
// we want to prevent path traversal vulnerabilities such as:
//
// curl -v "https://httpbin.org/status/200/../../anything/status/404/"
//
// this ^^ would cause the server to go to /anything/status/404/ not /status/200
//
// this could be an issue because the upstream server might be able to
// communicate with private/internal APIs, and so this type of attack could
// enable the caller to access whatever data the server would normally only
// have access to.
//
// example pattern match:
// https://regex101.com/r/RYhmwW/2
//
// NOTES:
// we utilize a 'long string' {"..."} instead of a string literal "..."
// to avoid interpretting the %2E as a period character when VCL statically
// compiles a regex (which would change the pattern quite significantly!)
//
// DOCUMENTATION:
// https://developer.fastly.com/reference/vcl/types/string/
//
if (req.url.path ~ {"(?i)(\.|%2E){2}(/|%2F)"}) {
error 699 "Bad Request";
}
}
sub security_error {
if (obj.status == 699) {
set obj.status = 400;
synthetic {"Bad Request"};
return(deliver);
}
}