panda's blog

bash脚本

htb_ac:bash脚本基础

2026/01/13
loading

bash脚本

脚本构成

  • shebang
    Shebang 行总是位于每个脚本的顶部

    #!/bin/bash
    #!/usr/bin/env python
    #!/usr/bin/env perl
    
  • 判断

    • 大于 -gt (greater than)
    • 小于 -lt (less than)
    • 大于或等于 -ge (greater than or equal)
    • 小于或等于 -le (less than or equal)
    • 不相等 -ne (not equal)
    • 相等 -eq (equal)
    符号解释
    string1 = string2[ 命令一起使用的等价运算符,如果两个操作数相等,则返回 true
    string1 == string2相等运算符与 [[ 命令一起使用,如果两个操作数都相等,则返回 true
    string1 != string2不等式运算符,如果两个操作数不相等,返回 true
    string1 =~ regexRegex 运算符,如果 string1 符合扩展的 regex,则返回 true
    string1 > string2大于运算符,如果 string1 大于 string2,则根据词法(字母)顺序返回 true
    string1 < string2小于运算符,如果 string1 小于 string2,则根据词法(字母)顺序返回 true
    -z string如果 string 的长度是 0,返回 true
    -n string如果 string 的长度不是 0,返回 true
  • 参数
    Bash 脚本的优势在于,我们总是可以将最多9个参数($0-$9)传递给脚本,而不需要将它们赋给变量或为这些变量设置相应的需求。9个参数,因为第一个参数 $0是为脚本保留的。
    image-20231208121322376-1768281549912.png

  • 特殊变量

    特殊变量描述
    $0获取当前脚本的名称。
    $#获取执行 bash 脚本时传递的参数数量。
    $*获取参数字符串数组。
    $@它将每个命令行参数的列表存储为数组。
    $1-$9存储前 9 个参数。
    $?获取最后一个命令或最近执行的进程的状态。
    $!显示最后一个后台命令的进程 ID。
    $$获取当前 shell 的进程 ID。
    $-获取当前 Shell 进程指定的选项。
  • 变量

    美元符号仅用于允许在其他代码部分中使用此变量的对应值。赋值变量时,名称和值之间不能有空格。
    image-20231208122558900-1768281548541.png

  • 数组

    在 Bash 中为单个变量分配多个值。如果我们想要扫描多个域或 IP 地址,这可能是有益的。这些变量称为数组,我们可以使用它们来存储和处理特定类型值的有序序列。数组以0开头的索引标识每个存储条目。

    需要注意的是,单引号(’...’)和双引号(“ ...”)可以防止数组中的单个值被空格分隔。

    domains=(www.inlanefreight.com ftp.inlanefreight.com vpn.inlanefreight.com www2.inlanefreight.com)
    for i in {0..4}
    do
    	echo ${domains[$i]}
    done
    

image-20231208123139841-1768281548540.png

  • 文件操作符

    OperatorDescription
    -eif the file exist
    -ftests if it is a file
    -dtests if it is a directory
    -Ltests if it is if a symbolic link
    -Nchecks if the file was modified after it was last read
    -Oif the current user owns the file
    -Gif the file’s group id matches the current user’s
    -stests if the file has a size greater than 0
    -rtests if the file has read permission
    -wtests if the file has write permission
    -xtests if the file has execute permission
  • 算术运算符

    OperatorDescription
    +Addition
    -Substraction
    *Multiplication
    /Division
    %Modulus
    variable++Increase the value of the variable by 1
    variable--Decrease the value of the variable by 1
  • 特殊使用

    • ${#变量}:计算字符长度
  • while

    #!/bin/bash
    
    counter=0
    
    while [ $counter -lt 10 ]
    do
      # Increase $counter by 1
      ((counter++))
      echo "Counter: $counter"
    
      if [ $counter == 2 ]
      then
        continue
      elif [ $counter == 4 ]
      then
        break
      fi
    done
    
  • case

    case <expression> in
    	pattern_1 ) statements ;;
    	pattern_2 ) statements ;;
    	pattern_3 ) statements ;;
    esac
    
  • function

    function name {
    	<commands>
    }
    
    name() {
    	<commands>
    }
    

输入输出

  • 转义字符

     使用双引号括起来的内容中有转义字符时,在添加参数 -e 之后才会被转义,否则会原样输出。

    echo "hello\n world"
    echo -e "hello\n world"
    
  • 输入

    read -p "please input your name and age:" name age
    read name age
    
  • 函数状态返回值

    状态码描述
    0命令成功结束
    1通用未知错误
    2误用shell命令
    126命令不可执行
    127没找到命令
    128无效退出参数
    128+xLinux信号x的严重错误
    130命令通过Ctrl+C终止
    255退出状态码越界

调试

bash -x 脚本
bash -x -v 脚本 #详细信息

例子

#!/bin/bash
var="panda"
for i in {1..2}
do
        var=$(echo $var|base64 )
done
echo $var
var=panda 
for i in {1..2};do var=$(echo $var|base64);echo $var;done
#!/bin/bash
# Count number of characters in a variable:
#     echo $variable | wc -c

# Variable to encode
var="nef892na9s1p9asn2aJs71nIsm"

for counter in {1..40}
do
        var=$(echo $var | base64)
        if [ $counter -eq 35 ]   #注意空格
        then
                echo $var | wc -c
        fi
done
#创建一个“ if-else”条件,该条件检查了名为“ var”的变量是否包含名为“ value”的变量。此外,变量“ var”必须包含超过113,450个字符。如果满足这些条件,则必须打印变量“ var”的最后20个字符。提交这些最后20个字符作为答#案。

#!/bin/bash

var="8dm7KsjU28B7v621Jls"
value="ERmFRMVZ0U2paTlJYTkxDZz09Cg"

for i in {1..40}
do
        var=$(echo $var | base64)
		if [[ $(echo $var|wc -c) > 113450 && $(echo $var|grep $value) ]]
		then
			echo $var | tail -c20
		fi
done
#创建一个编码,构建“base64”28次变量“ var”的“ for”循环。第28个哈希字符的数量是必须分配给“盐”变量的值。

#!/bin/bash

# Decrypt function
function decrypt {
	MzSaas7k=$(echo $hash | sed 's/988sn1/83unasa/g')
	Mzns7293sk=$(echo $MzSaas7k | sed 's/4d298d/9999/g')
	MzSaas7k=$(echo $Mzns7293sk | sed 's/3i8dqos82/873h4d/g')
	Mzns7293sk=$(echo $MzSaas7k | sed 's/4n9Ls/20X/g')
	MzSaas7k=$(echo $Mzns7293sk | sed 's/912oijs01/i7gg/g')
	Mzns7293sk=$(echo $MzSaas7k | sed 's/k32jx0aa/n391s/g')
	MzSaas7k=$(echo $Mzns7293sk | sed 's/nI72n/YzF1/g')
	Mzns7293sk=$(echo $MzSaas7k | sed 's/82ns71n/2d49/g')
	MzSaas7k=$(echo $Mzns7293sk | sed 's/JGcms1a/zIm12/g')
	Mzns7293sk=$(echo $MzSaas7k | sed 's/MS9/4SIs/g')
	MzSaas7k=$(echo $Mzns7293sk | sed 's/Ymxj00Ims/Uso18/g')
	Mzns7293sk=$(echo $MzSaas7k | sed 's/sSi8Lm/Mit/g')
	MzSaas7k=$(echo $Mzns7293sk | sed 's/9su2n/43n92ka/g')
	Mzns7293sk=$(echo $MzSaas7k | sed 's/ggf3iunds/dn3i8/g')
	MzSaas7k=$(echo $Mzns7293sk | sed 's/uBz/TT0K/g')

	flag=$(echo $MzSaas7k | base64 -d | openssl enc -aes-128-cbc -a -d -salt -pass pass:$salt)
}

# Variables
var="9M"
salt=""
hash="VTJGc2RHVmtYMTl2ZnYyNTdUeERVRnBtQWVGNmFWWVUySG1wTXNmRi9rQT0K"

for i in {1..28}
do
	var=$(echo $var|base64)
done
salt=$(echo $var|wc -c)

# Check if $salt is empty
if [[ ! -z "$salt" ]]
then
	decrypt
	echo $flag
else
	exit 1
fi

ssh登录脚本

#!/usr/bin/expect   
set ip [lindex $argv 0]
spawn ssh htb-student@$ip
expect {
       "yes/no" { send "yes\r";exp_continue }
       "password:" {send "HTB_@cademy_stdnt!\r" }
   }
interact
CATALOG