{"id":20176835,"url":"https://github.com/thisisnotgcsar/f3s","last_synced_at":"2026-06-29T11:31:48.465Z","repository":{"id":248269090,"uuid":"770555457","full_name":"thisisnotgcsar/f3s","owner":"thisisnotgcsar","description":"Static analysis tool for format string vulnerability detection","archived":false,"fork":false,"pushed_at":"2024-07-15T21:02:44.000Z","size":1049,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-03T05:25:27.028Z","etag":null,"topics":["angr","format-string","reaching-definition-analysis","static-analysis","taint-analysis"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thisisnotgcsar.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"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,"publiccode":null,"codemeta":null}},"created_at":"2024-03-11T18:49:45.000Z","updated_at":"2024-07-15T21:02:47.000Z","dependencies_parsed_at":"2024-11-14T03:16:16.417Z","dependency_job_id":null,"html_url":"https://github.com/thisisnotgcsar/f3s","commit_stats":null,"previous_names":["thisisnotgcsar/f3s"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/thisisnotgcsar/f3s","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thisisnotgcsar%2Ff3s","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thisisnotgcsar%2Ff3s/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thisisnotgcsar%2Ff3s/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thisisnotgcsar%2Ff3s/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thisisnotgcsar","download_url":"https://codeload.github.com/thisisnotgcsar/f3s/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thisisnotgcsar%2Ff3s/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34925718,"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-29T02:00:05.398Z","response_time":58,"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":["angr","format-string","reaching-definition-analysis","static-analysis","taint-analysis"],"created_at":"2024-11-14T02:12:00.668Z","updated_at":"2026-06-29T11:31:48.447Z","avatar_url":"https://github.com/thisisnotgcsar.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"```\n    _________     \n   / __/__  /_____\n  / /_  /_ \u003c/ ___/\n / __/___/ (__  ) \n/_/  /____/____/  \n```\n\n# f3s \u003c!-- omit in toc --\u003e\n\u003e Format String Static Scanner is a static analysis tool for format string vulnerabilities in binaries.\n\n- [1. About](#1-about)\n  - [1.1. What does f3s do?](#11-what-does-f3s-do)\n  - [1.2. Example usage](#12-example-usage)\n  - [1.3. What binary architectures are supported?](#13-what-binary-architectures-are-supported)\n  - [1.4. What function sinks f3s looks for?](#14-what-function-sinks-f3s-looks-for)\n  - [1.5. What is a static taint analysis and how does it work?](#15-what-is-a-static-taint-analysis-and-how-does-it-work)\n  - [1.6. What static analyses and static binary techniques f3s makes use of?](#16-what-static-analyses-and-static-binary-techniques-f3s-makes-use-of)\n  - [1.7. What is a format string vulnerability?](#17-what-is-a-format-string-vulnerability)\n- [2. Dependencies and installation](#2-dependencies-and-installation)\n- [3. Tests](#3-tests)\n- [4. Roadmap](#4-roadmap)\n- [5. Contributing](#5-contributing)\n- [6. Acknowledgments](#6-acknowledgments)\n- [7. Meta](#7-meta)\n\n\n# 1. About\n## 1.1. What does f3s do?\nf3s makes use of a combination of static analyses directly on raw binaries to spot format string vulnerabilities. \n\nA function (called sink) is flagged if the corresponding format parameter is found to be coming from user input. \n\nFor every flag it does also display a callstack trace of the path that brought from the starting top function to the vulnerability found. \n\nf3s works on different types of architectures and stripped binaries.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://i.ibb.co/5TRZCS5/meme.png\" alt=\"Your Image Alt Text\" width=500\u003e\n\u003c/p\u003e\n\n## 1.2. Example usage\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://i.ibb.co/ZzvvBsD/PHOTO-2024-07-11-20-17-42.jpg\" alt=\"Your Image Alt Text\" width=500\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n  \u003ci\u003eUse `-h` option to discover all other arguments.\u003c/i\u003e\n\u003c/p\u003e\n\n\n## 1.3. What binary architectures are supported?\nCurrently f3s has been tested and works over these architectures:\n - AMD64\n - ARM32\n - ARM64\n\n## 1.4. What function sinks f3s looks for?\nYou can find and extend the checked functions with their respective parameters at `./src/sinks/fs_sinks.py`. \nHere is the list of the currently ones present in the file\n - printf\n - fprintf\n - sprintf\n - dprintf\n - snprintf \n - vprintf\n - vfprintf \n - vdprintf \n - vsprintf \n - vsnprintf\n - syslog\n\n## 1.5. What is a static taint analysis and how does it work?\n*Static* means it does not make use of running the binary to build knowledge out of it but rather just look at the machine code. There are few important concepts you should know about taint analysis:\n - Taint: a taint is a flag that is logically associated with a particular datum. Tainted sources are usually user input arguments to a binary.\n - Elaboration of tainted data: everything that touches taint gets tainted. So every output of every function that takes in tainted data will be tainted. This is tipically for keeping track of where the user input has flowed.\n - Sink: a sink is a parameter of a possible vulnerable function. Usually function+parameter matches are pre-known and checked during the analysis\n - Sink + Taint: when we find a sink that takes in a tainted value we know that our possible malicious data reached a possible vulnerable function and we trigger a report.\n\n## 1.6. What static analyses and static binary techniques f3s makes use of?\n - VEX intermediate representation included in angr to lift-up the binaries and operate with architecture agnostic code.\n - Taint analysis for tainting input and reporting of sinks.\n - Calling Convetion Analysis is made to asses the architecture of the binary and its calling convention.\n - A Control Flow Graph Analysis is carried out to asses the presence of sinks and derive a set of callstack traces to it.\n - A modified recursive Reaching Definition Analysis is laid out for every trace starting from the first top function and going forward towards the sink.\n - A that point the Calling Convention, tainting of input and vulnerable sinks parameters are combined to asses if they will contain a tainted value.\n\n## 1.7. What is a format string vulnerability?\n```\nprintf(\"wow!\")             //wow!!\nprintf(\"%s\", \"wow!\")       //wow!\nprintf(\"%s %x\", \"wow!\")    //wow! 0x4567B4AC    \u003c-- stack content, information leakage!\nprintf(\"%s %2$x\", \"wow!\")  //wow! 0x21776F77    \u003c-- \"wow!\" string in stack after a offset of 2\nprintf(\"%s %2$n\", \"wow!\")  //segmentation fault \u003c-- selective memory corruption\n```\nWhen the format string \"%x %x\" is parsed the function expects two parameters, depending on the calling convention, in the stack. When these parameters are not supplied by the caller what was previously in the stack gets read. A special formatter `%n` could be used to write. If the user has control over the format string (e.g.: its supplied directly from input) it could craft it in such a wat to selectively leak and write arbitrarly information into the stack. This is a [wikipedia article](https://en.wikipedia.org/wiki/Uncontrolled_format_string) talking about format string vulnerability.\n\n# 2. Dependencies and installation\nIn the file `./requirements.txt` you can find a list of dependencies f3s relies on. You can install through pip with the command: `pip install -r requirements.txt`.\n\n# 3. Tests\nUnder `./tests` you can find a collection of ad-hoc made source codes to test and demonstrate the capabilities of f3s. To run all the tests do `pytest run_tests.py`.\n\u003e ⚠️ NOTE you should have gcc and both a ARM64 and ARM32 cross compiler installed in your systems to run the tests.\n\n# 4. Roadmap\n- [X] Create f3s first version.\n- [ ] Create a Docker image containing the toolbox and all the dependent software already setup\n- [ ] Extend f3s also for command injection vulnerabilities\n\nSee the [open issues](https://github.com/thisisnotgcsar/f3s/issues) for a full list of proposed features (and known issues).\n\n# 5. Contributing\nContributions are more than welcome! Here's a [short video tutorial](https://www.youtube.com/watch?v=8lGpZkjnkt4) on how to open a pull request.\n\n# 6. Acknowledgments\n - [operation-mango](https://github.com/sefcom/operation-mango-public/tree/master) in particular for the argument_resolver module\n - [pamplemousse](https://blog.xaviermaso.com/) in particular for its [lecture video](https://youtu.be/4SMRnpuqN6E?si=a8w28haScE-jnfZN) and [blog post](https://blog.xaviermaso.com/2021/02/25/Handle-function-calls-during-static-analysis-with-angr.html)\n - [angr](https://github.com/angr/angr)\n\n# 7. Meta\ngcsar\n\n \u003cp xmlns:cc=\"http://creativecommons.org/ns#\" xmlns:dct=\"http://purl.org/dc/terms/\"\u003e\u003ca property=\"dct:title\" rel=\"cc:attributionURL\" href=\"https://github.com/thisisnotgcsar/f3s\"\u003ef3s\u003c/a\u003e by \u003ca rel=\"cc:attributionURL dct:creator\" property=\"cc:attributionName\" href=\"https://github.com/thisisnotgcsar\"\u003egcsar\u003c/a\u003e is licensed under \u003ca href=\"https://creativecommons.org/licenses/by-nc-sa/4.0/?ref=chooser-v1\" target=\"_blank\" rel=\"license noopener noreferrer\" style=\"display:inline-block;\"\u003eCC BY-NC-SA 4.0\u003cimg style=\"height:22px!important;margin-left:3px;vertical-align:text-bottom;\" src=\"https://mirrors.creativecommons.org/presskit/icons/cc.svg?ref=chooser-v1\" alt=\"\"\u003e\u003cimg style=\"height:22px!important;margin-left:3px;vertical-align:text-bottom;\" src=\"https://mirrors.creativecommons.org/presskit/icons/by.svg?ref=chooser-v1\" alt=\"\"\u003e\u003cimg style=\"height:22px!important;margin-left:3px;vertical-align:text-bottom;\" src=\"https://mirrors.creativecommons.org/presskit/icons/nc.svg?ref=chooser-v1\" alt=\"\"\u003e\u003cimg style=\"height:22px!important;margin-left:3px;vertical-align:text-bottom;\" src=\"https://mirrors.creativecommons.org/presskit/icons/sa.svg?ref=chooser-v1\" alt=\"\"\u003e\u003c/a\u003e\u003c/p\u003e\n\nhttps://github.com/thisisnotgcsar\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthisisnotgcsar%2Ff3s","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthisisnotgcsar%2Ff3s","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthisisnotgcsar%2Ff3s/lists"}