### Kiterunner Quick Start Scan (Bash) Source: https://github.com/assetnote/kiterunner/blob/main/readme.md This example demonstrates a quick start for Kiterunner, performing a scan with a list of hosts and Assetnote's API route wordlists, specifying concurrency and failing status codes. ```bash kr scan hosts.txt -A=apiroutes-210328:20000 -x 5 -j 100 --fail-status-codes 400,401,404,403,501,502,426,411 ``` -------------------------------- ### Install Kiterunner via AUR Helper (Bash) Source: https://github.com/assetnote/kiterunner/blob/main/readme.md This snippet shows how to install the Kiterunner binary on Arch-based Linux distributions using an AUR helper like 'yay'. ```bash yay -S kiterunner-bin ``` -------------------------------- ### Install Kiterunner via AUR (Bash) Source: https://context7.com/assetnote/kiterunner/llms.txt Provides commands to install the Kiterunner binary from the Arch User Repository using popular AUR helpers like yay and paru. ```bash yay -S kiterunner-bin paru -S kiterunner-bin ``` -------------------------------- ### GET /thisshouldnotexist Source: https://github.com/assetnote/kiterunner/blob/main/api-signatures/tornado.md Demonstrates the 404 Not Found error handling behavior of the Tornado server. ```APIDOC ## GET /thisshouldnotexist ### Description Requests a non-existent resource to trigger the standard 404 error response. ### Method GET ### Endpoint /thisshouldnotexist ### Response #### Error Response (404) - **body** (html) - Standard 404 Not Found HTML page. #### Response Example 404: Not Found404: Not Found ``` -------------------------------- ### Kiterunner Depth Scanning Wordlist Example Source: https://github.com/assetnote/kiterunner/blob/main/readme.md Provides an example of a wordlist used for depth scanning in Kiterunner. The paths in the wordlist illustrate different levels of directory depth, which Kiterunner uses to detect wildcards. ```plaintext /api/v1/user/create /api/v1/user/delete /api/v2/user/ /api/v2/admin/ /secrets/v1/ /secrets/v2/ ``` -------------------------------- ### Kiterunner Input and Domain Parsing Examples Source: https://github.com/assetnote/kiterunner/blob/main/readme.md Demonstrates how Kiterunner parses different input formats for domains, including full URIs, incomplete URIs, and hostnames with specified ports. It shows the expansion of these inputs into usable targets for scanning. ```bash one.com two.com:80 three.com:443 four.com:9447 https://five.com:9090 http://six.com:80/api ``` -------------------------------- ### GET / Source: https://github.com/assetnote/kiterunner/blob/main/api-signatures/kestrel.md This endpoint is the root path for the Kestrel service, typically used for basic access or redirection. ```APIDOC ## GET / ### Description Provides access to the root of the Kestrel service. ### Method GET ### Endpoint / ### Response #### Success Response (200) - **message** (string) - A welcome message or service information. #### Response Example ```json { "message": "Welcome to Kestrel" } ``` #### Error Response (404) - **error** (string) - Indicates the resource was not found. #### Response Example ```json { "error": "Not Found" } ``` ``` -------------------------------- ### GET / Source: https://github.com/assetnote/kiterunner/blob/main/api-signatures/nest.md Attempts to retrieve the root resource. Typically returns a 404 Not Found error for Nest applications. ```APIDOC ## GET / ### Description Attempts to retrieve the root resource. This endpoint is expected to return a 404 Not Found error in a Nest.js application. ### Method GET ### Endpoint / ### Parameters None ### Request Example None ### Response #### Error Response (404) - **statusCode** (integer) - The HTTP status code, expected to be 404. - **message** (string) - A message indicating the resource was not found. - **error** (string) - The type of error, expected to be "Not Found". #### Response Example ```json { "statusCode": 404, "message": "Cannot GET /", "error": "Not Found" } ``` ``` -------------------------------- ### GET / Source: https://github.com/assetnote/kiterunner/blob/main/api-signatures/tornado.md Retrieves the root endpoint of the Tornado server to identify the server signature. ```APIDOC ## GET / ### Description Fetches the root path of the server to verify the TornadoServer signature. ### Method GET ### Endpoint / ### Response #### Success Response (200) - **Server** (string) - The server header identifying the software as TornadoServer. #### Response Example { "Server": "TornadoServer" } ``` -------------------------------- ### Execute Kiterunner Scans with Assetnote Wordlists Source: https://github.com/assetnote/kiterunner/blob/main/readme.md Examples of using the -A flag to specify Assetnote wordlist aliases for scanning and brute-forcing targets. ```bash kr scan targets.txt -A=apiroutes-210228 -x 10 --ignore-length=34 kr brute targets.txt -A=aspx-210228 -x 10 --ignore-length=34 -easp,aspx ``` -------------------------------- ### Kiterunner Scan with Custom and Assetnote Wordlists (Bash) Source: https://github.com/assetnote/kiterunner/blob/main/readme.md This example shows how to use Kiterunner to scan a target domain, combining a custom wordlist with Assetnote's wordlists, and configuring concurrency and ignored status codes. ```bash kr scan target.com -w routes.kite -A=apiroutes-210328:20000 -x 20 -j 1 --fail-status-codes 400,401,404,403,501,502,426,411 ``` -------------------------------- ### GET / - Not Found Error Source: https://github.com/assetnote/kiterunner/blob/main/api-signatures/loopback.md This endpoint is expected to return a 'NotFoundError' when accessed. ```APIDOC ## GET / ### Description This endpoint is expected to return a 'NotFoundError'. ### Method GET ### Endpoint / ### Parameters None ### Request Example None ### Response #### Success Response (200) - **name** (string) - Indicates the type of error, 'NotFoundError'. #### Response Example ```json { "name": "NotFoundError" } ``` ``` -------------------------------- ### GET /thisshouldnotexist - Not Found Error Source: https://github.com/assetnote/kiterunner/blob/main/api-signatures/loopback.md This endpoint is designed to return a 'NotFoundError'. ```APIDOC ## GET /thisshouldnotexist ### Description This endpoint is designed to return a 'NotFoundError'. ### Method GET ### Endpoint /thisshouldnotexist ### Parameters None ### Request Example None ### Response #### Success Response (200) - **name** (string) - Indicates the type of error, 'NotFoundError'. #### Response Example ```json { "name": "NotFoundError" } ``` ``` -------------------------------- ### GET /api-auth/login/ Source: https://github.com/assetnote/kiterunner/blob/main/api-signatures/django.md Retrieves the Django REST framework login interface for user authentication. ```APIDOC ## GET /api-auth/login/ ### Description Accesses the login page provided by the Django REST framework to authenticate users. ### Method GET ### Endpoint /api-auth/login/ ### Parameters #### Query Parameters - **next** (string) - Optional - The URL to redirect to after successful authentication. ### Request Example GET /api-auth/login/?next=/ ### Response #### Success Response (200) - **Content-Type** (text/html) - Returns the HTML login form for the Django REST framework. ``` -------------------------------- ### GET / (Root and Non-existent Paths) Source: https://github.com/assetnote/kiterunner/blob/main/api-signatures/dropwizard.md Describes the behavior of the Dropwizard API when accessing the root path or undefined routes. ```APIDOC ## GET / ### Description Returns a 404 Not Found error when accessing the root or any undefined path on the Dropwizard server. ### Method GET ### Endpoint / ### Parameters None ### Request Example GET / ### Response #### Success Response (404) - **message** (string) - The error message indicating the resource was not found. #### Response Example { "message": "HTTP 404 Not Found" } ``` -------------------------------- ### GET / Source: https://github.com/assetnote/kiterunner/blob/main/api-signatures/jetty.md Attempts to access the root path of the Jetty server. It may return a problem message or server information. ```APIDOC ## GET / ### Description Attempts to access the root path of the Jetty server. This endpoint can reveal if the server is running and potentially expose error messages or server details. ### Method GET ### Endpoint / ### Parameters None ### Request Example None ### Response #### Success Response (200) - **Server** (string) - The server software, e.g., "Jetty" #### Error Response (e.g., 404) - **message** (string) - A message indicating a problem accessing the resource, e.g., "Problem accessing /. Reason:" ### Response Example ``` Server: Jetty ``` OR ``` Problem accessing /. Reason: ``` ``` -------------------------------- ### Kiterunner Vanilla Bruteforcing Source: https://github.com/assetnote/kiterunner/blob/main/readme.md Example of performing a vanilla brute-force scan using Kiterunner. It utilizes a specified wordlist and options for concurrency, default depth, ignored lengths, and output formats. ```bash kr brute https://target.com -A=raft-large-words -A=apiroutes-210228:20000 -x 10 -d=0 --ignore-length=34 -ejson,txt ``` -------------------------------- ### Kiterunner Traditional Bruteforce Scanning (Bash) Source: https://context7.com/assetnote/kiterunner/llms.txt Illustrates how to use Kiterunner's `kr brute` command for traditional directory and file bruteforcing. Examples include using text wordlists, file extensions, Assetnote wordlists, and compatibility modes. ```bash # Basic bruteforce with a text wordlist kr brute https://target.com -w wordlist.txt -x 10 --ignore-length=34 # Bruteforce with file extensions kr brute https://target.com -w wordlist.txt -x 10 -d=0 --ignore-length=34 -ejson,txt,xml,html # Use Assetnote wordlists for bruteforcing kr brute https://target.com -A=raft-large-words -A=apiroutes-210228:20000 -x 10 -d=0 --ignore-length=34 -ejson,txt # Dirsearch compatibility mode (replaces %EXT% in wordlist) kr brute https://target.com -w dirsearch.txt -x 10 -d=0 --ignore-length=34 -ejson,asp,aspx,ashx -D # Bruteforce a specific subpath kr brute https://target.com/subapp/ -A=aspx-210328:20000 -x 20 -j 1 # Read targets from stdin with extensions cat hosts | kr brute - -w wordlist.txt -easpx,asmx,ashx,asp --dirsearch-compat # Bruteforce with custom status code filtering kr brute https://target.com -w wordlist.txt --success-status-codes 200,301,302,403 -x 10 ``` -------------------------------- ### Laravel Signature Detection Source: https://github.com/assetnote/kiterunner/blob/main/api-signatures/laravel.md Endpoints and patterns used to identify Laravel framework installations. ```APIDOC ## GET / ### Description Detects Laravel installations via default headers and error page content. ### Method GET ### Endpoint / ### Parameters None ### Request Example GET / HTTP/1.1 ### Response #### Success Response (200) - **content** (string) - Contains "Environment & details:" or "Whoops, looks like something went wrong." #### Response Example { "message": "Whoops, looks like something went wrong." } ## GET /thisshouldnotexist ### Description Triggers a 404 Not Found page to identify Laravel specific error templates. ### Method GET ### Endpoint /thisshouldnotexist ### Response #### Success Response (404) - **content** (string) - Contains "Not Found" and references to "Nunito" font. #### Response Example { "error": "Not Found" } ``` -------------------------------- ### GET / Source: https://github.com/assetnote/kiterunner/blob/main/api-signatures/fastapi.md Retrieves a 'Not Found' message, indicating the root endpoint is not a valid resource. ```APIDOC ## GET / ### Description This endpoint is not a valid resource and will return a 'Not Found' error. ### Method GET ### Endpoint / ### Response #### Success Response (404) - **detail** (string) - Indicates that the requested resource was not found. ### Response Example ```json { "detail": "Not Found" } ``` ``` -------------------------------- ### GET /thisshouldntexist Source: https://github.com/assetnote/kiterunner/blob/main/api-signatures/jetty.md Attempts to access a non-existent path on the Jetty server, typically resulting in an error. ```APIDOC ## GET /thisshouldntexist ### Description Attempts to access a non-existent path on the Jetty server. This endpoint is expected to return an error message indicating the resource could not be found. ### Method GET ### Endpoint /thisshouldntexist ### Parameters None ### Request Example None ### Response #### Error Response (e.g., 404) - **message** (string) - A message indicating a problem accessing the resource, e.g., "Problem accessing /thisshouldntexist. Reason:" ### Response Example ``` Problem accessing /thisshouldntexist. Reason: ``` ``` -------------------------------- ### GET /thisshouldntexist Source: https://github.com/assetnote/kiterunner/blob/main/api-signatures/fastapi.md Attempts to access a non-existent endpoint, resulting in a 'Not Found' error. ```APIDOC ## GET /thisshouldntexist ### Description This endpoint does not exist and will return a 'Not Found' error. ### Method GET ### Endpoint /thisshouldntexist ### Response #### Success Response (404) - **detail** (string) - Indicates that the requested resource was not found. ### Response Example ```json { "detail": "Not Found" } ``` ``` -------------------------------- ### GET / Source: https://github.com/assetnote/kiterunner/blob/main/api-signatures/tomcat.md Attempts to access the root path of a Tomcat server. Typically returns a 404 Not Found error if the root path is not explicitly handled. ```APIDOC ## GET / ### Description Attempts to access the root path of a Tomcat server. This endpoint is often used to check if a server is running, though it may return a 404. ### Method GET ### Endpoint / ### Parameters None ### Request Example None ### Response #### Success Response (200) None #### Error Response (404) - **title** (string) - "HTTP Status 404 – Not Found" #### Response Example ```html HTTP Status 404 – Not Found ``` ``` -------------------------------- ### GET / - Powered By Loopback Source: https://github.com/assetnote/kiterunner/blob/main/api-signatures/loopback.md This endpoint returns an image indicating the service is powered by Loopback. ```APIDOC ## GET / ### Description This endpoint returns an image indicating the service is powered by Loopback. ### Method GET ### Endpoint / ### Parameters None ### Request Example None ### Response #### Success Response (200) - **image** (string) - The filename of the 'powered-by-loopback-sm.png' image. #### Response Example ``` powered-by-loopback-sm.png ``` ``` -------------------------------- ### GET /thisshouldnotexist Source: https://github.com/assetnote/kiterunner/blob/main/api-signatures/nest.md Attempts to access a non-existent endpoint. This request is expected to result in a 404 Not Found error. ```APIDOC ## GET /thisshouldnotexist ### Description Attempts to access a non-existent endpoint. This request is expected to return a 404 Not Found error. ### Method GET ### Endpoint /thisshouldnotexist ### Parameters None ### Request Example None ### Response #### Error Response (404) - **statusCode** (integer) - The HTTP status code, expected to be 404. - **message** (string) - A message indicating the resource was not found. - **error** (string) - The type of error, expected to be "Not Found". #### Response Example ```json { "statusCode": 404, "message": "Cannot GET /thisshouldnotexist", "error": "Not Found" } ``` ``` -------------------------------- ### http.Target - Target Configuration Source: https://context7.com/assetnote/kiterunner/llms.txt The Target type encapsulates connection details for a scan target including hostname, port, TLS settings, and custom headers. This example shows how to create, configure, and use a Target for making HTTP requests. ```APIDOC ## http.Target - Target Configuration ### Description The Target type encapsulates connection details for a scan target including hostname, port, TLS settings, and custom headers. ### Method N/A (This is a type definition and usage example) ### Endpoint N/A ### Parameters N/A ### Request Example ```go package main import ( "context" "fmt" "time" "github.com/assetnote/kiterunner/pkg/http" ) func main() { // Create target using pool (recommended for high-volume scanning) target := http.AcquireTarget() defer http.ReleaseTarget(target) // Configure target properties target.Hostname = "api.example.com" target.Port = 443 target.IsTLS = true target.BasePath = "/v2" // Prepended to all request paths // Add custom headers target.Headers = []http.Header{ {Key: []byte("Authorization"), Value: []byte("Bearer eyJhbGciOiJIUzI1NiIs...")}, {Key: []byte("X-API-Key"), Value: []byte("abc123")}, {Key: []byte("Accept"), Value: []byte("application/json")}, } // Set context for cancellation support ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() target.SetContext(ctx) // Parse host header (required before using target) target.ParseHostHeader() // Get HTTP client configured for this target client := target.HTTPClient(5, 3*time.Second) // maxConns, timeout // Create and execute a request route := &http.Route{ Path: []byte("/users"), Method: http.GET, Query: []byte("limit=100&offset=0"), } req := http.Request{ Target: target, Route: route, } config := &http.Config{ Timeout: 3 * time.Second, MaxRedirects: 3, ReadBody: true, ReadHeaders: true, } resp, err := http.DoClient(client, req, config) if err != nil { fmt.Printf("Request failed: %v\n", err) return } fmt.Printf("Response: %d - %d bytes\n", resp.StatusCode, resp.BodyLength) fmt.Printf("Target URL: %s\n", target.String()) // https://api.example.com:443/v2 // Check quarantine status (for wildcard detection) if target.Quarantined() { fmt.Println("Target was quarantined due to excessive matches") } } ``` ### Response N/A (This is a usage example) ``` -------------------------------- ### kiterunner.Engine - Core Scanning Engine Source: https://context7.com/assetnote/kiterunner/llms.txt The Engine type provides the primary interface for programmatic scanning, supporting both synchronous and asynchronous operation modes. This example demonstrates setting up routes, configuring the engine, and running an asynchronous scan. ```APIDOC ## kiterunner.Engine - Core Scanning Engine ### Description The Engine type provides the primary interface for programmatic scanning, supporting both synchronous and asynchronous operation modes. ### Method N/A (This is a type definition and usage example) ### Endpoint N/A ### Parameters N/A ### Request Example ```go package main import ( "context" "fmt" "time" "github.com/assetnote/kiterunner/pkg/http" "github.com/assetnote/kiterunner/pkg/kiterunner" "github.com/assetnote/kiterunner/pkg/proute" ) func main() { // Define routes to scan routes := http.RouteMap{ "/api": []*http.Route{ {Path: []byte("/api/v1/users"), Method: http.GET}, {Path: []byte("/api/v1/items"), Method: http.GET}, {Path: []byte("/api/v1/orders"), Method: http.POST}, }, "/admin": []*http.Route{ {Path: []byte("/admin/config"), Method: http.GET}, {Path: []byte("/admin/users"), Method: http.GET}, }, } // Create engine with configuration options engine := kiterunner.NewEngine(routes, kiterunner.MaxParallelHosts(50), kiterunner.MaxConnPerHost(5), kiterunner.MaxTimeout(3*time.Second), kiterunner.MaxRedirects(3), kiterunner.TargetQuarantineThreshold(10), kiterunner.WildcardDetection(true), ) ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel() // Start async scanning - returns input and output channels tx, rx, err := engine.RunAsync(ctx) if err != nil { panic(fmt.Sprintf("failed to start engine: %v", err)) } // Send targets to scan go func() { targets := []struct { hostname string port int tls bool }{ {"api.target.com", 443, true}, {"internal.target.com", 8080, false}, } for _, t := range targets { target := http.AcquireTarget() target.Hostname = t.hostname target.Port = t.port target.IsTLS = t.tls target.SetContext(ctx) tx <- target } close(tx) // Signal no more targets }() // Process results for result := range rx { fmt.Printf("Found: %s %s - Status: %d, Length: %d\n", result.Route.Method, result.Route.Path, result.Response.StatusCode, result.Response.BodyLength, ) result.Release() // Return to pool } } ``` ### Response N/A (This is a usage example) ``` -------------------------------- ### GET / (404 Not Found) Source: https://github.com/assetnote/kiterunner/blob/main/api-signatures/nginx.md This endpoint represents a 404 Not Found response when accessing the root path of the Nginx server. ```APIDOC ## GET / ### Description Returns a 404 Not Found error when accessing the root path. ### Method GET ### Endpoint / ### Response #### Success Response (404) - **body** (string) - HTML content indicating a 404 Not Found error. ### Response Example ```html

