-
-
Notifications
You must be signed in to change notification settings - Fork 504
Add raw HTTP request support to pipe mode #773
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,9 +2,12 @@ package cmd | |
|
|
||
| import ( | ||
| "bufio" | ||
| "encoding/base64" | ||
| "fmt" | ||
| "io/ioutil" | ||
| "os" | ||
| "strconv" | ||
| "strings" | ||
| "sync" | ||
| "time" | ||
|
|
||
|
|
@@ -35,6 +38,13 @@ func runPipeCmd(cmd *cobra.Command, args []string) { | |
| options.Method = "Pipe Mode" | ||
| printing.Summary(options, "Stdin (pipeline)") | ||
| options.Method = tMethod | ||
|
|
||
| rawdata, _ := cmd.Flags().GetBool("rawdata") | ||
| if rawdata { | ||
| runRawDataPipeMode(cmd) | ||
| return | ||
| } | ||
|
|
||
| var targets []string | ||
| mutex := &sync.Mutex{} | ||
| options.Mutex = mutex | ||
|
|
@@ -60,6 +70,71 @@ func runPipeCmd(cmd *cobra.Command, args []string) { | |
| } | ||
| } | ||
|
|
||
| // runRawDataPipeMode processes a file containing raw HTTP request data | ||
| func runRawDataPipeMode(cmd *cobra.Command) { | ||
| printing.DalLog("SYSTEM", "Using pipe mode with raw data format", options) | ||
| bytes, err := ioutil.ReadAll(os.Stdin) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| if err != nil { | ||
| printing.DalLog("ERROR", "Failed to read from stdin: "+err.Error(), options) | ||
| return | ||
| } | ||
| rawReq := string(bytes) | ||
|
|
||
| // Check if the input is base64 encoded | ||
| b64decoded, err := base64.StdEncoding.DecodeString(rawReq) | ||
| if err == nil { | ||
| rawReq = string(b64decoded) | ||
| } | ||
|
|
||
| ff := strings.Split(strings.ReplaceAll(rawReq, "\r\n", "\n"), "\n") | ||
|
|
||
| var path, body, host, target string | ||
| bodyswitch := false | ||
| for index, line := range ff { | ||
| if index == 0 { | ||
| parse := strings.Split(line, " ") | ||
| if len(parse) > 1 { | ||
| options.Method = parse[0] | ||
| path = parse[1] | ||
| } else { | ||
| printing.DalLog("ERROR", "HTTP Raw Request Format Error", options) | ||
| os.Exit(1) | ||
| } | ||
| } else { | ||
| if strings.Contains(line, "Host: ") || strings.Contains(line, "host: ") { | ||
| host = line[6:] | ||
| } else { | ||
| parse := strings.Split(line, ":") | ||
| if len(parse) > 1 { | ||
| options.Header = append(options.Header, line) | ||
| } | ||
| } | ||
| if bodyswitch { | ||
| body = body + line | ||
| } | ||
| if len(line) == 0 { | ||
| bodyswitch = true | ||
| } | ||
| } | ||
| } | ||
|
Comment on lines
+91
to
+119
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The HTTP request parsing loop has potential issues:
Consider refactoring the parsing logic to improve correctness and robustness. var path, host, target string
var body strings.Builder
// Normalize line endings and split headers from body
rawReq = strings.ReplaceAll(rawReq, "\r\n", "\n")
parts := strings.SplitN(rawReq, "\n\n", 2)
headerLines := strings.Split(parts[0], "\n")
if len(parts) > 1 {
body.WriteString(parts[1])
}
if len(headerLines) == 0 || headerLines[0] == "" {
printing.DalLog("ERROR", "HTTP Raw Request Format Error: Empty request", options)
os.Exit(1)
}
// Parse first line (request line)
firstLine := headerLines[0]
parse := strings.Fields(firstLine)
if len(parse) > 1 {
options.Method = parse[0]
path = parse[1]
} else {
printing.DalLog("ERROR", "HTTP Raw Request Format Error", options)
os.Exit(1)
}
// Parse headers
for _, line := range headerLines[1:] {
if strings.HasPrefix(strings.ToLower(line), "host:") {
host = strings.TrimSpace(line[len("host:"):])
} else if strings.Contains(line, ":") {
options.Header = append(options.Header, line)
}
} |
||
| options.Data = body | ||
| http, _ := cmd.Flags().GetBool("http") | ||
| if strings.Index(path, "http") == 0 { | ||
| target = path | ||
| } else { | ||
| if host == "" { | ||
| printing.DalLog("ERROR", "HTTP Raw Request Format Error - Host not found", options) | ||
| os.Exit(1) | ||
| } | ||
| if http { | ||
| target = "http://" + host + path | ||
| } else { | ||
| target = "https://" + host + path | ||
| } | ||
| } | ||
| _, _ = scanning.Scan(target, options, "single") | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| } | ||
|
|
||
| // runMulticastMode processes multiple targets in parallel using worker pools | ||
| // It distributes scanning tasks across multiple goroutines for efficient processing | ||
| func runMulticastMode(targets []string, cmd *cobra.Command, sf bool, limit int) { | ||
|
|
@@ -209,6 +284,8 @@ func runSingleMode(targets []string, sf bool, limit int) { | |
| // init registers the pipe command and its flags | ||
| func init() { | ||
| rootCmd.AddCommand(pipeCmd) | ||
| pipeCmd.Flags().Bool("rawdata", false, "[FORMAT] Use raw data from Burp/ZAP. Example: --rawdata") | ||
| pipeCmd.Flags().Bool("http", false, "Force HTTP on raw data mode. Example: --http") | ||
| pipeCmd.Flags().Bool("multicast", false, "Enable parallel scanning in N*Host mode (only shows PoC code). Example: --multicast") | ||
| pipeCmd.Flags().Bool("mass", false, "Enable parallel scanning in N*Host mode (only shows PoC code). Example: --mass") | ||
| pipeCmd.Flags().Bool("silence-force", false, "Only print PoC code, suppress progress output. Example: --silence-force") | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,12 +11,14 @@ layout: page | |
|
|
||
| This guide provides detailed instructions on how to scan a target using a raw HTTP request with Dalfox. Follow the steps below to perform a scan using a raw request. | ||
|
|
||
| ## Sample Raw Request | ||
| ## Using `file` mode | ||
|
|
||
| ### Sample Raw Request | ||
|
|
||
| Create a file named `sample_rawdata.txt` with the following content: | ||
|
|
||
| ```http | ||
| POST https://www.hahwul.com/?q=xspear HTTP/1.1 | ||
| POST https://www.hahwul.com/?q=dalfox HTTP/1.1 | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:56.0) Gecko/20100101 Firefox/56.0 | ||
| Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 | ||
| Accept-Language: ko-KR,ko;q=0.8,en-US;q=0.5,en;q=0.3 | ||
|
|
@@ -28,14 +30,32 @@ Host: www.hahwul.com | |
| asdf=asdf | ||
| ``` | ||
|
|
||
| ## Command | ||
| ### Command | ||
|
|
||
| To scan using the raw request from a file, use the following command: | ||
|
|
||
| ```bash | ||
| dalfox file ./samples/sample_rawdata.txt --rawdata | ||
| ``` | ||
|
|
||
| ## Using `pipe` mode | ||
|
|
||
| To scan using the raw request, use the following command: | ||
| You can also provide the raw request via stdin using the `pipe` command. | ||
|
|
||
| ### Command | ||
|
|
||
| ```bash | ||
| cat ./samples/sample_rawdata.txt | dalfox pipe --rawdata | ||
| ``` | ||
|
|
||
| Or for base64 encoded requests: | ||
|
|
||
| ```bash | ||
| dalfox file --rawdata ./samples/sample_rawdata.txt | ||
| cat ./samples/sample_rawdata.txt | base64 | dalfox pipe --rawdata | ||
| ``` | ||
|
|
||
| Dalfox will automatically detect if the piped input is base64 encoded and decode it before parsing. | ||
|
|
||
| ## Output | ||
|
|
||
| Here is an example of the output you can expect from running the above command: | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The function
runRawDataPipeModedirectly exits the program usingos.Exit(1)when encountering errors. This abrupt termination can hinder testability and reusability. It's better to return an error to allow the caller function to handle the error gracefully.