{"id":50713106,"url":"https://github.com/Permiso-io-tools/LogLicker","last_synced_at":"2026-06-26T17:00:43.717Z","repository":{"id":188949267,"uuid":"663694096","full_name":"Permiso-io-tools/LogLicker","owner":"Permiso-io-tools","description":"Tool for obfuscating and deobfuscating data. ","archived":false,"fork":false,"pushed_at":"2024-03-20T18:19:32.000Z","size":31,"stargazers_count":47,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-03-20T19:52:38.457Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Permiso-io-tools.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2023-07-07T22:27:15.000Z","updated_at":"2024-03-11T16:04:07.000Z","dependencies_parsed_at":null,"dependency_job_id":"246b99ec-8f73-4fd4-9437-c43a36cb5e1c","html_url":"https://github.com/Permiso-io-tools/LogLicker","commit_stats":null,"previous_names":["permiso-io-tools/loglicker"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Permiso-io-tools/LogLicker","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Permiso-io-tools%2FLogLicker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Permiso-io-tools%2FLogLicker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Permiso-io-tools%2FLogLicker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Permiso-io-tools%2FLogLicker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Permiso-io-tools","download_url":"https://codeload.github.com/Permiso-io-tools/LogLicker/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Permiso-io-tools%2FLogLicker/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34825611,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-26T02:00:06.560Z","response_time":106,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-09T17:00:26.117Z","updated_at":"2026-06-26T17:00:43.711Z","avatar_url":"https://github.com/Permiso-io-tools.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"![LogLicker](https://permiso.io/hubfs/LogLicker.png \"LogLicker Logo\")\n# LogLicker\n**Permiso:** https://permiso.io  \n**Read our release blog:** https://permiso.io/blog/intern-showcase-anonymizing-logs-made-easy-with-loglicker\n\nTool for obfuscating and deobfuscating data. This tool is built to be highly customizable, so while it does have in-built support for AWS CloudTrail logs, support for other data types can be added. This is because this tool searches and replaces sensitive data based on regexes pulled from an inputted file.\n\n## Required Packages\n\u003e```bash\n\u003epython3 -m pip install regex boto3 exrex\n\u003e```\n\n## Input\n\nThis tool offers a CLI (Command Line Interface). As such, here we review its use:\n\nNote the following commands examples do not specify a file path for RunLogLicker.py which will need to be included or a symlink should be registered:\n\u003e**MAC**\n\u003e```bash\n\u003eln -s /path/to/file/RunLogLicker.py RunLogLicker.py\n\u003e```\n\u003e-----\n\u003e**Windows**\n\u003e```bash\n\u003emklink RunLogLicker.py C:\\path\\to\\file\\RunLogLicker.py\n\u003e```\n\nThe tool has different subparsers for different inputs. Calling the three different subparsers looks like this:\n\u003e```PowerShell\n\u003epython3 RunLogLicker.py rawtext\n\u003epython3 RunLogLicker.py cloudtrail\n\u003epython3 RunLogLicker.py rawcloudtrail\n\u003e```\n\u003e-----\n\u003e**While this documentation goes over the available arguments for each subparser, the following commands will show them while using the tool.**\n\u003e```PowerShell\n\u003epython3 RunLogLicker.py rawtext -h\n\u003epython3 RunLogLicker.py cloudtrail -h\n\u003epython3 RunLogLicker.py rawcloudtrail -h\n\u003e```\n-----\n\u003e**For all subparsers, if no output file is specified then the output will be written to the location of the RunLogLicker folder within the \u003eoutput directory.**\n-----\n### cloudtrail - Subparser\n\nInbuilt support for the CloudTrail API to pull logs directly from CloudTrail.\n\n\u003e--awsaccesskey, --awssecretkey, --region\n\u003e- These are the arguments needed to create a CloudTrail Client. They are not required if environmental variables for configured.\n\u003e```PowerShell\n\u003epython3 RunLogLicker.py cloudtrail --awsaccesskey ________ --awssecretkey ________ --region us-west-2\n\u003e```\n\u003e-----\n\u003e.--eventid, --eventname, --readonly, --username, --resourcetype, --resourcename, --eventsource, --accesskeyid\n\u003e- These are the mutually exclusive arguments for grabbing CloudTrail logs (only one can be used at a time). Logs that do not fit the argument provided are not retrieved from CloudTrail. https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/cloudtrail/client/lookup_events.html\n\u003e```PowerShell\n\u003epython3 RunLogLicker.py cloudtrail --readonly true\n\u003e```\n\u003e-----\n\u003e--starttime, --endtime\n\u003e-  These are the non-mutually exclusive arguments for grabbing CloudTrail logs, which means as many of these can be added as wanted. An example call using these looks like:\n\u003e```PowerShell\n\u003epython3 RunLogLicker.py cloudtrail --starttime 07132023 --endtime 07152023 \n\u003e```\n### rawtext - Subparser\n\nPull from a text file.\n**For the best performance, each line should hold an entire object, instead of each object being accross multiple lines. As the tool grabs and writes line-by-line.**\n\n\u003e--inputfilepath\n\u003e- The path to the file to grab data from\n\u003e```PowerShell\n\u003epython3 RunLogLicker.py rawtext --inputfilepath input/example/file.txt\n\u003epython3 RunLogLicker.py rawtext --ifp input/example/file.txt\n\u003e```\n\u003e-----\n\u003e--deanonymize or -da (true)\n\u003e- Whether or not to deobfustcate data. (Requires input that needs de-anonymized and the manifest that says how to de-anonymize.)\n\u003e```PowerShell\n\u003epython3 RunLogLicker.py rawtext --inputfilepath input/example/file.txt -imfp output/manifest.json -da true\n\u003e```\n\n### rawtext \u0026 cloudtrail arguments\n\nThe rawtext and cloudtrail subparsers also have the following common arguments:\n\n\u003e--exrexfilepath, --regexfilepath\n\u003e- The path to the regexes and exrexes. Regexes are regular expressions used to find data, and exrexes are the regular expressions used to generate a random string. By default \u003ethese go to default/default_exrex.json and default/default_regex.json. These should be JSON files formatted as such:\n\u003e```json\n\u003e{\n\u003e    \"longTermAccessKeyID\": \"(?:AKIA)[A-Z0-9]{16}\",\n\u003e    \"shortTermAccessKeyID\": \"(?:ASIA)[A-Z0-9]{16}\",\n\u003e    \"publicKeyID\": \"(?:APKA)[A-Z0-9]{16}\",\n\u003e    \"ipv4\": \"((?\u003c![0-9])(?:(?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|\u003e[0-1]?[0-9]{1,2}))(?![0-9]))\"\n\u003e}\n\u003e```\n\u003e-----\n\u003e--inputmanifestfilepath, --outputmanifestfilepath\n\u003e- The input manifest must be provided when deanonymizing, so the program can know what values where replaced and what to put them back to. The input manifest can be provided when \u003eanonymizing which will replace values with the same value in the manifest. This allows for keeping consistant replacements accross multiple files, and for custom replacement of \u003especific values. The output manifest file path designates where the manifest of changed values is outputted to.\n\u003e```PowerShell\n\u003epython3 RunLogLicker.py cloudtrail --inputmanifestfilepath input/example/manifest.json --outputmanifestfilepath output/example/manifest.json\n\u003e```\n\u003e-----\n\u003e--limit\n\u003e- The max amount of logs to grab from the cloudtrail API, by default the value is 1000.\n\u003e```PowerShell\n\u003epython3 RunLogLicker.py cloudtrail --inputmanifestfilepath input/example/manifest.json --outputmanifestfilepath output/example/manifest.json --limit 50\n\u003e```\n\u003e-----\n\u003e--regexlist\n\u003e- To only get specific values to anonymize, you can specify here. Only the values provided will be anonymized, assuming the corresponding regexes already exist in the regex file.\n\u003e```PowerShell\n\u003epython3 RunLogLicker.py cloudtrail -ofp output/anonymizedcloudtrail.txt -imfp output/manifest.json -rl ipv4 arn\n\u003e```\n\n### rawcloudtrail\n\nThe rawcloudtrail subparser allows for direct dumping of CloudTrail logs without any modifications. The arguments are the same as the cloudtrail parser, without any of the ones overlapping arguments that exist for cloudtrail and rawtext.\n\n### rawcloudtrail, cloudtrail and rawtext arguments\n\nThe only overlapping argument for all of the above is:\n\u003e--outputfilepath\n\u003e- The path where the output file is put. If no output file path is put nothing will be written. This can be useful for just finding possible \u003esensitive information within logs, without wanting to anonymize it, as a manifest can still be created if a file path for the manifest is \u003econfigured.\n\u003e```PowerShell\n\u003epython3 RunLogLicker.py rawcloudtrail --outputfilepath output/example/rawcloudtrail.txt\n\u003epython3 RunLogLicker.py rawcloudtrail --ofp output/example/rawcloudtrail.txt\n\u003epython3 RunLogLicker.py rawcloudtrail\n\u003e```\n\n## Subparser Examples\n```PowerShell\npython3 RunLogLicker.py rawcloudtrail -es ssm.amazonaws.com -s 2021-12-01 -r us-west-2 -ofp output/rawcloudtrail.txt -l 20\npython3 RunLogLicker.py rawcloudtrail -s 2021-12-01 -e 2023-07-19 -r us-west-2 -ofp output/rawcloudtrail.txt\npython3 RunLogLicker.py rawcloudtrail -s 2021-12-01 -e 2023-07-19 -r us-west-2 -ofp output/rawcloudtrail.txt\npython3 RunLogLicker.py rawcloudtrail -s 2021-12-01 -e 2023-08-01 -r us-west-2 -ofp output/rawcloudtrail.txt -l 20000\n```\n-----\n```PowerShell\npython3 RunLogLicker.py rawtext -ifp output/rawcloudtrail.txt -ofp output/anonymizedrawtext.txt\npython3 RunLogLicker.py rawtext -ifp output/anonymizedrawtext.txt -ofp output/deanonymizedrawtext.txt -imfp output/manifest.json -da true\npython3 RunLogLicker.py rawtext -ifp output/rawcloudtrail.txt -ofp output/anonymizedrawtext.txt -rl ipv4 arn shortTermAccessKeyID\npython3 RunLogLicker.py rawtext -ifp output/anonymizedrawtext.txt -ofp output/deanonymizedrawtext.txt -imfp output/manifest.json -da true\n```\n-----\n```PowerShell\npython3 RunLogLicker.py cloudtrail -ofp output/anonymizedcloudtrail.txt -imfp output/manifest.json -es ssm.amazonaws.com -s 2021-12-01 -l 20\npython3 RunLogLicker.py cloudtrail -ofp output/anonymizedcloudtrail.txt -imfp output/manifest.json -s 2021-12-01 -e 2023-07-19\npython3 RunLogLicker.py cloudtrail -ofp output/anonymizedcloudtrail.txt -imfp output/manifest.json -s 2021-12-01 -e 2023-07-19 -rl ipv4 arn\npython3 RunLogLicker.py cloudtrail -ofp output/anonymizedcloudtrail.txt -imfp output/manifest.json -s 2021-12-01 -e 2023-08-01 -l 20000\n```\n-----\n## Example Call Chain\n#### The following example was chosen to take a raw cloudtrail log, anonymize it and get the manifest, use both to reverse back to de-anonymized version.\n```PowerShell\n----------\nGet non-anonymized raw cloudtrail data.\n----------\n\npython3 RunLogLicker.py rawcloudtrail\n\n  88      dP.Yb   dPEEb8 88     88  dPTTb8 77  dP 867888 88\u003c\u003eYb\n  AA     EE   Yb dP      88     88 dP      88edP  88__   88__dP\n  88  DD Yb   dP Yb  X88 88     88 Yb      99mYb  88\"\"   88VYb\n  88ooBB  Yb.dP   YboodP 88ood8 88  YbZZdP 88  Yb 882283 88  Yb\n\n[*] Parsing input arguments.\n[*] Loading regex files and any specified manifest.\n[*] Processing.\n[*] Fetching data.\n[*] Completed. - 5bf42d01fbe2bb83df9ed5b8597fc48e\n\n----------\nAnonymize the raw cloudtrail data.\n----------\n\npython3 RunLogLicker.py rawtext -ifp /Users/UserA/Repos/LogLicker/output/rawCTOutput-5bf42d01fbe2bb83df9ed5b8597fc48e.json\n\n  88      dP.Yb   dPEEb8 88     88  dPTTb8 77  dP 867888 88\u003c\u003eYb\n  AA     EE   Yb dP      88     88 dP      88edP  88__   88__dP\n  88  DD Yb   dP Yb  X88 88     88 Yb      99mYb  88\"\"   88VYb\n  88ooBB  Yb.dP   YboodP 88ood8 88  YbZZdP 88  Yb 882283 88  Yb\n\n[*] Parsing input arguments.\n[*] Loading regex files and any specified manifest.\n[*] Processing.\n[*] Anonymizing - Writing to output \u0026 manifest.\n[*] Completed. - f146979ecec0448282f24803c93bafdd\n\n----------\nUse anonymized data file and manifest to search the anonymized data and replace with orginals.\n----------\n\npython3 RunLogLicker.py rawtext -ifp /Users/UserA/Repos/LogLicker/output/anonymizedRawtext-f146979ecec0448282f24803c93bafdd.json -imfp /Users/UserA/Repos/LogLicker/output/manifest-f146979ecec0448282f24803c93bafdd.json -da true\n\n  88      dP.Yb   dPEEb8 88     88  dPTTb8 77  dP 867888 88\u003c\u003eYb\n  AA     EE   Yb dP      88     88 dP      88edP  88__   88__dP\n  88  DD Yb   dP Yb  X88 88     88 Yb      99mYb  88\"\"   88VYb\n  88ooBB  Yb.dP   YboodP 88ood8 88  YbZZdP 88  Yb 882283 88  Yb\n\n[*] Parsing input arguments.\n[*] Loading regex files and any specified manifest.\n[*] Processing.\n[*] De-anonymizing - Writing to output.\n[*] Completed. - f146979ecec0448282f24803c93bafdd\n```\n-----\n## Output\n\nThe two outputs of the tool are a text file containing the transformed data, as well as the manifest of those transformations. The orginal file or deanonymized file can also be obtained as output. The manifest is formatted as such:\n\nNote the below manifest is the result of double anonymization through the tool.\n\n```JSON\n{\n    \"longTermAccessKeyID\": {},\n    \"shortTermAccessKeyID\": {\n        \"ASIA44BFS3DB9AZSLVKN\": \"ASIARRA7214EQQRGSOR8\",\n        \"ASIA58XS6QR4LQUU6MAT\": \"ASIAQNG9PSO77X5XE6XJ\",\n        \"ASIAKESN7KC3TQNRUUD7\": \"ASIALG1VFSHW4T3QIOI9\",\n        \"ASIA7IMFF7TTJ6GGK5RK\": \"ASIA69KD9OFYVKE9WNCO\",\n        \"ASIAEM0Q7HMERFGZHVX1\": \"ASIA20VIIH15A2HZ3YQK\",\n        \"ASIAWPC2Z9LK2AIEOKSU\": \"ASIALR275EU6OCEOD4DZ\",\n        \"ASIALCJDZ7KLQZ280X44\": \"ASIAH30ULGUKKLXWNXMY\",\n        \"ASIA3HOROPQ12T83EXL2\": \"ASIANDXL666WMBUHKWSK\",\n        \"ASIAJLP0YUGS7Y9J1L5W\": \"ASIAFKUY82ZLMDQWN9JW\",\n    },\n    \"publicKeyID\": {},\n    \"stsServiceBearerTokenID\": {},\n    \"contextSpecificCredentialID\": {},\n    \"groupID\": {},\n    \"ec2InstanceProfileID\": {},\n    \"iamUserID\": {},\n    \"managedPolicyID\": {},\n    \"roleID\": {\n        \"AROAX8FPY6SLINGD5TRIY\": \"AROAFMMNPSOMSUB3U0PS7\",\n        \"AROAHF19VBSC3PEQ5S7AR\": \"AROAXTDOSUSGP0DYHQIZP\",\n        \"AROA72BM0TPC9EOJDGRSS\": \"AROAOKOZ9RAV91QYNLKSJ\",\n        \"AROAESH5Z6ZNASDBVB35Z\": \"AROAXYIJM34DYM4LCCZ5I\"\n    },\n    \"certificateID\": {},\n    \"accountID\": {\n        \"037004843194\": \"335218083019\"\n    },\n    \"username\": {\n        \"random-namex0cmjcGZFzcB\": \"random-nameKr9MbbOGlggB\",\n        \"random-generated-nameKEV833qWlntN\": \"random-nameWdE6hgKCByqw\",\n        \"random-generatedNlTKfrplXYd9\": \"random-names4PWayd1paxS\",\n        \"random-namerkIM3rcQqCrG\": \"random-generated5714THlzRgiz\"\n    },\n    \"arn\": {\n        \"assumed-role/random-namex0cmjcGZFzcB/permisoIdentity\": \"random-generated-name25VkjCitbTAl\",\n        \"role/random-namex0cmjcGZFzcB\": \"random-userP05GjxuUtlqG\",\n        \"random-userqfqIsrqkbeXE\": \"random-userqEre8a1P0d2v\",\n        \"random-nameBfffGInqmkoC\": \"random-userJNa22tvcOPEF\",\n        \"assumed-role/random-generated-nameKEV833qWlntN/LascoEntropy-3308480586824857098\": \"random-user0OFxJmCUrcY2\",\n        \"random-userBhz6XEm4Iq5d\": \"random-nameOHzall3NlDrP\",\n        \"random-namer9M8cK8JAZnq\": \"random-generated-userrI5pGvVoSsrk\",\n        \"assumed-role/random-generated-nameKEV833qWlntN/MandoService5411494363614758860\": \"random-userAcg538doYyur\",\n    },\n    \"instanceID\": {},\n    \"ipv4\": {\n        \"210.200.250.217\": \"17.76.253.255\",\n        \"251.255.239.248\": \"4.210.254.11\"\n    },\n    \"region\": {\n        \"eu-northwest-3\": \"ap-isob-south-2r\"\n    },\n    \"email\": {},\n    \"specifiedStrings\": {}\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FPermiso-io-tools%2FLogLicker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FPermiso-io-tools%2FLogLicker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FPermiso-io-tools%2FLogLicker/lists"}