Tuesday, July 24, 2018

Enumerating Lambda functions for Pentesting

Lambda functions can be directly pentested as discussed in the last post. We would like to take it to the next level by illustrating the methodology to automate  pentesting. It is interesting to leverage scripting to automate reviewing Lambda functions from security standpoint. We can use SDK and libraries available in various languages. In this post, we are using python with boto3. More detail and documentation can be found at (https://boto3.readthedocs.io/en/latest/reference/services/lambda.html).

Let’s use a simple sample and run against our target deployment. Before running these scripts, one needs to setup AWS configuration as discussed in the last post. We can run script and use “list_functions” to fetch all functions deployed on the target environment. Here is the list of functions, which are fetched from deployment.

tools $python3 listfunction.py
(+) Lambda functions ...

Here is the code snippet for the function used.

def getFunctions():
    raw_functions = client.list_functions()
    all_functions = raw_functions["Functions"]
    list_of_functions = []
    for i in all_functions:
    return list_of_functions

This can be entry point for pentesting. You can uncomment the line where we are using json.dumps. It will give you entire stream for evaluation. Now, we can take each function and start enumerating as shown below. We can start evaluating important parameters and its impact on security.

tools $python3 getFunctionInfo.py login
(+) Fetching Lambda function login...
       (+) Platform: nodejs6.10
       (+) Permission: arn:aws:iam::313588302550:role/service-role/access
       (+) Code-Location: https://awslambda-us-east-2-tasks.s3.us-east-2.amazonaws.com/snapshots/313588302550/login-a1488a4f-………69c59232e73703

In above case, we can fetch important information like platform, permission and code-location to fetch source. We can use “get_function” to fetch detail about function. Here is the code snippet -

target_function = sys.argv[1]
print("(+) Fetching Lambda function "+target_function+"...")
myfunc = client.get_function(FunctionName=target_function)
temp = myfunc["Configuration"]
print ("       (+) Platform: "+temp["Runtime"])
print ("       (+) Permission: "+temp["Role"])
temp_code = myfunc["Code"]
print ("       (+) Code-Location: "+temp_code["Location"]+"\n")

In case, if you are interested in seeing the entire object, just use json.dump() and print the object as line commented in both of the above cases.

We can enumerate other mapping information as well, here is the way we can leverage “list_event_source_mappings”.

tools $python3 listmap.py
[{'UUID': '682c8cb8-cb32-4cdc-b059-8f655f71fe07', 'BatchSize': 100, 'EventSourceArn': 'arn:aws:dynamodb:us-east-1:223983707454:table/targetlocations/stream/2018-05-30T09:41:22.995', 'FunctionArn': 'arn:aws:lambda:us-east-1:223983707454:function: targetlocations', 'LastModified': datetime.datetime(2018, 7, 4, 8, 10, tzinfo=tzlocal()), 'LastProcessingResult': 'OK', 'State': 'Enabled', 'StateTransitionReason': 'User action'}]

Here is the code for the same.

myfunc = client.list_event_source_mappings(FunctionName='targetlocations')
temp = myfunc["EventSourceMappings"]

It seems function is using “dynamodb” from ARN.

In next posts, we will go over  invoke and tracing the functions.  

Article by Amish Shah & Shreeraj Shah