(outputDirectory string, verbosity int)
| 261 | } |
| 262 | |
| 263 | func (m *LambdasModule) writeLoot(outputDirectory string, verbosity int) { |
| 264 | path := filepath.Join(outputDirectory, "loot") |
| 265 | err := os.MkdirAll(path, os.ModePerm) |
| 266 | if err != nil { |
| 267 | m.modLog.Error(err.Error()) |
| 268 | m.CommandCounter.IncrError() |
| 269 | } |
| 270 | pullFile := filepath.Join(path, "lambda-get-function-commands.txt") |
| 271 | |
| 272 | var out string |
| 273 | out = out + fmt.Sprintln("#############################################") |
| 274 | out = out + fmt.Sprintln("# The profile you will use to perform these commands is most likely not the profile you used to run CloudFox") |
| 275 | out = out + fmt.Sprintln("# Set the $profile environment variable to the profile you are going to use to inspect the buckets.") |
| 276 | out = out + fmt.Sprintln("# E.g., export profile=dev-prod.") |
| 277 | out = out + fmt.Sprintln("#############################################") |
| 278 | out = out + fmt.Sprintln("") |
| 279 | |
| 280 | for _, function := range m.Lambdas { |
| 281 | out = out + fmt.Sprintln("=============================================") |
| 282 | out = out + fmt.Sprintf("# Lambda Name: %s\n\n", function.Name) |
| 283 | out = out + "# Get function metadata including download location\n" |
| 284 | out = out + fmt.Sprintf("aws --profile $profile --region %s lambda get-function --function-name %s\n", function.Region, function.Name) |
| 285 | out = out + "# Download function code to to disk (requires jq and curl) \n" |
| 286 | out = out + fmt.Sprintf("mkdir -p ./lambdas/%s\n", function.Name) |
| 287 | out = out + fmt.Sprintf("url=`aws --profile $profile lambda get-function --region %s --function-name %s | jq .Code.Location | sed s/\\\"//g` && curl \"$url\" -o ./lambdas/%s.zip\n", function.Region, function.Name, function.Name) |
| 288 | } |
| 289 | err = os.WriteFile(pullFile, []byte(out), 0644) |
| 290 | if err != nil { |
| 291 | m.modLog.Error(err.Error()) |
| 292 | m.CommandCounter.IncrError() |
| 293 | } |
| 294 | |
| 295 | if verbosity > 2 { |
| 296 | fmt.Println() |
| 297 | fmt.Printf("[%s][%s] %s \n\n", cyan(m.output.CallingModule), cyan(m.AWSProfile), green("Beginning of loot file.")) |
| 298 | |
| 299 | fmt.Print(out) |
| 300 | fmt.Printf("[%s][%s] %s \n\n", cyan(m.output.CallingModule), cyan(m.AWSProfile), green("End of loot file.")) |
| 301 | } |
| 302 | |
| 303 | fmt.Printf("[%s][%s] Loot written to [%s]\n", cyan(m.output.CallingModule), cyan(m.AWSProfile), pullFile) |
| 304 | |
| 305 | } |
| 306 | |
| 307 | func (m *LambdasModule) getLambdasPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}, dataReceiver chan Lambda) { |
| 308 | defer func() { |
no test coverage detected