404 Not Found

``` ``` -------------------------------- ### GET /thisdoesntexist Source: https://github.com/assetnote/kiterunner/blob/main/api-signatures/tomcat.md Attempts to access a non-existent path on a Tomcat server. This is expected to return a 404 Not Found error. ```APIDOC ## GET /thisdoesntexist ### Description Attempts to access a path that does not exist on the Tomcat server. This is a common test to verify the server's error handling for invalid routes. ### Method GET ### Endpoint /thisdoesntexist ### Parameters None ### Request Example None ### Response #### Success Response (200) None #### Error Response (404) - **title** (string) - "HTTP Status 404 – Not Found" #### Response Example ```html HTTP Status 404 – Not Found ``` ``` -------------------------------- ### GET / Source: https://github.com/assetnote/kiterunner/blob/main/api-signatures/spring-boot.md Retrieves the root endpoint of the Spring Boot application, often returning a default error message or Whitelabel Error Page. ```APIDOC ## GET / ### Description Accesses the root path of the application to check for default Spring Boot error handling or index responses. ### Method GET ### Endpoint / ### Response #### Success Response (200) - **message** (string) - The error message returned by the server. - **path** (string) - The path requested. #### Response Example { "message": "No message available", "path": "/" } ``` -------------------------------- ### GET /profile Source: https://github.com/assetnote/kiterunner/blob/main/api-signatures/spring-boot.md Attempts to access the profile endpoint, which is often used in Spring Boot applications to expose configuration or link information. ```APIDOC ## GET /profile ### Description Checks for the existence of the profile endpoint, which may return HATEOAS links or configuration metadata. ### Method GET ### Endpoint /profile ### Response #### Success Response (200) - **_links** (object) - A collection of HATEOAS links associated with the profile. #### Response Example { "_links": { "self": { "href": "http://example.com/profile" } } } ``` -------------------------------- ### Run Async Scan with Kiterunner Engine Source: https://context7.com/assetnote/kiterunner/llms.txt Demonstrates how to initialize and run the Kiterunner Engine in asynchronous mode. It shows setting up routes, configuring engine options, sending targets via a channel, and processing scan results. Dependencies include the kiterunner and http packages. ```go package main import ( "context" "fmt" "time" "github.com/assetnote/kiterunner/pkg/http" "github.com/assetnote/kiterunner/pkg/kiterunner" "github.com/assetnote/kiterunner/pkg/proute" ) func main() { // Define routes to scan routes := http.RouteMap{ "/api": []*http.Route{ {Path: []byte("/api/v1/users"), Method: http.GET}, {Path: []byte("/api/v1/items"), Method: http.GET}, {Path: []byte("/api/v1/orders"), Method: http.POST}, }, "/admin": []*http.Route{ {Path: []byte("/admin/config"), Method: http.GET}, {Path: []byte("/admin/users"), Method: http.GET}, }, } // Create engine with configuration options engine := kiterunner.NewEngine(routes, kiterunner.MaxParallelHosts(50), kiterunner.MaxConnPerHost(5), kiterunner.MaxTimeout(3*time.Second), kiterunner.MaxRedirects(3), kiterunner.TargetQuarantineThreshold(10), kiterunner.WildcardDetection(true), ) ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel() // Start async scanning - returns input and output channels tx, rx, err := engine.RunAsync(ctx) if err != nil { panic(fmt.Sprintf("failed to start engine: %v", err)) } // Send targets to scan go func() { targets := []struct { hostname string port int tls bool }{ {"api.target.com", 443, true}, {"internal.target.com", 8080, false}, } for _, t := range targets { target := http.AcquireTarget() target.Hostname = t.hostname target.Port = t.port target.IsTLS = t.tls target.SetContext(ctx) tx <- target } close(tx) // Signal no more targets }() // Process results for result := range rx { fmt.Printf("Found: %s %s - Status: %d, Length: %d\n", result.Route.Method, result.Route.Path, result.Response.StatusCode, result.Response.BodyLength, ) result.Release() // Return to pool } } ``` -------------------------------- ### Build Kiterunner from Source and Compile Wordlists (Bash) Source: https://context7.com/assetnote/kiterunner/llms.txt Instructions for cloning the Kiterunner repository, building the binary, and compiling wordlists from JSON to the .kite format for API scanning. It also shows how to download pre-compiled .kite files. ```bash git clone https://github.com/assetnote/kiterunner.git cd kiterunner make build ln -s $(pwd)/dist/kr /usr/local/bin/kr wget https://wordlists-cdn.assetnote.io/rawdata/kiterunner/routes-small.json.tar.gz tar -xzf routes-small.json.tar.gz kr kb compile routes-small.json routes.kite wget https://wordlists-cdn.assetnote.io/data/kiterunner/routes-small.kite.tar.gz tar -xzf routes-small.kite.tar.gz ``` -------------------------------- ### Define Parameterized API Routes in Go Source: https://context7.com/assetnote/kiterunner/llms.txt This snippet demonstrates how to initialize an API definition using proute, configure global headers and query parameters, and define specific routes with dynamic path, query, and body crumbs. It concludes by converting the definition into executable HTTP routes and performing a debug print. ```go package main import ( "fmt" "github.com/assetnote/kiterunner/pkg/http" "github.com/assetnote/kiterunner/pkg/proute" ) func main() { api := proute.NewAPI("", "https://api.example.com") api.HeaderCrumbs = []proute.Crumb{ &proute.StaticCrumb{K: "Content-Type", V: "application/json"}, &proute.StaticCrumb{K: "Accept", V: "application/json"}, } api.QueryCrumbs = []proute.Crumb{ &proute.StaticCrumb{K: "api_version", V: "v2"}, } api.Routes = []proute.Route{ { Method: http.GET, PathCrumbs: []proute.Crumb{ &proute.StaticCrumb{V: "/users"}, }, QueryCrumbs: []proute.Crumb{ &proute.IntCrumb{K: "limit"}, &proute.IntCrumb{K: "offset"}, &proute.StaticCrumb{K: "sort", V: "created_at"}, }, }, { Method: http.POST, PathCrumbs: []proute.Crumb{ &proute.StaticCrumb{V: "/users"}, }, BodyCrumbs: []proute.Crumb{ &proute.StringCrumb{K: "name"}, &proute.StringCrumb{K: "email"}, &proute.UUIDCrumb{K: "tenant_id"}, }, HeaderCrumbs: []proute.Crumb{ &proute.StaticCrumb{K: "X-Request-ID", V: ""}, }, }, { Method: http.GET, PathCrumbs: []proute.Crumb{ &proute.StaticCrumb{V: "/users/"}, &proute.UUIDCrumb{}, }, }, } httpRoutes := api.ToHTTPRoutes() for _, route := range httpRoutes { fmt.Printf("%s %s?%s\n", route.Method, route.Path, route.Query) } apis := proute.APIS{api} limited := apis.First(100) fmt.Printf("Limited to %d APIs\n", len(limited)) api.DebugPrint() } ``` -------------------------------- ### Build and Compile Kiterunner Wordlists (Bash) Source: https://github.com/assetnote/kiterunner/blob/main/readme.md This snippet demonstrates how to build the Kiterunner binary from source, compile JSON wordlists into the Kiterunner's native '.kite' format, and then use the compiled wordlist for scanning hosts. ```bash make build ln -s $(pwd)/dist/kr /usr/local/bin/kr kr kb compile routes.json routes.kite kr scan hosts.txt -w routes.kite -x 20 -j 100 --ignore-length=1053 ``` -------------------------------- ### Configure Kiterunner Engine Programmatically in Go Source: https://context7.com/assetnote/kiterunner/llms.txt Demonstrates how to initialize and customize the Kiterunner engine using both direct struct configuration and functional options. It includes setting concurrency limits, HTTP timeouts, and implementing custom request validators. ```go package main import ( "fmt" "time" "github.com/assetnote/kiterunner/pkg/http" "github.com/assetnote/kiterunner/pkg/kiterunner" ) type CustomValidator struct { blockedPaths []string } func (v *CustomValidator) Validate(resp http.Response, wcr kiterunner.WildcardResponses, config *kiterunner.Config) error { if resp.StatusCode == 500 { return fmt.Errorf("server error responses blocked") } return nil } func main() { config := kiterunner.NewDefaultConfig() config.MaxParallelHosts = 100 config.MaxConnPerHost = 10 config.QuarantineThreshold = 15 config.WildcardDetection = true config.Delay = 100 * time.Millisecond config.HTTP.Timeout = 5 * time.Second config.RequestValidators = append(config.RequestValidators, &CustomValidator{blockedPaths: []string{"/health", "/status"}}) routes := http.RouteMap{} engine := kiterunner.NewEngine(routes, kiterunner.MaxParallelHosts(100), kiterunner.MaxConnPerHost(10), kiterunner.MaxTimeout(5*time.Second), ) } ``` -------------------------------- ### GET /api/v2.0/pinga Source: https://github.com/assetnote/kiterunner/blob/main/api-signatures/kestrel.md This endpoint is used to check the status or health of the Kestrel service. ```APIDOC ## GET /api/v2.0/pinga ### Description Checks the health status of the Kestrel service. ### Method GET ### Endpoint /api/v2.0/pinga ### Response #### Success Response (200) - **message** (string) - Indicates the service is operational. #### Response Example ```json { "message": "pong" } ``` #### Error Response (404) - **error** (string) - Indicates the resource was not found. #### Response Example ```json { "error": "Not Found" } ``` ``` -------------------------------- ### Configure and Use http.Target for Scans Source: https://context7.com/assetnote/kiterunner/llms.txt Illustrates how to configure a scan target using the http.Target type, including setting hostname, port, TLS, base path, and custom headers. It also shows how to create an HTTP client, make a request, and check target quarantine status. This utilizes the http package. ```go package main import ( "context" "fmt" "time" "github.com/assetnote/kiterunner/pkg/http" ) func main() { // Create target using pool (recommended for high-volume scanning) target := http.AcquireTarget() defer http.ReleaseTarget(target) // Configure target properties target.Hostname = "api.example.com" target.Port = 443 target.IsTLS = true target.BasePath = "/v2" // Prepended to all request paths // Add custom headers target.Headers = []http.Header{ {Key: []byte("Authorization"), Value: []byte("Bearer eyJhbGciOiJIUzI1NiIs...")}, {Key: []byte("X-API-Key"), Value: []byte("abc123")}, {Key: []byte("Accept"), Value: []byte("application/json")}, } // Set context for cancellation support ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() target.SetContext(ctx) // Parse host header (required before using target) target.ParseHostHeader() // Get HTTP client configured for this target client := target.HTTPClient(5, 3*time.Second) // maxConns, timeout // Create and execute a request route := &http.Route{ Path: []byte("/users"), Method: http.GET, Query: []byte("limit=100&offset=0"), } req := http.Request{ Target: target, Route: route, } config := &http.Config{ Timeout: 3 * time.Second, MaxRedirects: 3, ReadBody: true, ReadHeaders: true, } resp, err := http.DoClient(client, req, config) if err != nil { fmt.Printf("Request failed: %v\n", err) return } fmt.Printf("Response: %d - %d bytes\n", resp.StatusCode, resp.BodyLength) fmt.Printf("Target URL: %s\n", target.String()) // https://api.example.com:443/v2 // Check quarantine status (for wildcard detection) if target.Quarantined() { fmt.Println("Target was quarantined due to excessive matches") } } ``` -------------------------------- ### Kiterunner API Scanning with Target List File Source: https://github.com/assetnote/kiterunner/blob/main/readme.md Demonstrates how to initiate an API scan using a file containing a list of targets. Kiterunner reads each line from the specified file as a target for the scan. ```bash kr scan targets.txt -w routes.kite -A=apiroutes-210228:20000 -x 10 --ignore-length=34 ``` -------------------------------- ### List Available Assetnote Wordlists Source: https://github.com/assetnote/kiterunner/blob/main/readme.md Command to display all available Assetnote wordlists, including their aliases, filenames, source, count, and cache status. ```bash kr wordlist list ``` -------------------------------- ### Kiterunner CLI Help - Scan Command Source: https://github.com/assetnote/kiterunner/blob/main/readme.md Displays the help information for the 'kite scan' command, outlining its usage, available flags, and global options. This includes parameters for assetnote wordlists, blacklisted domains, request delays, and more. ```bash Usage: kite scan [flags] Flags: -A, --assetnote-wordlist strings use the wordlists from wordlist.assetnote.io. specify the type/name to use, e.g. apiroutes-210228. You can specify an additional maxlength to use only the first N values in the wordlist, e.g. apiroutes-210228;20000 will only use the first 20000 lines in that wordlist --blacklist-domain strings domains that are blacklisted for redirects. We will not follow redirects to these domains --delay duration delay to place inbetween requests to a single host --disable-precheck whether to skip host discovery --fail-status-codes ints which status codes blacklist as fail. if this is set, this will override success-status-codes --filter-api strings only scan apis matching this ksuid --force-method string whether to ignore the methods specified in the ogl file and force this method -H, --header strings headers to add to requests (default [x-forwarded-for: 127.0.0.1]) -h, --help help for scan --ignore-length strings a range of content length bytes to ignore. you can have multiple. e.g. 100-105 or 1234 or 123,34-53. This is inclusive on both ends --kitebuilder-full-scan perform a full scan without first performing a phase scan. -w, --kitebuilder-list strings ogl wordlist to use for scanning -x, --max-connection-per-host int max connections to a single host (default 3) -j, --max-parallel-hosts int max number of concurrent hosts to scan at once (default 50) --max-redirects int maximum number of redirects to follow (default 3) -d, --preflight-depth int when performing preflight checks, what directory depth do we attempt to check. 0 means that only the docroot is checked (default 1) --profile-name string name for profile output file --progress a progress bar while scanning. by default enabled only on Stderr (default true) --quarantine-threshold int if the host return N consecutive hits, we quarantine the host as wildcard. Set to 0 to disable (default 10) --success-status-codes ints which status codes whitelist as success. this is the default mode -t, --timeout duration timeout to use on all requests (default 3s) --user-agent string user agent to use for requests (default "Chrome. Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36") --wildcard-detection can be set to false to disable wildcard redirect detection (default true) Global Flags: --config string config file (default is $HOME/.kiterunner.yaml) -o, --output string output format. can be json,text,pretty (default "pretty") -q, --quiet quiet mode. will mute unecessarry pretty text -v, --verbose string level of logging verbosity. can be error,info,debug,trace (default "info") ``` -------------------------------- ### Kiterunner Dirsearch Bruteforcing with Extension Substitution Source: https://github.com/assetnote/kiterunner/blob/main/readme.md Shows how to use Kiterunner for Dirsearch-style bruteforcing, specifically when the wordlist contains '%EXT%' placeholders for file extensions. The '-D' flag enables this substitution. ```bash kr brute https://target.com -w dirsearch.txt -x 10 -d=0 --ignore-length=34 -ejson,txt -D ``` -------------------------------- ### Apply Head Syntax to Limit Wordlist Lines Source: https://github.com/assetnote/kiterunner/blob/main/readme.md Demonstrates how to use the : syntax to restrict the number of lines processed from a specific wordlist. ```bash # this will use the first 20000 lines in the api routes wordlist kr scan targets.txt -A=apiroutes-210228:20000 -x 10 --ignore-length=34 # this will use the first 10 lines in the aspx wordlist kr brute targets.txt -A=aspx-210228:10 -x 10 --ignore-length=34 -easp,aspx ``` -------------------------------- ### GET / (403 Forbidden) Source: https://github.com/assetnote/kiterunner/blob/main/api-signatures/nginx.md This endpoint represents a 403 Forbidden response when accessing the root path of the Nginx server. ```APIDOC ## GET / ### Description Returns a 403 Forbidden error when accessing the root path. ### Method GET ### Endpoint / ### Response #### Success Response (403) - **body** (string) - HTML content indicating a 403 Forbidden error. ### Response Example ```html

