
Высокоскоростной инструмент для обнаружения API и веб-контента, который перебирает маршруты с использованием скомпилированных наборов данных Swagger, поддерживая сканирование в глубину, пользовательские списки слов и одновременное сканирование хостов.

Долгое время обнаружение контента было сосредоточено на поиске файлов и папок. Хотя этот подход эффективен для устаревших веб-серверов, которые обслуживают статические файлы или отвечают 3xx при частичном пути, он больше не эффективен для современных веб-приложений, особенно API.
Со временем мы видели, как много усилий было вложено в ускорение инструментов обнаружения контента, чтобы можно было использовать более крупные списки слов, однако искусство обнаружения контента не получило инноваций.
Kiterunner — это инструмент, способный не только выполнять традиционное обнаружение контента с молниеносной скоростью, но и перебирать маршруты/конечные точки в современных приложениях.
Современные фреймворки приложений, такие как Flask, Rails, Express, Django и другие, следуют парадигме явного определения маршрутов, которые ожидают определенные HTTP-методы, заголовки, параметры и значения.
При использовании традиционных инструментов обнаружения контента такие маршруты часто упускаются и их трудно обнаружить.
Собрав набор спецификаций Swagger и сконденсировав его в собственную схему, Kiterunner может использовать этот набор для перебора конечных точек API, отправляя правильный HTTP-метод, заголовки, путь, параметры и значения для каждого отправляемого запроса.
Файлы Swagger были собраны из нескольких источников данных, включая интернет-сканирование 40+ наиболее распространенных путей Swagger. Другие источники данных включали GitHub через BigQuery и APIs.guru.
Вы можете загрузить предварительно собранную копию с https://github.com/assetnote/kiterunner/releases.
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
Наборы данных JSON можно найти ниже:
- [routes-large.json](https://wordlists-cdn.assetnote.io/rawdata/kiterunner/routes-large.json.tar.gz) (118MB сжатый, 2.6GB распакованный)
- [routes-small.json](https://wordlists-cdn.assetnote.io/rawdata/kiterunner/routes-small.json.tar.gz) (14MB сжатый, 228MB распакованный)
Кроме того, можно загрузить скомпилированные файлы `.kite` по ссылкам ниже:
- [routes-large.kite](https://wordlists-cdn.assetnote.io/data/kiterunner/routes-large.kite.tar.gz) (40MB сжатый, 183M распакованный)
- [routes-small.kite](https://wordlists-cdn.assetnote.io/data/kiterunner/routes-small.kite.tar.gz) (2MB сжатый, 35MB распакованный)
## AUR
Пользователи дистрибутивов на основе Arch могут загрузить предварительно собранный бинарный файл из [AUR](https://aur.archlinux.org/packages/kiterunner-bin/)
Вы можете использовать "Aur Helper", например `yay`, для установки kiterunner```
yay -S kiterunner-bin
kr [scan|brute] [flags]
- `<input>` может быть файлом, доменом или URI. мы разберемся за вас. См. [Input/Host Formatting](#inputhost-formatting) для получения дополнительных сведений```
# Just have a list of hosts and no wordlist
kr scan hosts.txt -A=apiroutes-210328:20000 -x 5 -j 100 --fail-status-codes 400,401,404,403,501,502,426,411
# You have your own wordlist but you want assetnote wordlists too
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
# Bruteforce like normal but with the first 20000 words
kr brute https://target.com/subapp/ -A=aspx-210328:20000 -x 20 -j 1
# Use a dirsearch style wordlist with %EXT%
kr brute https://target.com/subapp/ -w dirsearch.txt -x 20 -j 1 -exml,asp,aspx,ashx -D
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")
bruteforce флаги (все флаги выше +)```
-D, --dirsearch-compat this will replace %EXT% with the extensions provided. backwards compat with dirsearch because shubs loves him some dirsearch
-e, --extensions strings extensions to append while scanning
-w, --wordlist strings normal wordlist to use for scanning
При подаче ввода kiterunner попытается обработать его в следующем порядке:
Если вы указываете «домен», но он существует как файл, например google.com, а google.com также является текстовым файлом в текущем каталоге,
мы загрузим google.com как текстовый файл, так как он найден первым.
Разбор доменов
Предпочтительно указывать полный URI в качестве ввода, однако вы можете указать неполные URI, и мы попытаемся угадать, что вы имеете в виду. Пример списка доменов, которые вы можете указать:``` one.com two.com:80 three.com:443 four.com:9447 https://five.com:9090 http://six.com:80/api
Приведенный выше список доменов расширится до последующего списка целей```
(two targets are created for one.com, since neither port nor protocol was specified)
http://one.com (port 80 implied)
https://one.com (port 443 implied)
http://two.com (port 80 implied)
https://three.com (port 443 implied)
http://four.com:9447 (non-tls port guessed)
https://five.com:9090
http://six.com/api (port 80 implied; basepath API appended)
Когда у вас есть одна цель```bash
kr scan https://target.com:8443/ -w routes.kite -A=apiroutes-210228:20000 -x 10 --ignore-length=34
kr scan target.com -w routes.kite -A=apiroutes-210228:20000 -x 10 --ignore-length=34
kr scan targets.txt -w routes.kite -A=apiroutes-210228:20000 -x 10 --ignore-length=34
## Обычный брутфорс```bash
kr brute https://target.com -A=raft-large-words -A=apiroutes-210228:20000 -x 10 -d=0 --ignore-length=34 -ejson,txt
Для случаев, когда у вас есть старый словарь, в котором всё ещё присутствует %EXT%, вы можете использовать -D. Это заменит расширение только там, где %EXT% присутствует в пути.```bash
kr brute https://target.com -w dirsearch.txt -x 10 -d=0 --ignore-length=34 -ejson,txt -D
# Технические особенности
## Сканирование по глубине
Ключевая особенность kiterunner — это сканирование на основе глубины. Оно предназначено для обработки обнаружения подстановочных знаков (wildcards) при маршрутизации на основе виртуальных путей приложения. Глубина определяет, на сколько уровней вложенности каталогов выполняются базовые проверки, например```bash
~/kiterunner $ cat wordlist.txt
/api/v1/user/create
/api/v1/user/delete
/api/v2/user/
/api/v2/admin/
/secrets/v1/
/secrets/v2/
/ будет иметь базовые проверки для обнаружения подстановочных запросов (wildcard)/api и /secrets будут иметь базовые проверки; эти проверки будут применяться соответственно к /api и /secrets/api/v1, /api/v2, /secrets/v1 и /secrets/v2 будут иметь базовые проверки.По умолчанию kr scan использует глубину 1, так как на основе внутреннего использования мы часто видим, что это наиболее распространенная глубина, на которой происходит виртуальная маршрутизация. kr brute имеет глубину по умолчанию 0, так как обычно не требуется выполнять эту проверку со статическим списком слов.
Естественно, увеличение глубины повышает точность сканирования, но также увеличивает количество запросов к цели. (# базовых проверок * # каталогов базовой глубины). Поэтому мы рекомендуем не превышать глубину 1, и в редких случаях — глубину 2.
Мы предоставляем встроенную загрузку и кэширование списков слов с assetnote.io. Вы можете использовать их с флагом -A, который принимает список псевдонимов или полных имен, разделенных запятыми.
Полный список всех списков слов Assetnote можно получить с помощью kr wordlist list.
При использовании списки слов кэшируются в ~/.cache/kiterunner/wordlists. При использовании они компилируются из .txt в .kite.```
+-----------------------------------+-------------------------------------------------------+----------------+---------+----------+--------+
| ALIAS | FILENAME | SOURCE | COUNT | FILESIZE | CACHED |
+-----------------------------------+-------------------------------------------------------+----------------+---------+----------+--------+
| 2m-subdomains | 2m-subdomains.txt | manual.json | 2167059 | 28.0mb | false |
| asp_lowercase | asp_lowercase.txt | manual.json | 24074 | 1.1mb | false |
| aspx_lowercase | aspx_lowercase.txt | manual.json | 80293 | 4.4mb | false |
| bak | bak.txt | manual.json | 31725 | 634.8kb | false |
| best-dns-wordlist | best-dns-wordlist.txt | manual.json | 9996122 | 139.0mb | false |
| cfm | cfm.txt | manual.json | 12100 | 260.3kb | true |
| do | do.txt | manual.json | 173152 | 4.8mb | false |
| dot_filenames | dot_filenames.txt | manual.json | 3191712 | 71.3mb | false |
| html | html.txt | manual.json | 4227526 | 107.7mb | false |
| apiroutes-201120 | httparchive_apiroutes_2020_11_20.txt | automated.json | 953011 | 45.3mb | false |
| apiroutes-210128 | httparchive_apiroutes_2021_01_28.txt | automated.json | 225456 | 6.6mb | false |
| apiroutes-210228 | httparchive_apiroutes_2021_02_28.txt | automated.json | 223544 | 6.5mb | true |
| apiroutes-210328 | httparchive_apiroutes_2021_03_28.txt | automated.json | 215114 | 6.3mb | false |
| aspx-201118 | httparchive_aspx_asp_cfm_svc_ashx_asmx_2020_11_18.txt | automated.json | 63200 | 1.7mb | false |
| aspx-210128 | httparchive_aspx_asp_cfm_svc_ashx_asmx_2021_01_28.txt | automated.json | 46286 | 928.7kb | false |
| aspx-210228 | httparchive_aspx_asp_cfm_svc_ashx_asmx_2021_02_28.txt | automated.json | 43958 | 883.3kb | false |
| aspx-210328 | httparchive_aspx_asp_cfm_svc_ashx_asmx_2021_03_28.txt | automated.json | 45928 | 926.8kb | false |
| cgi-201118 | httparchive_cgi_pl_2020_11_18.txt | automated.json | 2637 | 44.0kb | false |
When using assetnote provided wordlists, you may not want to use the entire wordlist, so you can opt to use the first N lines in a given wordlist using the head syntax. The format is <wordlist_name>:<N lines> when specifying a wordlist.
Использование```
kr scan targets.txt -A=apiroutes-210228:20000 -x 10 --ignore-length=34
kr brute targets.txt -A=aspx-210228:10 -x 10 --ignore-length=34 -easp,aspx
## Настройки параллелизма/Ускорение
Kiterunner создан для работы на большом количестве хостов. Но из-за того, что вы можете запустить kiterunner с 20000 горутин, это не значит, что это хорошая идея. Узкие места и снижение производительности возникнут при высоком количестве потоков из-за увеличения времени на планирование горутин, ожидающих сетевого ввода-вывода и переключения контекста ядра.
В kiterunner есть два основных параметра параллелизма:
- `-x, --max-connection-per-host` — максимальное количество открытых соединений на одном хосте. Каждое соединение управляется одной горутиной. Чтобы избежать DOS на хост, мы рекомендуем держать этот параметр в диапазоне 5–10. В зависимости от задержки до цели, в среднем это даст от 1 до 5 запросов в секунду на одно соединение (200 мс–1000 мс/запрос) к хосту.
- `-j, --max-parallel-hosts` — максимальное количество хостов, сканируемых одновременно. Каждый хост управляется одной горутиной-супервизором.
В зависимости от аппаратного обеспечения, с которого вы выполняете сканирование, «максимальное» количество горутин, которое вы можете оптимально запустить, будет различаться. На AWS t3.medium мы заметили снижение производительности при превышении 2500 горутин. То есть 500 хостов × 5 соединений на хост (2500) давали пиковую производительность.
Мы рекомендуем **не** запускать kiterunner с вашего **macbook**. Из-за плохой оптимизации ядра для высоких нагрузок ввода-вывода и системных вызовов Epoll на macOS мы заметили существенно более низкую (в 0,3–0,5 раза) производительность по сравнению с запуском kiterunner на аналогично настроенном экземпляре Linux.
Для максимальной производительности при сканировании отдельной цели или большой поверхности атаки мы рекомендуем следующие советы:
- Запустите EC2-инстанс в том же географическом регионе/дата-центре, что и цели(и), которые вы сканируете.
- Выполните несколько начальных тестов на вашем наборе целей с различными значениями `-x` и `-j`. Рекомендуем начинать с типичной точки `-x 5 -j 100` и увеличивать `-j` по мере того, как позволяет загрузка ЦП/производительность сети.
## Конвертация между форматами файлов
Kiterunner также позволяет конвертировать между JSON-схемой, kite-файлом и стандартным текстовым списком слов.
**Использование**
Формат определяется расширением файла, указанным в полях `<input>` и `<output>`. Мы поддерживаем `txt`, `json` и `kite`.```bash
kr kb convert wordlist.txt wordlist.kite
kr kb convert wordlist.kite wordlist.json
kr kb convert wordlist.kite wordlist.txt
❯ go run ./cmd/kiterunner kb convert -qh
convert an input file format into the specified output file format
this will determine the conversion based on the extensions of the input and the output
we support the following filetypes: txt, json, kite
You can convert any of the following into the corresponding types
-d Debug mode will attempt to convert the schema with error handling
-v=debug Debug verbosity will print out the errors for the schema
Usage:
kite kb convert <input> <output> [flags]
Flags:
-d, --debug debug the parsing
-h, --help help for convert
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")``bigquery
Когда вы получаете множество результатов от kiterunner, бывает сложно сразу понять, почему запрос вызывает определённый код ответа/длину. Kiterunner предоставляет способ восстановления запроса из использованных списков слов, включая все заголовки и параметры тела.
kb replay.--proxy для перенаправления запросов через прокси, чтобы вы могли изменять/повторять/перехватывать запрос с помощью сторонних инструментов, если захотите.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
# Техническая реализация
## Промежуточный тип данных (PRoutes)
Мы используем промежуточное представление wordlist'ов и JSON-схем kitebuilder в kiterunner. Это позволяет нам динамически генерировать поля в wordlist'е и восстанавливать тела/заголовки запросов и параметры запроса из заданной спецификации.
Тип PRoute состоит из параметров Headers, Body, Query и Cookie, которые кодируются в `pkg/proute.Crumb`. Тип Crumb — это интерфейс, который реализуется для таких типов, как UUID, Float, Int, Random String и т.д.
При выполнении преобразований в файлы txt, json и kite и из них все преобразования сначала выполняются в промежуточный тип `proute.API`. Затем записывается соответствующая кодировка.
## Формат файла Kite
Мы используем суперсекретный формат файла kite для хранения JSON-схем из kitebuilder. Это просто protobuf-закодированные `pkg/proute.APIS`, записанные в файл. Компиляция используется для быстрой десериализации уже разобранного wordlist'а. Этот формат файла нестабилен и должен использоваться только с встроенными инструментами преобразования в kiterunner.
При выпуске новой версии формата файла kite вам может потребоваться перекомпилировать ваши kite-файлы.