
أداة لتدقيق نقاط النهاية المُعرفة في ملفات تعريف (Swagger/OpenAPI) المكشوفة.
# sj (Swagger Jacker)

sj هي أداة سطر أوامر مصممة للمساعدة في تدقيق ملفات تعريف Swagger/OpenAPI المكشوفة من خلال فحص نقاط نهاية API المرتبطة بها بحثًا عن مصادقة ضعيفة. كما توفر قوالب أوامر لاختبار الثغرات يدويًا.
تقوم بذلك عن طريق تحليل ملف التعريف بحثًا عن المسارات والمعاملات والطرق المقبولة قبل استخدام النتائج مع أحد الأوامر الفرعية الخمسة:
- `automate` - يصيغ سلسلة من الطلبات ويحلل رمز الحالة للاستجابة.
- `prepare` - ينشئ قائمة بالأوامر لاستخدامها في الاختبار اليدوي.
- `endpoints` - ينشئ قائمة بمسارات API الخام. *لن يتم استبدال قيم المسار ببيانات الاختبار*.
- `brute` - يرسل سلسلة من الطلبات إلى هدف للعثور على تعريفات العمليات بناءً على مسارات الملفات الشائعة الاستخدام.
- `convert` - يحول ملف التعريف من الإصدار v2 إلى v3.
## البناء
للترجمة من المصدر، تأكد من تثبيت إصدار Go `>= 1.22.5` وقم بتشغيل `go build` من داخل المستودع:
```bash
$ git clone https://github.com/BishopFox/sj.git
$ cd sj/
$ go build .
```
## التثبيت
لتثبيت أحدث إصدار من الأداة، قم بتشغيل:
```bash
$ go install github.com/BishopFox/sj@latest
# Note: you may also need to place the path to your Go binaries within your PATH environment variable:
$ export PATH=$PATH:~/go/bin
```
## الاستخدام
> استخدم الأمر `automate` لإرسال سلسلة من الطلبات إلى كل نقطة نهاية محددة وتحليل رمز الحالة لكل استجابة.
```bash
$ sj automate -u https://petstore.swagger.io/v2/swagger.json -qi -p http://127.0.0.1:8080
Gathering API details.
⚠ POST 500 /v2/pet
⚠ PUT 500 /v2/pet
✓ GET 200 /v2/pet/findByStatus
✓ GET 200 /v2/pet/findByTags
✓ GET 200 /v2/pet/1
✓ POST 200 /v2/pet/1
⚠ POST N/A /v2/pet/1/uploadImage
✓ GET 200 /v2/store/inventory
⚠ POST N/A /v2/store/order
⚠ GET N/A /v2/store/order/1
✓ POST 200 /v2/user
⚠ POST N/A /v2/user/createWithArray
⚠ POST N/A /v2/user/createWithList
✓ GET 200 /v2/user/login
✓ GET 200 /v2/user/logout
✓ GET 200 /v2/user/bishopfox
✓ PUT 200 /v2/user/bishopfox
```
يمكنك استخدام العلامة `--replay-proxy` لإعادة تشغيل الطلبات المطابقة عبر وكيل منفصل (مثل Burp Suite). يتيح لك ذلك توجيه جميع حركة المرور عبر وكيل واحد (أو مباشرة) مع إرسال النتائج المثيرة للاهتمام فقط إلى وكيل الاعتراض الخاص بك:
```bash
$ sj automate -u https://petstore.swagger.io/v2/swagger.json -qi --replay-proxy http://127.0.0.1:8080
```
يمكنك أيضًا دمجه مع `--proxy` لتوجيه حركة مرور الفحص عبر وكيل مختلف أثناء إعادة تشغيل المطابقات إلى Burp:
```bash
$ sj automate -u https://petstore.swagger.io/v2/swagger.json -qi -p http://proxy:9090 --replay-proxy http://127.0.0.1:8080
```
يمكنك أيضًا طلب إخراج مطوّل لرؤية الاستجابة الجزئية (أو الكاملة):
```bash
$ sj automate -u https://petstore.swagger.io/v2/swagger.json -qi -p http://127.0.0.1:8080 -v
Gathering API details.
⚠ POST 500 /v2/pet
{"code":500,"type":"unknown","message":"something
⚠ PUT 500 /v2/pet
{"code":500,"type":"unknown","message":"something
✓ GET 200 /v2/pet/findByStatus
[]
✓ GET 200 /v2/pet/findByTags
[]
✓ GET 200 /v2/pet/1
{"id":1,"category":{"id":1,"name":"cat"},"name":"d
✓ POST 200 /v2/pet/1
{"code":200,"type":"unknown","message":"1"}
⚠ POST N/A /v2/pet/1/uploadImage
✓ GET 200 /v2/store/inventory
{"sold":115,"bishopfox":1,"SOLD":1,"string":224,"d
⚠ POST N/A /v2/store/order
⚠ GET N/A /v2/store/order/1
✓ POST 200 /v2/user
{"code":200,"type":"unknown","message":"1"}
⚠ POST N/A /v2/user/createWithArray
⚠ POST N/A /v2/user/createWithList
✓ GET 200 /v2/user/login
{"code":200,"type":"unknown","message":"logged in
✓ GET 200 /v2/user/logout
{"code":200,"type":"unknown","message":"ok"}
✓ GET 200 /v2/user/bishopfox
{"id":1,"username":"bishopfox","firstName":"bishop
✓ PUT 200 /v2/user/bishopfox
{"code":200,"type":"unknown","message":"1"}
```
> استخدم الأمر `prepare` لإعداد قائمة بالأوامر للاختبار اليدوي. يدعم حاليًا كلاً من `curl` و `sqlmap`. من المحتمل أن تحتاج إلى تعديلها قليلاً.
```bash
$ sj prepare -u https://petstore.swagger.io/v2/swagger.json -qi -p http://127.0.0.1:8080
$ curl -X POST "https://petstore.swagger.io/v2/pet" -H 'Content-Type: application/json' -d '{"category":{"id":1,"name":"bishopfox"},"id":1,"name":"doggie","photoUrls":"https://bishopfox.com","status":"available","tags":[{"id":1,"name":"bishopfox"}]}'
$ curl -X PUT "https://petstore.swagger.io/v2/pet" -H 'Content-Type: application/json' -d '{"category":{"id":1,"name":"bishopfox"},"id":1,"name":"doggie","photoUrls":"https://bishopfox.com","status":"available","tags":[{"id":1,"name":"bishopfox"}]}'
$ curl -X GET "https://petstore.swagger.io/v2/pet/findByStatus?status=1"
$ curl -X GET "https://petstore.swagger.io/v2/pet/findByTags?tags=1"
$ curl -X GET "https://petstore.swagger.io/v2/pet/1"
$ curl -X POST "https://petstore.swagger.io/v2/pet/1" -H 'Content-Type: application/x-www-form-urlencoded' -d 'name=bishopfox&status=bishopfox'
$ curl -X POST "https://petstore.swagger.io/v2/pet/1/uploadImage" -H 'Content-Type: application/x-www-form-urlencoded' -d 'additionalMetadata=bishopfox&file=1'
$ curl -X GET "https://petstore.swagger.io/v2/store/inventory"
$ curl -X POST "https://petstore.swagger.io/v2/store/order" -H 'Content-Type: application/json' -d '{"complete":true,"id":1,"petId":1,"quantity":1,"shipDate":"1990-01-01","status":"placed"}'
$ curl -X GET "https://petstore.swagger.io/v2/store/order/1"
$ curl -X POST "https://petstore.swagger.io/v2/user" -H 'Content-Type: application/json' -d '{"email":"[email protected]","firstName":"bishopfox","id":1,"lastName":"bishopfox","password":"bishopfox","phone":"bishopfox","userStatus":1,"username":"bishopfox"}'
$ curl -X POST "https://petstore.swagger.io/v2/user/createWithArray" -H 'Content-Type: application/json' -d '[{"email":"[email protected]","firstName":"bishopfox","id":1,"lastName":"bishopfox","password":"bishopfox","phone":"bishopfox","userStatus":1,"username":"bishopfox"}]'
$ curl -X POST "https://petstore.swagger.io/v2/user/createWithList" -H 'Content-Type: application/json' -d '[{"email":"[email protected]","firstName":"bishopfox","id":1,"lastName":"bishopfox","password":"bishopfox","phone":"bishopfox","userStatus":1,"username":"bishopfox"}]'
$ curl -X GET "https://petstore.swagger.io/v2/user/login?username=bishopfox&password=bishopfox"
$ curl -X GET "https://petstore.swagger.io/v2/user/logout"
$ curl -X GET "https://petstore.swagger.io/v2/user/bishopfox"
$ curl -X PUT "https://petstore.swagger.io/v2/user/bishopfox" -H 'Content-Type: application/json' -d '{"email":"[email protected]","firstName":"bishopfox","id":1,"lastName":"bishopfox","password":"bishopfox","phone":"bishopfox","userStatus":1,"username":"bishopfox"}'
```
### أنواع محتوى جسم الطلب المتعددة
غالبًا ما تعلن العملية عن نفس الجسم تحت عدة أنواع محتوى. بشكل افتراضي، يرسل `sj`
النوع الأكثر احتمالاً للقبول، مع تفضيل `application/json`، ثم
`application/x-www-form-urlencoded`، ثم `multipart/form-data`، ثم XML. الاختيار
حتمي، لذا تنتج التشغيلات المتكررة أوامر متطابقة.
نظرًا لأن محلل JSON ومحلل XML يمثلان سطح هجوم مختلف، فإن `--all-content-types`
يرسل كل نوع معلن بدلاً من النوع المفضل فقط:
```bash
$ sj prepare -l spec.yaml -T https://api.example.com -q --all-content-types
$ curl -X POST "https://api.example.com/multi" -H 'Content-Type: application/json' -d '{"name":"bishopfox","size":1}'
$ curl -X POST "https://api.example.com/multi" -H 'Content-Type: application/x-www-form-urlencoded' -d 'name=bishopfox&size=1'
$ curl -X POST "https://api.example.com/multi" -F 'name=bishopfox' -F 'size=1'
$ curl -X POST "https://api.example.com/multi" -H 'Content-Type: application/xml' -d '<name>bishopfox</name><size>1</size>'
```
لاحظ أن هذا يضاعف عدد الطلبات المرسلة إلى الهدف، وأن
`--replay-proxy` يستقبل كل واحد منها.
لاختبار ترميز واحد محدد، مرره مع `-H`. عندما تعلن العملية عن ذلك
النوع، يرسل `sj` الجسم المطابق تحته:
```bash
$ sj prepare -l spec.yaml -T https://api.example.com -q -H "Content-Type: application/xml"
```
عندما *لا* تعلن العملية عنه، يحذر `sj` ويرسل الجسم المفضل تحت
ترويسة الخاص بك على أي حال، وهو أمر مفيد لاختبار الفروق بين المحللات. أنواع المحتوى التي
لا يستطيع `sj` ترميز جسم لها (`application/octet-stream`، `text/plain`) يتم تخطيها بدلاً
من إرسالها كجسم فارغ تحت ترويسة مضللة.
> استخدم الأمر `endpoints` لإنشاء قائمة بنقاط النهاية الخام من ملف التعريف المقدم.
```bash
$ sj endpoints -u https://petstore.swagger.io/v2/swagger.json -qi -p http://127.0.0.1:8080
INFO[0000] Gathering endpoints.
/v2/store/inventory
/v2/store/order/{orderId}
/v2/pet
/v2/pet
/v2/store/order
/v2/user/createWithList
/v2/pet/{petId}/uploadImage
/v2/pet/findByTags
/v2/pet/{petId}
/v2/pet/{petId}
/v2/user/{username}
/v2/user/{username}
/v2/user/createWithArray
/v2/pet/findByStatus
/v2/user/login
/v2/user/logout
/v2/user
```
> استخدم الأمر `brute` لإرسال سلسلة من الطلبات في محاولة للعثور على ملف تعريف على الهدف.
```bash
$ sj brute -u https://petstore.swagger.io -qi -p http://127.0.0.1:8080 -e
INFO[0000] Sending 2173 requests. This could take a while...
Request: 343
INFO[0033] Definition file found: https://petstore.swagger.io/v2/swagger
```
> استخدم الأمر `convert` لتحويل ملف تعريف من الإصدار 2 إلى الإصدار 3.
```bash
$ sj convert -u https://petstore.swagger.io/v2/swagger.json -qi -p http://127.0.0.1:8080 -o openapi.json
INFO[0000] Gathering API details.
INFO[0000] Wrote file to /current/directory/openapi.json
```
## المساعدة
يمكن العثور على قائمة كاملة بالأوامر باستخدام العلامة `--help`:
```bash
$ sj --help
The process of reviewing and testing exposed API definition files is often tedious and requires a large investment of time for a thorough review.
sj (swaggerjacker) is a CLI tool that can be used to perform an initial check of API endpoints identified through exposed Swagger/OpenAPI definition files.
Once you determine what endpoints require authentication and which do not, you can use the "prepare" command to generate command templates for further (manual) testing.
Example usage:
Perform a quick check of endpoints which require authentication:
$ sj automate -u https://petstore.swagger.io/v2/swagger.json
Generate a list of commands to use for manual testing:
$ sj prepare -u https://petstore.swagger.io/v2/swagger.json
Generate a list of raw API routes for use with custom scripts:
$ sj endpoints -u https://petstore.swagger.io/v2/swagger.json
Perform a brute-force attack against the target to identify hidden definition files:
$ sj brute -u https://petstore.swagger.io
Convert a Swagger (v2) definition file to an OpenAPI (v3) definition file:
$ sj convert -u https://petstore.swagger.io/v2/swagger.json -o openapi.json
Usage:
sj [flags]
sj [command]
Available Commands:
automate Sends a series of automated requests to the discovered endpoints.
brute Sends a series of automated requests to discover hidden API operation definitions.
convert Converts a Swagger definition file to an OpenAPI v3 definition file.
endpoints Prints a list of endpoints from the target.
help Help about any command
prepare Prepares a set of commands for manual testing of each endpoint.
Flags:
-A, --agent string Set the User-Agent string. (default "Swagger Jacker (github.com/BishopFox/sj)")
--all-content-types Send a separate request for every request body content type an operation declares, instead of only the preferred one.
-b, --base-path string Set the API base path if not defined in the definition file (i.e. /V2/).
-f, --format string Declare the format of the definition file (json/yaml/yml/js). (default "json")
-H, --headers stringArray Add custom headers, separated by a colon ("Name: Value"). Multiple flags are accepted.
-h, --help help for sj
-i, --insecure Ignores server certificate validation.
-l, --local-file string Loads the documentation from a local file.
-o, --outfile string Output the results to a file. Only supported for the 'automate' and 'brute' commands at this time.
-p, --proxy string Proxy host and port. Example: http://127.0.0.1:8080 (default "NOPROXY")
-q, --quiet Do not prompt for user input - uses default values for all requests.
--replay-proxy string Replay matched requests using this proxy.
--randomize-user-agent Randomizes the user agent string. Default is 'false'.
-s, --safe-word stringArray Avoids 'dangerous word' check for the specified word(s). Multiple flags are accepted.
-T, --target string Manually set a target for the requests to be made if separate from the host the documentation resides on.
-t, --timeout int Set the request timeout period. (default 30)
-u, --url string Loads the documentation file from a URL
-v, --version version for sj
Use "sj [command] --help" for more information about a command.
```