Skip to content

Catalog

TarradeMarc edited this page Jul 9, 2024 · 3 revisions

Ready-to-use decoy ideas.

Cookie tampering

Idea: the application sets a cookie to remember user's preferences. An attacker may probe the cookie value to possibly escalate privileges or to trigger an injection, while non-malicious users typically ignore cookies or just delete cookies.

  • Injection: a cookie is injected when visiting a page
  • Detection: an alert is raised if the cookie value is modified
    {
      "decoy": {
        "key": "theme",
        "separator": "=",
        "value": "light"
      },
      "inject": {
        "store": {
          "inResponse": ".*",
          "as": "cookie"
        }
      },
      "detect": {
        "seek": {
          "inRequest": ".*",
          "in": "cookie"
        },
        "alert": {
          "severity": "MEDIUM",
          "whenModified": true
        }
      }
    }
09-decoy-cookie.mp4

'Leaked' credentials

Idea: the application developers use hardcoded credentials to debug the application, and forgot to remove the credentials from the productive version. An attacker may try to login with these credentials, while non-malicious users won't typically look at the application's source code or will refrain from using the credentials.

  • Injection: an HTML comment is injected in the HTTP response body of a certain page
  • Detection: specified username/password are used as POST payload parameters of the /login page
    {
      "decoy": {
        "key": "username=debug%40myapp.com",
        "separator": "&",
        "value": "password=ghj34g5jk34%25%24%24d",
        "string": "<!-- debug with: debug@myapp.com / ghj34g5jk34%$$d -->"
      },
      "inject": {
        "store": {
          "inResponse": "/login$",
          "withVerb": "GET",
          "as": "body",
          "at": {
            "method": "line",
            "property": "1"
          }
        }
      },
      "detect": {
        "seek": {
          "inRequest": "/login$",
          "withVerb": "POST",
          "in": "payload"
        },
        "alert": {
          "severity": "MEDIUM",
          "whenComplete": true
        }
      }
    }
10-decoy-htmlComment.mp4

Analytic bot

Idea: a specific endpoint (/api) is only to be consumed by a certain bot. This bot is recognized as it sends a secret HTTP request header (x-analytics). Again, the developers forgot to remove this information from the productive version. An attacker may try to set this HTTP parameter to impersonate the bot, while non-malicious users will refrain or even not see the instructions in the first place.

  • Injection: POST requests to /api are met with an error message saying that the header is missing
  • Detection: specified HTTP request header is set prior to visiting a page
    {
      "decoy": {
        "key": "x-analytics",
        "string": "Missing header: x-analytics - denying"
      },
      "inject": {
        "store": {
          "inResponse": "^\/api(\/.*)?$",
          "withVerb": "POST",
          "as": "body",
          "at": {
            "method": "replace",
            "property": "((.|\n)*)"
          }
        }
      },
      "detect": {
        "seek": {
          "inRequest": ".*",
          "withVerb": "POST",
          "in": "header"
        },
        "alert": {
          "severity": "MEDIUM",
          "whenSeen": true
        }
      }
    },
    {
      "decoy": {
        "key": "401"
      },
      "inject": {
        "store": {
          "inResponse": "^\/api(\/.*)?$",
          "withVerb": "POST",
          "as": "status"
        }
      }
    }
11-decoy-header.mp4

Old server

Idea: different servers are deployed for different versions. The login page specifies the latest server name. When a new server is deployed, the page is updated to progressively migrate the traffic. The older version of the server, containing bugs, may still be reachable. An attacker may try to send a request to this older server, while non-malicious users won't see this server parameter or will refrain to modify it.

  • Injection: a hidden FORM field in the response body of the /login page
  • Detection: unexpected value in the postParam of the corresponding POST /login request.
  {
    "decoy": {
      "key": "server",
      "separator": "=",
      "value": "PROD02",
      "string": "<input type=\"hidden\" name=\"server\" value=\"PROD02\">\n      "
    },
    "inject": {
      "store": {
        "inResponse": "/login$",
        "withVerb": "GET",
        "as": "body",
        "at": {
          "method": "line",
          "property": "5"
        }
      }
    },
    "detect": {
      "seek": {
        "inRequest": "/login$",
        "withVerb": "POST",
        "in": "postParam"
      },
        "alert": {
          "severity": "MEDIUM",
          "whenModified": true
        }
      }
    }
12-decoy-form.mp4

Forgotten endpoint

