linux - Bash 中的并行迭代 IP 地址

标签 linux bash curl gnu-parallel

我正在处理一个大型私有(private)/8 网络,需要枚举所有正在监听端口 443 并在其 HTTP header 响应中声明特定版本的网络服务器。

首先,我想通过连接扫描运行 nmap 并通过输出文件 grep 自己,但结果在 nmap 声明端口的地方抛出了很多误报在它实际“打开”时被“过滤”(使用连接扫描:nmap -sT -sV -Pn -n -oA foo 10.0.0.0/8 -p 443)。

所以现在我想用 bash 和 curl 编写一些脚本 - 伪代码如下:

for each IP in 10.0.0.0/8  
do:  
    curl --head https://{IP}:443 | grep -iE "(Server\:\ Target)" > {IP}_info.txt;  
done  

因为我不太熟悉 bash,所以我不确定如何正确编写脚本 - 我必须:

  • 遍历所有IP
  • 确保只有X个威胁并行运行
  • 理想情况下将输出剪切为只在一个文件中记下匹配主机的 IP
  • 最好确保只记下匹配的服务器版本

非常感谢任何建议或指向方向。

最佳答案

小规模 - 迭代

对于较小的IP地址跨度,可能建议像这样迭代:

for ip in 192.168.1.{1..10}; do ...

如本 similar question 所述.


大规模 - 并行!

鉴于您的问题涉及巨大 IP 地址跨度,您可能应该考虑采用不同的方法。

请求使用gnu parallel .

使用 gnu parallel 在 bash 中并行迭代大范围的 IP 地址需要将逻辑拆分为多个文件(供并行命令使用)。

ip2int

#!/bin/bash

set -e

function ip_to_int()
{
  local IP="$1"
  local A=$(echo $IP | cut -d. -f1)
  local B=$(echo $IP | cut -d. -f2)
  local C=$(echo $IP | cut -d. -f3)
  local D=$(echo $IP | cut -d. -f4)
  local INT

  INT=$(expr 256 "*" 256 "*" 256 "*" $A)
  INT=$(expr 256 "*" 256 "*" $B + $INT)
  INT=$(expr 256 "*" $C + $INT)
  INT=$(expr $D + $INT)

  echo $INT
}

function int_to_ip()
{
  local INT="$1"

  local D=$(expr $INT % 256)
  local C=$(expr '(' $INT - $D ')' / 256 % 256)
  local B=$(expr '(' $INT - $C - $D ')' / 65536 % 256)
  local A=$(expr '(' $INT - $B - $C - $D ')' / 16777216 % 256)

  echo "$A.$B.$C.$D"
}



扫描IP

#!/bin/bash

set -e

source ip2int

if [[ $# -ne 1 ]]; then
    echo "Usage: $(basename "$0") ip_address_number"
    exit 1
fi

CONNECT_TIMEOUT=2 # in seconds
IP_ADDRESS="$(int_to_ip ${1})"

set +e
data=$(curl --head -vs -m ${CONNECT_TIMEOUT} https://${IP_ADDRESS}:443 2>&1)
exit_code="$?"
data=$(echo -e "${data}" | grep "Server: ")
     # wasn't sure what are you looking for in your servers
set -e

if [[ ${exit_code} -eq 0 ]]; then
    if [[ -n "${data}" ]]; then
        echo "${IP_ADDRESS} - ${data}"
    else
        echo "${IP_ADDRESS} - Got empty data for server!"
    fi
else
    echo "${IP_ADDRESS} - no server."
fi



扫描范围

#!/bin/bash

set -e

source ip2int

START_ADDRESS="10.0.0.0"
NUM_OF_ADDRESSES="16777216" # 256 * 256 * 256

start_address_num=$(ip_to_int ${START_ADDRESS})
end_address_num=$(( start_address_num + NUM_OF_ADDRESSES ))

seq ${start_address_num} ${end_address_num} | parallel -P0 ./scan_ip

# This parallel call does the same as this:
#
# for ip_num in $(seq ${start_address_num} ${end_address_num}); do
#     ./scan_ip ${ip_num}
# done
#
# only a LOT faster!


迭代方法的改进:

The run time of the naive for loop (which is estimated to take 200 days for 256*256*256 addresses) was improved to under a day according to @skrskrskr.

关于linux - Bash 中的并行迭代 IP 地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25399966/

相关文章:

c++ - 使用 bash 脚本使用不同的参数(例如并行)同时运行一个命令 n 次

c++ - 如何优化 curl 库的大小?

linux - 使用 curl 浏览 Web 链接的所有页面

php - 如何解决 Laravel 安装上 MAC OS 上的 curl 证书问题?

linux - crontab 权限被拒绝错误

linux - 将 'srm' 设置为默认命令,而不是 linux 中的 'rm'

debugging - bash 脚本 : catching errors from a block of statements

bash - 如果找到则使用 awk 替换特定列值

linux - 如何在 Linux 中获取进程/守护进程/程序状态更改通知

linux - 内核更新导致键盘布局改变无法解密luks加密