403 Forbidden

``` ``` -------------------------------- ### Kiterunner API Scanning with HTTP and HTTPS Source: https://github.com/assetnote/kiterunner/blob/main/readme.md Illustrates scanning a single target domain, attempting both HTTP and HTTPS protocols. This is useful when the protocol is not explicitly known or needs to be tested for both cases. ```bash kr scan target.com -w routes.kite -A=apiroutes-210228:20000 -x 10 --ignore-length=34 ``` -------------------------------- ### Replay Request with Kiterunner CLI Source: https://github.com/assetnote/kiterunner/blob/main/readme.md Replays a captured HTTP request using the `kb replay` command. This command reconstructs the request from wordlists and can forward it through a specified proxy for inspection. The Go net/http client may alter the request slightly. ```bash ❯ go run ./cmd/kiterunner kb replay -q --proxy=http://localhost:8080 -w routes.kite "POST 403 [ 287, 10, 1] https://target.com/dedalo/lib/dedalo/publication/server_api/v1/json/thesaurus_parents 0cc39f76702ea287ec3e93f4b4710db9c8a86251" 11:25AM INF Raw reconstructed request POST /dedalo/lib/dedalo/publication/server_api/v1/json/thesaurus_parents?ar_fields=48637466&code=66132381&db_name=08791392&lang=lg-eng&recursive=false&term_id=72336471 HTTP/1.1 Content-Type: any 11:25AM INF Outbound request POST /dedalo/lib/dedalo/publication/server_api/v1/json/thesaurus_parents?ar_fields=48637466&code=66132381&db_name=08791392&lang=lg-eng&recursive=false&term_id=72336471 HTTP/1.1 Host: target.com User-Agent: Go-http-client/1.1 Content-Length: 0 Content-Type: any Accept-Encoding: gzip 11:25AM INF Response After Redirects HTTP/1.1 403 Forbidden Connection: close Content-Length: 45 Content-Type: application/json Date: Wed, 07 Apr 2021 01:25:28 GMT X-Amzn-Requestid: 7e6b2ea1-c662-4671-9eaa-e8cd31b463f2 User is not authorized to perform this action ``` -------------------------------- ### Kiterunner API Endpoint Scanning (Bash) Source: https://context7.com/assetnote/kiterunner/llms.txt Demonstrates various ways to perform API endpoint scanning using Kiterunner's `kr scan` command. It covers scanning single targets, multiple targets from a file, using Assetnote wordlists, combining local and Assetnote wordlists, custom headers, timeouts, and different scanning modes. ```bash # Scan a single target with a compiled kite wordlist kr scan https://target.com:8443/ -w routes.kite -x 10 --ignore-length=34 # Scan multiple targets from a file kr scan hosts.txt -w routes.kite -x 10 -j 100 --ignore-length=34 # Scan using Assetnote wordlists (auto-downloaded and cached) kr scan hosts.txt -A=apiroutes-210328:20000 -x 5 -j 100 --fail-status-codes 400,401,404,403,501,502,426,411 # Combine local wordlist with Assetnote wordlists kr scan target.com -w routes.kite -A=apiroutes-210328:20000 -x 20 -j 1 --fail-status-codes 400,401,404,403,501,502,426,411 # Scan with custom headers and timeout kr scan https://api.target.com -w routes.kite -x 5 -t 5s -H "Authorization: Bearer token123" -H "X-Custom-Header: value" # Full scan without phase optimization (more thorough but slower) kr scan target.com -w routes.kite --kitebuilder-full-scan -x 10 # Disable wildcard detection for specific cases kr scan target.com -w routes.kite --wildcard-detection=false -x 10 # Scan with depth-based preflight checks (for virtual path routing) kr scan target.com -w routes.kite -d 2 -x 10 # Read targets from stdin cat hosts.txt | kr scan - -w routes.kite -x 5 -j 50 ```