Forked from cktricky/gist:8f4e9912f757d1ccdcd00ad8e8630620
Created
January 8, 2018 09:21
-
-
Save junaid18183/17c5b94e38a3072722440051074c9b5d to your computer and use it in GitHub Desktop.
Lambda Function to Alert (Slack) of Unauthorized IAM Attempt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var AWS = require('aws-sdk'); | |
var url = require('url'); | |
var https = require('https'); | |
var hookUrl, kmsEncyptedHookUrl, slackChannel; | |
kmsEncyptedHookUrl = 'abcd1234'; // Enter the base-64 encoded, encrypted key (CiphertextBlob) | |
slackChannel = 'example_channel'; // Enter the Slack channel to send a message to | |
var postMessage = function(message, callback) { | |
var body = JSON.stringify(message); | |
var options = url.parse(hookUrl); | |
options.method = 'POST'; | |
options.headers = { | |
'Content-Type': 'application/json', | |
'Content-Length': Buffer.byteLength(body), | |
}; | |
var postReq = https.request(options, function(res) { | |
var chunks = []; | |
res.setEncoding('utf8'); | |
res.on('data', function(chunk) { | |
return chunks.push(chunk); | |
}); | |
res.on('end', function() { | |
var body = chunks.join(''); | |
if (callback) { | |
callback({ | |
body: body, | |
statusCode: res.statusCode, | |
statusMessage: res.statusMessage | |
}); | |
} | |
}); | |
return res; | |
}); | |
postReq.write(body); | |
postReq.end(); | |
}; | |
var processEvent = function(event, context) { | |
var slackMessage = { | |
channel: slackChannel, | |
text: '```' + event.detail.errorMessage + '\n' + 'Event ID: ' + event.detail.eventID + '\n' + 'AWS Account: <Enter Your AWS Account Nameg\n' + "Source IP: " + event.detail.sourceIPAddress + "\nUsername: " + event.detail.userIdentity.userName + "```", | |
}; | |
postMessage(slackMessage, function(response) { | |
if (response.statusCode < 400) { | |
console.info('Message posted successfully'); | |
context.succeed(); | |
} else if (response.statusCode < 500) { | |
console.error("Error posting message to Slack API: " + response.statusCode + " - " + response.statusMessage); | |
context.succeed(); // Don't retry because the error is due to a problem with the request | |
} else { | |
// Let Lambda retry | |
context.fail("Server error when processing message: " + response.statusCode + " - " + response.statusMessage); | |
} | |
}); | |
}; | |
exports.handler = function(event, context) { | |
// Print the incoming Amazon CloudWatch Events event. | |
console.log('Received event:', JSON.stringify(event, null, 2)); | |
console.log('Event code:', JSON.stringify(event.detail.errorCode, null, 2)); | |
// If the event is not because of unauthorized activity, do nothing. | |
if ((event.detail.errorCode != 'AccessDenied') && (event.detail.errorCode != 'Client.UnauthorizedOperation' )) { | |
console.log('No unauthorized activity'); | |
context.done(); | |
} else { | |
console.log('Unauthorized activity'); | |
// Get the user name from the event. | |
var userName = event.detail.userIdentity.userName; | |
if (hookUrl) { | |
// Container reuse, simply process the event with the key in memory | |
processEvent(event, context); | |
} else if (kmsEncyptedHookUrl && kmsEncyptedHookUrl !== '') { | |
var encryptedBuf = new Buffer(kmsEncyptedHookUrl, 'base64'); | |
var cipherText = { CiphertextBlob: encryptedBuf }; | |
var kms = new AWS.KMS(); | |
kms.decrypt(cipherText, function(err, data) { | |
if (err) { | |
console.log("Decrypt error: " + err); | |
context.fail(err); | |
} else { | |
hookUrl = "https://" + data.Plaintext.toString('ascii'); | |
processEvent(event, context); | |
} | |
}); | |
} else { | |
context.fail(event); | |
context.fail('Hook URL has not been set.'); | |
} | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment