diff --git a/pkg/passive/sources.go b/pkg/passive/sources.go index 77a9307e6..1bdae68d8 100644 --- a/pkg/passive/sources.go +++ b/pkg/passive/sources.go @@ -31,6 +31,7 @@ import ( "github.com/projectdiscovery/subfinder/pkg/subscraping/sources/threatminer" "github.com/projectdiscovery/subfinder/pkg/subscraping/sources/virustotal" "github.com/projectdiscovery/subfinder/pkg/subscraping/sources/waybackarchive" + "github.com/projectdiscovery/subfinder/pkg/subscraping/sources/ximcx" "github.com/projectdiscovery/subfinder/pkg/subscraping/sources/zoomeye" ) @@ -56,6 +57,7 @@ var DefaultSources = []string{ "threatcrowd", "threatminer", "virustotal", + "ximcx", } // DefaultRecursiveSources contains list of default recursive sources @@ -105,6 +107,7 @@ var DefaultAllSources = []string{ "threatminer", "virustotal", "waybackarchive", + "ximcx", "zoomeye", } @@ -188,6 +191,8 @@ func (a *Agent) addSources(sources []string) { a.sources[source] = &virustotal.Source{} case "waybackarchive": a.sources[source] = &waybackarchive.Source{} + case "ximcx": + a.sources[source] = &ximcx.Source{} case "zoomeye": a.sources[source] = &zoomeye.Source{} } diff --git a/pkg/subscraping/sources/ximcx/ximcx.go b/pkg/subscraping/sources/ximcx/ximcx.go new file mode 100644 index 000000000..d18b93691 --- /dev/null +++ b/pkg/subscraping/sources/ximcx/ximcx.go @@ -0,0 +1,63 @@ +package ximcx + +import ( + "context" + "fmt" + + jsoniter "github.com/json-iterator/go" + "github.com/projectdiscovery/subfinder/pkg/subscraping" +) + +// Source is the passive scraping agent +type Source struct{} + +type domain struct { + Domain string `json:"domain"` +} + +type ximcxResponse struct { + Code int64 `json:"code"` + Message string `json:"message"` + Data []domain `json:"data"` +} + +// Run function returns all subdomains found with the service +func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Session) <-chan subscraping.Result { + results := make(chan subscraping.Result) + + go func() { + defer close(results) + + resp, err := session.SimpleGet(ctx, fmt.Sprintf("http://sbd.ximcx.cn/DomainServlet?domain=%s", domain)) + if err != nil { + results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err} + session.DiscardHTTPResponse(resp) + return + } + + var response ximcxResponse + err = jsoniter.NewDecoder(resp.Body).Decode(&response) + if err != nil { + results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err} + resp.Body.Close() + return + } + resp.Body.Close() + + if response.Code > 0 { + results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: fmt.Errorf("%d, %s", response.Code, response.Message)} + return + } + + for _, result := range response.Data { + results <- subscraping.Result{Source: s.Name(), Type: subscraping.Subdomain, Value: result.Domain} + } + }() + + return results +} + +// Name returns the name of the source +func (s *Source) Name() string { + return "ximcx" +}