关注 泷羽Sec和泷羽Sec-静安公众号,这里会定期更新与 OSCP、渗透测试等相关的最新文章,帮助你理解网络安全领域的最新动态。后台回复“OSCP配套工具”获取本文的工具
Bash脚本基础
新建一个hello-world.sh文件,写入以下内容:
1#!/bin/bash
2#Hello world Bash Script
3echo "hello world!"
然后给脚本添加执行权限后运行
1chmod +x hello-world.sh
2./hello-world.sh

变量
1s1=hello
2s2=world
3s3="I am Hacker"
4echo $s2 $s2 $s3

参数里面套命令,推荐用$()的用法,` 是过时的用法。
1user1=$(whoami) && user2=`whoami`
2echo $user1 $user2

参数
1$0 脚本文件名自己
2$1-$9 bash脚本的前九个参数
3$# 传递给bash脚本的参数数量
4$@ 传递给bash 脚本的所有参数
5$? 最近运行的程序的退出状态
6$USER 运行脚本的用户的用户名
7$HOSTNAME 计算机的主机名
8$RANDOM 生成一个随机数
9$LINENO 脚本中的当前行号
新建一个脚本写入如下内容。
1#!/bin/bash
2echo "The first two arguments are $1 and $2"

1#!/bin/bash
2# 文件名: demo_script.sh
3# 功能: 演示常用 Bash 参数的用法
4
5# 1. 打印脚本名称
6echo "脚本名称: $0"
7
8# 2. 打印前三个参数(若未传递参数则显示空)
9echo "第一个参数: ${1:-未提供}"
10echo "第二个参数: ${2:-未提供}"
11echo "第三个参数: ${3:-未提供}"
12
13# 3. 打印总参数个数
14echo "参数总数: $#"
15
16# 4. 打印所有参数(带循环)
17echo "所有参数:"
18count=1
19for arg in "$@"; do
20echo " 参数$count: $arg"
21((count++))
22done
23
24# 5. 测试上一个命令的退出状态
25echo "生成随机数(测试退出状态):"
26echo "随机数: $RANDOM"
27echo "生成随机数的退出状态: $? (0表示成功)"
28
29# 6. 故意执行一个失败的命令
30echo "执行一个失败的命令:"
31ls /non_existent_file
32echo "失败命令的退出状态: $? (非0表示失败)"
33
34# 7. 用户和主机信息
35echo "当前用户: $USER"
36echo "主机名: $HOSTNAME"
37
38# 8. 显示脚本当前行号(动态变化)
39echo "当前行号(执行前): $LINENO"
40echo "当前行号(执行后): $LINENO"
41
42# 9. 结束提示
43echo "脚本结束于行号: $LINENO"

Bash 特殊变量
| 变量名 | 作用 | 示例代码 | 输出示例(假设场景) |
|---|---|---|---|
$0 | 当前脚本文件名 | echo "脚本名: $0" | 脚本名: ./test.sh |
$1-$9 | 脚本的第1到第9个参数 | echo "参数1: $1" | 若执行 ./test.sh hi → 参数1: hi |
$# | 传递给脚本的参数个数 | echo "参数总数: $#" | 若执行 ./test.sh a b → 参数总数: 2 |
$@ | 所有参数,每个参数独立(推荐使用) | for arg in "$@"; do echo "$arg"; done | 循环打印每个参数 |
$* | 所有参数,合并为一个字符串 | echo "所有参数: $*" | 所有参数: a b c |
$? | 上一个命令的退出状态(0为成功) | ls /tmp; echo "状态: $?" | 状态: 0(若目录存在) |
$$ | 当前 Shell 进程的 PID | echo "PID: $$" | PID: 12345 |
$! | 最后一个后台进程的 PID | sleep 10 &; echo "后台PID: $!" | 后台PID: 6789 |
$_ | 上一个命令的最后一个参数 | ls /var; echo "$_" | /var(假设 ls 命令的参数是 /var) |
$RANDOM | 生成一个 0-32767 的随机数 | echo "随机数: $RANDOM" | 随机数: 18492 |
$LINENO | 当前脚本中的行号 | echo "当前行: $LINENO" | 当前行: 15 |
$FUNCNAME | 当前函数名(数组,${FUNCNAME[0]}为当前函数) | function test_fn { echo "函数名: ${FUNCNAME[0]}"; }; test_fn | 函数名: test_fn |
$SECONDS | 脚本已运行的秒数 | echo "运行时间: $SECONDS秒" | 运行时间: 5秒 |
$PWD | 当前工作目录路径 | echo "当前目录: $PWD" | 当前目录: /home/user |
$OLDPWD | 上一个工作目录路径(cd -切换时会更新) | echo "上一个目录: $OLDPWD" | 上一个目录: /tmp |
$IFS | 输入字段分隔符(默认是空格、制表符、换行) | IFS=:; echo "拆分: $*" | 若参数为 a:b:c → 拆分: a b c |
$BASH_VERSION | Bash 版本信息 | echo "Bash版本: $BASH_VERSION" | Bash版本: 5.1.16(1)-release |
$PPID | 父进程的 PID | echo "父进程PID: $PPID" | 父进程PID: 1234 |
$BASH_SOURCE | 当前脚本的路径(数组,${BASH_SOURCE[0]}为当前脚本) | echo "脚本路径: ${BASH_SOURCE[0]}" | 脚本路径: ./test.sh |
常用环境变量
| 变量名 | 作用 | 示例代码 | 输出示例 |
|---|---|---|---|
$USER | 当前用户名 | echo "用户: $USER" | 用户: ubuntu |
$HOME | 当前用户的主目录路径 | echo "主目录: $HOME" | 主目录: /home/user |
$PATH | 可执行文件的搜索路径 | echo "PATH: $PATH" | PATH: /usr/bin:/bin |
$SHELL | 当前 Shell 的路径 | echo "Shell: $SHELL" | Shell: /bin/bash |
$LANG | 系统语言设置 | echo "语言: $LANG" | 语言: en_US.UTF-8 |
$TERM | 终端类型 | echo "终端类型: $TERM" | 终端类型: xterm-256color |
$EDITOR | 默认文本编辑器 | echo "编辑器: $EDITOR" | 编辑器: vim |
$UID | 当前用户的 UID | echo "UID: $UID" | UID: 1000 |
$GROUPS | 当前用户所属的组(数组) | echo "组: ${GROUPS[@]}" | 组: 1000 4 24 |
$HOSTNAME | 系统主机名 | echo "主机名: $HOSTNAME" | 主机名: myserver |
$OSTYPE | 操作系统类型 | echo "系统类型: $OSTYPE" | 系统类型: linux-gnu |
用户输入
1#!/bin/bash
2echo "Hello there, would you like to learn how to hack: Y/N?"
3read answer # 把用户输入存到answer变量中
4echo "Your answer was $answer"

1#!/bin/bash
2# Prompt the user for credentials
3# Penetration Testing with Kali Linux 2.0
4# PWK 2.0 Copyright © Offensive Security Ltd. All rights reserved. 110
5read -p 'Username: ' username # 输出提示的同时将用户输入存入username变量
6read -sp 'Password: ' password # 输出提示的同时将用户输入存入password变量,且不显示,用于密码
7echo " "
8echo "Thanks, your creds are as follows: " $username " and " $password

判断
Bash 条件测试操作符详解
逻辑操作符
| 操作符 | 描述 | 示例 |
|---|---|---|
! EXPRESSION | 对表达式取反(非) | if ! [ -e file ] → 文件不存在时条件为真 |
字符串比较
| 操作符 | 描述 | 示例 |
|---|---|---|
-n STRING | 字符串长度大于零(非空) | if [ -n "$name" ] → 检查变量 name 是否非空 |
-z STRING | 字符串长度为零(空) | if [ -z "$error" ] → 检查变量 error 是否为空 |
STRING1 = STRING2 | 字符串相等 | if [ "$os" = "Linux" ] → 判断系统是否为 Linux |
STRING1 != STRING2 | 字符串不相等 | if [ "$input" != "exit" ] → 输入不是 “exit” 时条件为真 |
整数比较
| 操作符 | 描述 | 示例 |
|---|---|---|
INT1 -eq INT2 | 等于(Equal) | if [ "$a" -eq 5 ] → 判断 a 是否等于 5 |
INT1 -ne INT2 | 不等于(Not Equal) | if [ "$retry" -ne 0 ] → 重试次数不为 0 |
INT1 -gt INT2 | 大于(Greater Than) | if [ "$score" -gt 60 ] → 分数超过 60 |
INT1 -lt INT2 | 小于(Less Than) | if [ "$age" -lt 18 ] → 年龄小于 18 |
INT1 -ge INT2 | 大于等于(Greater or Equal) | if [ "$count" -ge 10 ] → 计数达到或超过 10 |
INT1 -le INT2 | 小于等于(Less or Equal) | if [ "$time" -le 30 ] → 时间小于等于 30 秒 |
文件测试
| 操作符 | 描述 | 示例 |
|---|---|---|
-d FILE | 文件存在且是目录 | if [ -d "/tmp" ] → 检查 /tmp 是否是目录 |
-e FILE | 文件存在 | if [ -e "log.txt" ] → 检查 log.txt 是否存在 |
-r FILE | 文件存在且有读权限 | if [ -r "config.cfg" ] → 检查配置文件是否可读 |
-s FILE | 文件存在且非空 | if [ -s "data.csv" ] → 检查数据文件是否有内容 |
-w FILE | 文件存在且有写权限 | if [ -w "output.log" ] → 检查日志文件是否可写 |
-x FILE | 文件存在且有执行权限 | if [ -x "install.sh" ] → 检查安装脚本是否有执行权限 |
新建一个文件**number_game.sh**
1#!/bin/bash
2# 生成随机数,用户猜测数字比大小
3
4# 生成1-100的随机数
5target=$((RANDOM % 100 + 1))
6attempts=0
7max_attempts=10
8
9echo "欢迎来到猜数字游戏!"
10echo "我已生成一个1到100之间的整数,你有${max_attempts}次机会猜中它。"
11
12while [ $attempts -lt $max_attempts ]; do
13((attempts++))
14remaining=$((max_attempts - attempts + 1))
15echo -n "第${attempts}次猜测(剩余${remaining}次):"
16
17read guess
18
19# 检查输入是否为空或非数字
20if [ -z "$guess" ]; then
21 echo "错误:输入不能为空!"
22 ((attempts--))
23 continue
24elif ! [[ "$guess" =~ ^[0-9]+$ ]]; then
25 echo "错误:请输入数字!"
26 ((attempts--))
27 continue
28fi
29
30# 比较数字
31if [ "$guess" -eq "$target" ]; then
32 echo "恭喜!你在第${attempts}次猜中了正确答案:${target}!"
33 exit 0
34elif [ "$guess" -lt "$target" ]; then
35 echo "提示:你猜的数字太小了!"
36else
37 echo "提示:你猜的数字太大了!"
38fi
39done
40
41echo "很遗憾,你已经用完所有次数。正确答案是:${target}。"
42exit 1

循环
1. for 循环
基本语法
1for 变量 in 列表; do
2循环体
3done
应用场景
- 遍历已知序列(数字、文件、字符串等)。
- 执行固定次数的重复操作。
示例 1:遍历数字序列
终端输入cat > for1.sh,复制粘贴如下内容,回车后按ctrl D结束输入。就能不用打开vim直接输入脚本了。
1#!/bin/bash
2# 遍历 1-5 并打印平方数
3for i in 1 2 3 4 5; do
4echo "$i 的平方是 $((i*i))"
5done
6
7# 使用序列生成器 {起..止..步长}
8for i in {1..5}; do
9echo "数字: $i"
10done
11
12# 指定步长(仅 Bash 4+ 支持)
13for i in {0..10..2}; do
14echo "偶数: $i"
15done
输出示例

示例 2:遍历文件
1#!/bin/bash
2# 遍历当前目录所有 .txt 文件并输出文件名
3for file in *.txt; do
4echo "find_${file}"
5done
6
7# 遍历带空格的文件名(需设置 IFS)
8IFS=$'\n' # 将字段分隔符设为换行符
9for file in $(find . -name "*.log"); do
10echo "处理文件: $file"
11done

示例 3:遍历数组
1#!/bin/bash
2fruits=("苹果" "香蕉" "橘子")
3for fruit in "${fruits[@]}"; do
4echo "水果: $fruit"
5done
输出示例

2. while 循环
基本语法
1while 条件; do
2循环体
3done
应用场景
- 条件持续满足时循环(如读取文件、等待任务完成)。
- 无限循环(需搭配
break或外部终止条件)。
示例 1:条件控制循环
1#!/bin/bash
2# 计数器从1累加到5
3count=1
4while [ $count -le 5 ]; do
5echo "计数: $count"
6((count++))
7done
输出示例

示例 2:读取文件内容**
1#!/bin/bash
2# 逐行读取文件
3while IFS= read -r line; do
4echo "行内容: $line"
5done < "w2.txt"

示例 3:无限循环 + 用户输入退出
1#!/bin/bash
2# 持续询问用户输入,直到输入 "exit"
3while true; do
4read -p "请输入命令(输入 exit 退出): " cmd
5if [ "$cmd" = "exit" ]; then
6 break
7else
8 echo "执行命令: $cmd" && echo $($cmd)
9fi
10done

3. until 循环(补充)
与 while 逻辑相反,当条件为 假 时执行循环。
1#!/bin/bash
2# 直到计数器大于5时停止
3count=1
4until [ $count -gt 5 ]; do
5echo "计数: $count"
6((count++))
7done

循环控制语句
| 命令 | 作用 | 示例 |
|---|---|---|
break | 立即终止循环 | if [ $i -eq 3 ]; then break; fi |
continue | 跳过当前循环,进入下一次 | if [ $i -eq 2 ]; then continue; fi |
选择循环的建议
- 已知迭代次数/列表 →
for循环 (如处理文件、数组、数字序列) - 依赖动态条件 →
while循环 (如读取输入、监控进程状态)
综合应用脚本
1#!/bin/bash
2# 功能: 查找并压缩所有 .log 文件,直到总压缩文件超过 3 个
3
4log_count=0
5while [ $log_count -lt 3 ]; do
6# 查找未压缩的 .log 文件
7for file in *.log; do
8 if [ -f "$file" ]; then
9 gzip "$file"
10 echo "已压缩: $file"
11 ((log_count++))
12 # 达到3个后退出循环
13 if [ $log_count -ge 3 ]; then
14 break 2 # 跳出外层 while 循环
15 fi
16 fi
17done
18sleep 1 # 等待新日志生成
19done
20echo "已压缩满3个文件!"

通过灵活组合 for 和 while,可以高效处理文件操作、系统监控等任务。
函数
在 Bash 脚本中,函数(Function)用于封装可重复使用的代码块,提升代码的可读性和复用性。以下是 Bash 函数的详细用法及示例:
1. 定义函数
语法
1# 方式1:使用 function 关键字
2function 函数名 {
3函数体
4}
5
6# 方式2:直接定义(兼容性更好)
7函数名() {
8函数体
9}
示例 1:简单函数
1# 定义一个打印欢迎信息的函数
2welcome() {
3echo "欢迎使用本脚本!当前用户:$USER"
4}
5
6# 调用函数
7welcome
输出:
1欢迎使用本脚本!当前用户:ubuntu

2. 函数参数
函数通过位置参数($1、$2…)接收参数,与脚本参数类似。
示例 2:带参数的函数
1# 定义一个加法计算器
2add() {
3local sum=$(( $1 + $2 )) # 使用 local 定义局部变量
4echo "$1 + $2 = $sum"
5}
6
7# 调用函数并传递参数
8add 5 3
输出:
15 + 3 = 8

3. 返回值
Bash 函数通过 return 返回 退出状态码(0 表示成功,非 0 表示错误),或通过 echo 输出结果。
示例 3:返回状态码
1# 检查文件是否存在
2file_exists() {
3if [ -f "$1" ]; then
4 return 0 # 文件存在,返回成功
5else
6 return 1 # 文件不存在,返回失败
7fi
8}
9
10# 调用函数并检查返回值
11if file_exists "/etc/passwd"; then
12echo "文件存在!"
13else
14echo "文件不存在!"
15fi

示例 4:返回字符串
1# 生成问候语(通过 echo 返回结果)
2get_greeting() {
3local name=$1
4echo "你好,$name!今天是 $(date +%F)"
5}
6
7# 捕获函数输出
8message=$(get_greeting "大黑阔")
9echo "$message"
输出:
1你好,小明!今天是 2023-10-05

4. 局部变量
使用 local 关键字定义局部变量,避免污染全局作用域。
1# 生成问候语(通过 echo 返回结果)
2get_greeting() {
3local name=$1
4globalname=$2
5echo "你好,$name!今天是 $(date +%F)"
6}
7
8# 捕获函数输出
9get_greeting "大黑阔" "Hacker"
10echo $name # 局部变量不可见
11echo $globalname

5. 高级用法
递归函数
1# 计算阶乘(递归实现)
2factorial() {
3if [ $1 -le 1 ]; then
4 echo 1
5else
6 local prev=$(factorial $(( $1 - 1 )) )
7 echo $(( $1 * $prev ))
8fi
9}
10
11# 计算 5!
12result=$(factorial 5)
13echo "5! = $result" # 输出 "5! = 120"

函数库
将常用函数保存为独立文件(如 utils.sh),通过 source 导入:to_upper函数实现小写转大写。
1# utils.sh
2to_upper() {
3echo "$1" | tr '[:lower:]' '[:upper:]'
4}
5
6# main.sh
7#!/bin/bash
8source utils.sh
9echo $(to_upper "hello")

6. 注意事项
- 定义顺序:函数必须在调用之前定义。
- 命名冲突:避免函数名与系统命令或别名重复。
- 参数传递:参数通过空格分隔,若参数含空格需用引号包裹(如
func "参数 1")。 - 返回值限制:
return只能返回 0-255 的整数,返回字符串或复杂数据需用echo。
布尔逻辑运算
在 Bash 中,&&、||、& 和 | 是常用的操作符,用于控制命令的执行逻辑和流程。以下是它们的详细解释及示例:
1. &&(逻辑与)
- 作用:只有 前一个命令成功执行(退出状态码为
0),才会执行后面的命令。
1mkdir mydir && cd mydir # 先创建目录,若成功则进入该目录
- 如果
mkdir mydir成功(目录创建成功),则执行cd mydir。 - 如果
mkdir失败(如目录已存在),则不会执行cd。
2. ||(逻辑或)
- 作用:只有 前一个命令执行失败(退出状态码非
0),才会执行后面的命令。
1ping -c1 google.com || echo "网络不可达" # 若 ping 失败,则提示错误
- 如果
ping失败(网络断开),则执行echo输出提示。 - 如果
ping成功,不执行echo。
3. &(后台执行)
- 作用:将命令放入 后台执行,终端可继续输入其他命令。
1sleep 10 & # 后台休眠10秒,终端可继续操作
- 命令后加
&会返回一个后台进程的PID(如[1] 12345)。 - 可通过
jobs查看后台任务,fg %1将任务调回前台。
4. |(管道)
- 作用:将 前一个命令的输出 作为 后一个命令的输入。
1cat log.txt | grep "error" | wc -l # 统计 log.txt 中 "error" 的行数
cat log.txt输出文件内容。grep "error"过滤含 “error” 的行。wc -l统计行数。
组合使用示例
场景:下载文件,若失败则重试,成功后解压并删除原文件。
1wget http://example.com/file.tar.gz && \
2tar -xzf file.tar.gz || \
3echo "下载失败,请检查网络!"
wget下载文件,若成功则执行tar解压。- 若
wget失败,直接执行echo提示错误。
符号优先级
- 默认优先级:
&&和||的优先级低于|和&。 - 强制优先级:用
()或{} - 分组:
1(cmd1 && cmd2) || cmd3 # 若 cmd1 和 cmd2 都成功则不执行 cmd3,否则执行
实操练习1-网页地址查找

1wget www.megacorpone.com
2ls -al index.html
3grep "href=" index.html

1grep "href=" index.html | grep "\.megacorpone" | grep -v "www\.megacorpone\.com" | head
2grep "href=" index.html | grep "\.megacorpone" | grep -v "www\.megacorpone\.com" | awk -F "http://" '{print $2}'
3
4grep "href=" index.html # 1. 提取所有包含 href= 的 HTML 行
5| grep "\.megacorpone" # 2. 筛选含 .megacorpone 的行(子域名或路径)
6| grep -v "www\.megacorpone\.com" # 3. 排除含 www.megacorpone.com 的行
7| head # 4. 仅显示前 10 条结果

1grep "href=" index.html | grep "\.megacorpone" | grep -v "www\.megacorpone\.com" | awk -F "http://" '{print $2}' | cut -d "/" -f 1
2grep -o '[^/]*\.megacorpone\.com' index.html | sort -u > list.txt
命令 1:提取特定子域名并处理链接结构
分步解析
grep "href=" index.html- 从
index.html中提取所有包含href=的行(HTML 超链接标签)。
- 从
grep "\.megacorpone"- 筛选包含
.megacorpone的行(匹配子域名或路径中的该字段)。
- 筛选包含
grep -v "www\.megacorpone\.com"- 排除包含
www.megacorpone.com的行(主站域名)。
- 排除包含
awk -F "http://" '{print $2}'- 以
http://为分隔符,提取其后的内容(如cdn.megacorpone.com/style.css)。
- 以
cut -d "/" -f 1- 以
/为分隔符,提取第一个字段(即域名部分,如cdn.megacorpone.com)。
- 以
命令 2:直接匹配并收集所有子域名
分步解析
grep -o '[^/]\*\.megacorpone\.com'-o:仅输出匹配的部分。正则
[^/]*\.megacorpone\.com[^/]*:匹配不包含/的任意字符(避免包含路径或端口)。\.megacorpone\.com:匹配以.megacorpone.com结尾的域名。
sort -u- 对结果排序并去重(
-u表示唯一性)。
- 对结果排序并去重(
> list.txt- 将结果保存到
list.txt文件。
- 将结果保存到

主机ip筛查
1for url in $(cat list.txt); do host $url; done
2for url in $(cat list.txt); do host $url; done | grep "has address" | cut -d " " -f 4 | sort -u


查找发现教材上的示例网页页面中的子域名,ip主要集中在加拿大(这里和教材示例不同,推测是因为使用了VPN的缘故,以及网页距离写教材时已经过去多年,更换过服务器)。
实操练习2-筛选漏洞脚本并下载
1searchsploit afd windows -w -t
2searchsploit afd windows -w -t | grep http | cut -f 2 -d "|"
3mkdir afd && cd afd
4for e in $(searchsploit afd windows -w -t | grep http | cut -f 2 -d "|"); do exp_name=$(echo $e | cut -d "/" -f 5) && url=$(echo $e | sed 's/exploits/raw/') && wget -q --no-check-certificate $url -O $exp_name; done

1file 17133
2cat 17133

实操练习3-Nmap扫描
1sudo nmap --script=vuln -p- -T4 -iL nmaphost.txt --min-rate 1000 --open
2sudo nmap -A -p80 --open 10.11.1.0/24 -oG nmap-scan_10.11.1.1-254
3cat nmap-scan_10.11.1.1-254 | grep 80 | grep -v "Nmap"
4cat nmap-scan_10.11.1.1-254 | grep 80 | grep -v "Nmap" | awk '{print $2}'
5for ip in $(cat nmap-scan_10.11.1.1-254 | grep 80 | grep -v "Nmap" | awk '{print $2}'); do cutycapt --url=$ip --out=$ip.png;done
课后练习
Research Bash loops and write a short script to perform a ping sweep of your target IP range of 10.11.1.0/24.
Try to do the above exercise with a higher-level scripting language such as Python, Perl, or Ruby.
Use the practical examples in this module to help you create a Bash script that extracts JavaScript files from the access_log.txt file (http://www.offensive-security.com/pwkfiles/access_log.txt.gz). Make sure the file names DO NOT include the path, are unique, and are sorted.
Re-write the previous exercise in another language such as Python, Perl, or Ruby.
研究 Bash 循环,编写一个简短的脚本,对目标 IP 范围
10.11.1.0/24执行 Ping 扫描。尝试用 Python 等高级语言实现上述功能。
使用本模块的实例,编写一个 Bash 脚本从
access_log.txt中提取 JavaScript 文件名,要求文件名不包含路径、唯一且排序。用 Python 等语言重写上述提取 JavaScript 文件名的功能。
1. Bash 脚本:Ping 扫描 10.11.1.0/24 网段
这里为了能有输出,改为172.168.169.0/24网段,时我本地虚拟机的内网
#!/bin/bash
# 遍历 1-254,发送 Ping 请求并输出存活主机
for ip in {1..254}; do
target="172.168.169.$ip"
# -c 1: 发送 1 个包,-W 1: 超时 1 秒
ping -c 1 -W 1 $target > /dev/null 2>&1
if [ $? -eq 0 ]; then
echo "$target is up"
fi
done

2. Python 脚本:Ping 扫描 10.11.1.0/24 网段
import os
import subprocess
from concurrent.futures import ThreadPoolExecutor
def ping_host(ip):
target = f"172.168.169.{ip}"
# 调用系统 Ping 命令(Windows 需将 '-c 1' 改为 '-n 1')
result = subprocess.run(['ping', '-c', '1', '-W', '1', target],
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
if result.returncode == 0:
print(f"{target} is up")
# 使用多线程加速扫描(1-254)
with ThreadPoolExecutor(max_workers=50) as executor:
executor.map(ping_host, range(1, 255))

3. Bash 脚本:从 access_log.txt 提取唯一 JS 文件名
wget --secure-protocol=TLSv1_2 https://www.offensive-security.com/pwk-files/access_log.txt.gz
gunzip access_log.txt.gz
#!/bin/bash
# 提取所有 JS 文件,去重并排序
grep -oP 'GET \K[^ ]+?\.js' access_log.txt | awk -F/ '{print $NF}' | sort -u
说明:
grep -oP 'GET \K[^ ]+?\.js': 匹配GET请求中的.js文件路径,\K丢弃GET前缀。awk -F/ '{print $NF}': 以/分割路径,输出最后一个字段(文件名)。sort -u: 排序并去重。

4. Python 脚本:提取唯一 JS 文件名
1import re
2from collections import defaultdict
3
4js_files = set()
5
6# 匹配 GET 请求中的 JS 文件
7pattern = re.compile(r'GET\s+([^ ]+?\.js)')
8
9with open('access_log.txt', 'r') as f:
10 for line in f:
11 match = pattern.search(line)
12 if match:
13 path = match.group(1)
14 # 提取文件名(忽略路径)
15 filename = path.split('/')[-1]
16 js_files.add(filename)
17
18# 排序并输出
19for filename in sorted(js_files):
20 print(filename)

🔔 想要获取更多网络安全与编程技术干货?
关注 泷羽Sec-静安 公众号,与你一起探索前沿技术,分享实用的学习资源与工具。我们专注于深入分析,拒绝浮躁,只做最实用的技术分享!💻
扫描下方二维码,马上加入我们,共同成长!🌟
👉 长按或扫描二维码关注公众号
或者直接回复文章中的关键词,获取更多技术资料与书单推荐!📚


