Day14 Kali的Bash脚本

关注 泷羽Sec泷羽Sec-静安公众号,这里会定期更新与 OSCP、渗透测试等相关的最新文章,帮助你理解网络安全领域的最新动态。后台回复“OSCP配套工具”获取本文的工具

Bash脚本基础

新建一个hello-world.sh文件,写入以下内容:

#!/bin/bash
#Hello world Bash Script
echo "hello world!"

然后给脚本添加执行权限后运行

chmod +x hello-world.sh 
./hello-world.sh

image-20250516132311698

变量

s1=hello
s2=world
s3="I am Hacker"
echo $s2 $s2 $s3

image-20250516132613788

参数里面套命令,推荐用$()的用法,` 是过时的用法。

user1=$(whoami) && user2=`whoami`
echo $user1 $user2  

image-20250516133017421

参数

$0  脚本文件名自己
$1-$9 bash脚本的前九个参数
$# 传递给bash脚本的参数数量
$@  传递给bash 脚本的所有参数
$? 最近运行的程序的退出状态
$USER   运行脚本的用户的用户名
$HOSTNAME 计算机的主机名
$RANDOM  生成一个随机数
$LINENO  脚本中的当前行号

新建一个脚本写入如下内容。

#!/bin/bash
echo "The first two arguments are $1 and $2"

image-20250516133425998

#!/bin/bash
# 文件名: demo_script.sh
# 功能: 演示常用 Bash 参数的用法

# 1. 打印脚本名称
echo "脚本名称: $0"

# 2. 打印前三个参数(若未传递参数则显示空)
echo "第一个参数: ${1:-未提供}"
echo "第二个参数: ${2:-未提供}"
echo "第三个参数: ${3:-未提供}"

# 3. 打印总参数个数
echo "参数总数: $#"

# 4. 打印所有参数(带循环)
echo "所有参数:"
count=1
for arg in "$@"; do
echo "  参数$count: $arg"
((count++))
done

# 5. 测试上一个命令的退出状态
echo "生成随机数(测试退出状态):"
echo "随机数: $RANDOM"
echo "生成随机数的退出状态: $? (0表示成功)"

# 6. 故意执行一个失败的命令
echo "执行一个失败的命令:"
ls /non_existent_file
echo "失败命令的退出状态: $? (非0表示失败)"

# 7. 用户和主机信息
echo "当前用户: $USER"
echo "主机名: $HOSTNAME"

# 8. 显示脚本当前行号(动态变化)
echo "当前行号(执行前): $LINENO"
echo "当前行号(执行后): $LINENO"

# 9. 结束提示
echo "脚本结束于行号: $LINENO"

image-20250516134013667

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 进程的 PIDecho "PID: $$"PID: 12345
$!最后一个后台进程的 PIDsleep 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_VERSIONBash 版本信息echo "Bash版本: $BASH_VERSION"Bash版本: 5.1.16(1)-release
$PPID父进程的 PIDecho "父进程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当前用户的 UIDecho "UID: $UID"UID: 1000
$GROUPS当前用户所属的组(数组)echo "组: ${GROUPS[@]}"组: 1000 4 24
$HOSTNAME系统主机名echo "主机名: $HOSTNAME"主机名: myserver
$OSTYPE操作系统类型echo "系统类型: $OSTYPE"系统类型: linux-gnu

用户输入

#!/bin/bash
echo "Hello there, would you like to learn how to hack: Y/N?"
read answer  # 把用户输入存到answer变量中
echo "Your answer was $answer"

image-20250516134506136

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

image-20250516134819426

判断

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**

#!/bin/bash
# 生成随机数,用户猜测数字比大小

# 生成1-100的随机数
target=$((RANDOM % 100 + 1))
attempts=0
max_attempts=10

echo "欢迎来到猜数字游戏!"
echo "我已生成一个1到100之间的整数,你有${max_attempts}次机会猜中它。"

while [ $attempts -lt $max_attempts ]; do
((attempts++))
remaining=$((max_attempts - attempts + 1))
echo -n "第${attempts}次猜测(剩余${remaining}次):"

read guess

# 检查输入是否为空或非数字
if [ -z "$guess" ]; then
    echo "错误:输入不能为空!"
    ((attempts--))
    continue
elif ! [[ "$guess" =~ ^[0-9]+$ ]]; then
    echo "错误:请输入数字!"
    ((attempts--))
    continue
fi

# 比较数字
if [ "$guess" -eq "$target" ]; then
    echo "恭喜!你在第${attempts}次猜中了正确答案:${target}!"
    exit 0
elif [ "$guess" -lt "$target" ]; then
    echo "提示:你猜的数字太小了!"
else
    echo "提示:你猜的数字太大了!"
fi
done

echo "很遗憾,你已经用完所有次数。正确答案是:${target}。"
exit 1

image-20250516135653801

循环

1. for 循环

基本语法
for 变量 in 列表; do
循环体
done
应用场景
  • 遍历已知序列(数字、文件、字符串等)。
  • 执行固定次数的重复操作
示例 1:遍历数字序列

终端输入cat > for1.sh,复制粘贴如下内容,回车后按ctrl D结束输入。就能不用打开vim直接输入脚本了。

#!/bin/bash
# 遍历 1-5 并打印平方数
for i in 1 2 3 4 5; do
echo "$i 的平方是 $((i*i))"
done

# 使用序列生成器 {起..止..步长}
for i in {1..5}; do
echo "数字: $i"
done

# 指定步长(仅 Bash 4+ 支持)
for i in {0..10..2}; do
echo "偶数: $i"
done
输出示例

image-20250516140637023

示例 2:遍历文件
#!/bin/bash
# 遍历当前目录所有 .txt 文件并输出文件名
for file in *.txt; do
echo "find_${file}"
done

# 遍历带空格的文件名(需设置 IFS)
IFS=$'\n'  # 将字段分隔符设为换行符
for file in $(find . -name "*.log"); do
echo "处理文件: $file"
done

image-20250516140921420

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

image-20250516141053886

2. while 循环

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

image-20250516141150659

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

image-20250516141326133

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

image-20250516141741050

3. until 循环(补充)

while 逻辑相反,当条件为 时执行循环。

#!/bin/bash
# 直到计数器大于5时停止
count=1
until [ $count -gt 5 ]; do
echo "计数: $count"
((count++))
done

image-20250516141825441

循环控制语句

命令作用示例
break立即终止循环if [ $i -eq 3 ]; then break; fi
continue跳过当前循环,进入下一次if [ $i -eq 2 ]; then continue; fi

选择循环的建议

  • 已知迭代次数/列表for 循环
    (如处理文件、数组、数字序列)
  • 依赖动态条件while 循环
    (如读取输入、监控进程状态)

综合应用脚本

#!/bin/bash
# 功能: 查找并压缩所有 .log 文件,直到总压缩文件超过 3 个

log_count=0
while [ $log_count -lt 3 ]; do
# 查找未压缩的 .log 文件
for file in *.log; do
    if [ -f "$file" ]; then
        gzip "$file"
        echo "已压缩: $file"
        ((log_count++))
        # 达到3个后退出循环
        if [ $log_count -ge 3 ]; then
            break 2  # 跳出外层 while 循环
        fi
    fi
done
sleep 1  # 等待新日志生成
done
echo "已压缩满3个文件!"

image-20250516142139500

通过灵活组合 forwhile,可以高效处理文件操作、系统监控等任务。

函数

在 Bash 脚本中,函数(Function)用于封装可重复使用的代码块,提升代码的可读性和复用性。以下是 Bash 函数的详细用法及示例:

1. 定义函数

语法
# 方式1:使用 function 关键字
function 函数名 {
函数体
}

# 方式2:直接定义(兼容性更好)
函数名() {
函数体
}
示例 1:简单函数
# 定义一个打印欢迎信息的函数
welcome() {
echo "欢迎使用本脚本!当前用户:$USER"
}

# 调用函数
welcome

输出

欢迎使用本脚本!当前用户:ubuntu

image-20250516142559077

2. 函数参数

函数通过位置参数($1$2…)接收参数,与脚本参数类似。

示例 2:带参数的函数
# 定义一个加法计算器
add() {
local sum=$(( $1 + $2 ))  # 使用 local 定义局部变量
echo "$1 + $2 = $sum"
}

# 调用函数并传递参数
add 5 3

输出

5 + 3 = 8

image-20250516142651984

3. 返回值

Bash 函数通过 return 返回 退出状态码(0 表示成功,非 0 表示错误),或通过 echo 输出结果。

示例 3:返回状态码
# 检查文件是否存在
file_exists() {
if [ -f "$1" ]; then
    return 0  # 文件存在,返回成功
else
    return 1  # 文件不存在,返回失败
fi
}

# 调用函数并检查返回值
if file_exists "/etc/passwd"; then
echo "文件存在!"
else
echo "文件不存在!"
fi

image-20250516142750036

示例 4:返回字符串
# 生成问候语(通过 echo 返回结果)
get_greeting() {
local name=$1
echo "你好,$name!今天是 $(date +%F)"
}

# 捕获函数输出
message=$(get_greeting "大黑阔")
echo "$message"

输出

你好,小明!今天是 2023-10-05

image-20250516142859752

4. 局部变量

使用 local 关键字定义局部变量,避免污染全局作用域。

# 生成问候语(通过 echo 返回结果)
get_greeting() {
local name=$1
globalname=$2
echo "你好,$name!今天是 $(date +%F)"
}

# 捕获函数输出
get_greeting "大黑阔" "Hacker"
echo $name  # 局部变量不可见
echo $globalname

image-20250516143423888

5. 高级用法

递归函数
# 计算阶乘(递归实现)
factorial() {
if [ $1 -le 1 ]; then
    echo 1
else
    local prev=$(factorial $(( $1 - 1 )) )
    echo $(( $1 * $prev ))
fi
}

# 计算 5!
result=$(factorial 5)
echo "5! = $result"  # 输出 "5! = 120"

image-20250516143630431

函数库

将常用函数保存为独立文件(如 utils.sh),通过 source 导入:to_upper函数实现小写转大写。

# utils.sh
to_upper() {
echo "$1" | tr '[:lower:]' '[:upper:]'
}

# main.sh
#!/bin/bash
source utils.sh
echo $(to_upper "hello")

image-20250516144109807

6. 注意事项

  1. 定义顺序:函数必须在调用之前定义。
  2. 命名冲突:避免函数名与系统命令或别名重复。
  3. 参数传递:参数通过空格分隔,若参数含空格需用引号包裹(如 func "参数 1")。
  4. 返回值限制return 只能返回 0-255 的整数,返回字符串或复杂数据需用 echo

布尔逻辑运算

在 Bash 中,&&||&| 是常用的操作符,用于控制命令的执行逻辑和流程。以下是它们的详细解释及示例:

1. &&(逻辑与)

  • 作用:只有 前一个命令成功执行(退出状态码为 0),才会执行后面的命令。
mkdir mydir && cd mydir  # 先创建目录,若成功则进入该目录
  • 如果 mkdir mydir 成功(目录创建成功),则执行 cd mydir
  • 如果 mkdir 失败(如目录已存在),则不会执行 cd

2. ||(逻辑或)

  • 作用:只有 前一个命令执行失败(退出状态码非 0),才会执行后面的命令。
ping -c1 google.com || echo "网络不可达"  # 若 ping 失败,则提示错误
  • 如果 ping 失败(网络断开),则执行 echo 输出提示。
  • 如果 ping 成功,不执行 echo

3. &(后台执行)

  • 作用:将命令放入 后台执行,终端可继续输入其他命令。
sleep 10 &  # 后台休眠10秒,终端可继续操作
  • 命令后加 & 会返回一个后台进程的 PID(如 [1] 12345)。
  • 可通过 jobs 查看后台任务,fg %1 将任务调回前台。

4. |(管道)

  • 作用:将 前一个命令的输出 作为 后一个命令的输入
cat log.txt | grep "error" | wc -l  # 统计 log.txt 中 "error" 的行数
  • cat log.txt 输出文件内容。
  • grep "error" 过滤含 “error” 的行。
  • wc -l 统计行数。

组合使用示例

场景:下载文件,若失败则重试,成功后解压并删除原文件。
wget http://example.com/file.tar.gz && \
tar -xzf file.tar.gz || \
echo "下载失败,请检查网络!"
  1. wget 下载文件,若成功则执行 tar 解压。
  2. wget 失败,直接执行 echo 提示错误。

符号优先级

  • 默认优先级&&|| 的优先级低于 |&
  • 强制优先级:用 () {}
  • 分组
(cmd1 && cmd2) || cmd3  # 若 cmd1 和 cmd2 都成功则不执行 cmd3,否则执行

实操练习1-网页地址查找

image-20250516145203881

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

image-20250516145036474

grep "href=" index.html | grep "\.megacorpone" | grep -v "www\.megacorpone\.com" | head
grep "href=" index.html | grep "\.megacorpone" | grep -v "www\.megacorpone\.com" | awk -F "http://" '{print $2}'

grep "href=" index.html         # 1. 提取所有包含 href= 的 HTML 行
| grep "\.megacorpone"          # 2. 筛选含 .megacorpone 的行(子域名或路径)
| grep -v "www\.megacorpone\.com"  # 3. 排除含 www.megacorpone.com 的行
| head                          # 4. 仅显示前 10 条结果

image-20250516145247591

grep "href=" index.html | grep "\.megacorpone" | grep -v "www\.megacorpone\.com" | awk -F "http://" '{print $2}' | cut -d "/" -f 1
grep -o '[^/]*\.megacorpone\.com' index.html | sort -u > list.txt

命令 1:提取特定子域名并处理链接结构

分步解析
  1. grep "href=" index.html
    • index.html 中提取所有包含 href= 的行(HTML 超链接标签)。
  2. grep "\.megacorpone"
    • 筛选包含 .megacorpone 的行(匹配子域名或路径中的该字段)。
  3. grep -v "www\.megacorpone\.com"
    • 排除包含 www.megacorpone.com 的行(主站域名)。
  4. awk -F "http://" '{print $2}'
    • http:// 为分隔符,提取其后的内容(如 cdn.megacorpone.com/style.css)。
  5. cut -d "/" -f 1
    • / 为分隔符,提取第一个字段(即域名部分,如 cdn.megacorpone.com)。

命令 2:直接匹配并收集所有子域名

分步解析
  1. grep -o '[^/]\*\.megacorpone\.com'

    • -o:仅输出匹配的部分。

    • 正则

      [^/]*\.megacorpone\.com
      
      • [^/]*:匹配不包含 / 的任意字符(避免包含路径或端口)。
      • \.megacorpone\.com:匹配以 .megacorpone.com 结尾的域名。
  2. sort -u

    • 对结果排序并去重(-u 表示唯一性)。
  3. > list.txt

    • 将结果保存到 list.txt 文件。

image-20250516145504949

主机ip筛查

for url in $(cat list.txt); do host $url; done
for url in $(cat list.txt); do host $url; done | grep "has address" | cut -d " " -f 4 | sort -u

image-20250516151236442

image-20250516151542562

查找发现教材上的示例网页页面中的子域名,ip主要集中在加拿大(这里和教材示例不同,推测是因为使用了VPN的缘故,以及网页距离写教材时已经过去多年,更换过服务器)。

实操练习2-筛选漏洞脚本并下载

searchsploit afd windows -w -t
searchsploit afd windows -w -t | grep http | cut -f 2 -d "|"
mkdir afd && cd afd
for 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

image-20250516152318445

file 17133
cat 17133

image-20250516152453236

实操练习3-Nmap扫描

sudo nmap --script=vuln -p- -T4 -iL nmaphost.txt --min-rate 1000 --open
sudo nmap -A -p80 --open 10.11.1.0/24 -oG nmap-scan_10.11.1.1-254
cat nmap-scan_10.11.1.1-254 | grep 80 | grep -v "Nmap"
cat nmap-scan_10.11.1.1-254 | grep 80 | grep -v "Nmap" | awk '{print $2}'
for 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

课后练习

  1. Research Bash loops and write a short script to perform a ping sweep of your target IP range of 10.11.1.0/24.

  2. Try to do the above exercise with a higher-level scripting language such as Python, Perl, or Ruby.

  3. 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.

  4. Re-write the previous exercise in another language such as Python, Perl, or Ruby.

  5. 研究 Bash 循环,编写一个简短的脚本,对目标 IP 范围 10.11.1.0/24 执行 Ping 扫描。

  6. 尝试用 Python 等高级语言实现上述功能。

  7. 使用本模块的实例,编写一个 Bash 脚本从 access_log.txt 中提取 JavaScript 文件名,要求文件名不包含路径、唯一且排序。

  8. 用 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

image-20250516161343955

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))

image-20250516161722235

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:
    排序并去重。

image-20250516161619646

4. Python 脚本:提取唯一 JS 文件名
import re
from collections import defaultdict

js_files = set()

# 匹配 GET 请求中的 JS 文件
pattern = re.compile(r'GET\s+([^ ]+?\.js)')

with open('access_log.txt', 'r') as f:
    for line in f:
        match = pattern.search(line)
        if match:
            path = match.group(1)
            # 提取文件名(忽略路径)
            filename = path.split('/')[-1]
            js_files.add(filename)

# 排序并输出
for filename in sorted(js_files):
    print(filename)

image-20250516161703492


🔔 想要获取更多网络安全与编程技术干货?

关注 泷羽Sec-静安 公众号,与你一起探索前沿技术,分享实用的学习资源与工具。我们专注于深入分析,拒绝浮躁,只做最实用的技术分享!💻

扫描下方二维码,马上加入我们,共同成长!🌟

👉 长按或扫描二维码关注公众号

或者直接回复文章中的关键词,获取更多技术资料与书单推荐!📚

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

泷羽Sec-静安

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值