Idea: an API is used for sending backup requests. The code is not used anymore but the endpoint is still here and may be an entry point. An attacker may try to probe this endpoint, searching for a vulnerability, while non-malicious users won't look at the source code of the server's javascript.

  • Injection: a method inside a javascript file which is never invoked, injected as a response body
  • Detection: the endpoint URL is being requested
  {
    "decoy": {
      "key": "backup-2024-sdj",
      "string": "function sendBackupRequest() {\n  const url = '/backup-2024-sdj';\n  const payload = {\n    start: 'now'\n  };\n\n  fetch(url, {\n    method: 'POST',\n    headers: {\n      'Content-Type':\n'application/json'\n    },\n    body: JSON.stringify(payload)\n  })\n  .then(response => {\n    if (!response.ok) {\n      throw new Error('Network response was not ok ' + response.statusText);\n    }\n    return response.json();\n  })\n  .then(data => {\n    console.log('Success:', data);\n  })\n  .catch(error => {\n    console.error('Error:', error);\n  });\n}"
    },
    "inject": {
      "store": {
        "inResponse": "/script.js$",
        "withVerb": "GET",
        "as": "body",
        "at": {
          "method": "line",
          "property": "0"
        }
      }
    },
    "detect": {
      "seek": {
        "inRequest": ".*",
        "withVerb": "POST",
        "in": "url"
      },
        "alert": {
          "severity": "MEDIUM",
          "whenSeen": true
      }
    }
  }
13-decoy-javascript.mp4

Forbidden url

Idea: the application has an endpoint that should not be crawled by bots. Attackers may try to visit that endpoint hoping to find interesting information, while non-malicious users won't try to read the content of the robots.txt file.

  • Injection: a full robots.txt page generated as response body, when requesting /robots.txt
  • Detection: the endpoint URL is being requested
  {
    "decoy": {
      "key": "/administrator/login",
      "string": "User-agent: *\nDisallow: /administrator/login"
    },
    "inject": {
      "store": {
        "inResponse": "/robots.txt$",
        "withVerb": "GET",
        "as": "body",
        "at": {
          "method": "replace",
          "property": "((.|\n)*)"
        }
      }
    },
    "detect": {
      "seek": {
        "inRequest": ".*",
        "withVerb": "GET",
        "in": "url"
      },
        "alert": {
          "severity": "MEDIUM",
          "whenSeen": true
      }
    }
  },
  {
    "decoy": {
      "key": "200"
    },
    "inject": {
      "store": {
        "inResponse": "/robots.txt$",
        "withVerb": "GET",
        "as": "status"
      }
    }
  },
  {
    "decoy": {
      "key": "content-type",
      "separator":"=",
      "value": "text/plain"
    },
    "inject": {
      "store": {
        "inResponse": "/robots.txt$",
        "withVerb": "GET",
        "as": "header",
        "at": {
          "method": "replace",
          "property": ".*"
        }
      }
    }
  }
14-decoy-robots.mp4

Client-side bypass

Idea: the login web form will refuse to be submitted if the username is not a URL. Attackers will try to bypass the client-side restriction, possibly hoping to discover an injection vulnerability, while non-malicious users will comply with the browser's request.

  • Injection: nothing
  • Detection: the format of the submitted username as POST payload violates the client-side rule.
  {
    "decoy": {
      "key": "username",
      "separator": "=",
      "dynamicValue": "[^\\%40\\s]+\\%40[^\\%40\\s]+\\.[^\\%40\\s]+"
    },
    "detect": {
      "seek": {
        "inRequest": "/login",
        "withVerb": "POST",
        "in": "postParam"
      },
        "alert": {
          "severity": "MEDIUM",
          "whenModified": true
        }
      }
    }
15-detection-clientSide.mp4

Hidden source code

Idea: a developer using a private github repository creates an image in an insecure way. As a consquence, the local .git folder is added to the image and can be harvested to retrieve the source code of the application.

  • Injection: nothing
  • Detection: the url '/.git' is visited.

Please note: non-malicious users won't try to find hidden source code, but certain browsers extensions used by developers can visit .git automatically (as an offensive security tool). While unlikely, this decoy may thus trigger some false positive alerts.

  {
    "decoy": {
      "key": "/.git"
    },
    "detect": {
      "seek": {
        "inRequest": ".*",
        "withVerb": "GET",
        "in": "url"
      },
        "alert": {
          "severity": "MEDIUM",
          "whenSeen": true
        }
      }
    }
16-detection-git.mp4
Clone this wiki locally