Skip to content

Latest commit

 

History

History
477 lines (304 loc) · 26 KB

File metadata and controls

477 lines (304 loc) · 26 KB

二、定制 Shell

bash 终端的几乎每个方面都是可定制的。现在您已经学习了使用一些重要的信息处理实用程序,我们可以继续学习如何使用它们来定制 shell。在本章中,我们将介绍的很多内容涉及从一个程序中获取信息,将其传输到另一个程序中,并过滤掉对我们来说重要的任何细节。

您还将了解一些关于 bash 脚本的知识,这是您的 Kali-Linux 和更大的 Linux 家族中大量应用程序的组成部分。

格式化终端输出

在 bash 终端上打印的所有内容都是由光标完成的,光标只是 bash 终端的另一个组件,您可以使用非常方便的速记进行控制。本节将介绍如何控制终端上打印输出的颜色和基本格式,在本章后面,您还将看到一些非常酷的提示和技巧。

首先,让我们讨论一下控制序列。控制序列是为终端上显示的文本引入特殊行为的字符模式。这些特殊字符始终位于它们格式化的输出之前。控制序列通常由转义字符分隔,我们感兴趣的控制序列由\e表示。

使用这个控制序列,我们可以做非常酷的事情;请遵守以下命令行:

for colorcode in {93..88} {124..129};  do echo –en "\e[48;5;${colorcode}m \e[0m"; done

下面是上一个命令的屏幕截图:

Formatting the terminal output

另一个示例是以下命令行:

for colorcode in {93..88} {124..129};  do echo –en "\e[38;5;${colorcode}m|||\e[0m"; done

下面是上一个命令的屏幕截图:

Formatting the terminal output

这是怎么回事?嗯我们需要讨论一些基本的文本格式控制序列。这些控件控制文本的样式,其中包括增强文本、下划线和反转终端打印等属性。控制顺序如下:

  • [0m:此将删除所有格式并打印普通文本。我们将使用此选项重置终端文本的所有属性。它作为一个控件来限制我们希望对其前面的任何格式产生影响的文本量。

  • [1m: This will embolden any text following it. For instance, consider the following command line:

    echo –e "Kali Linux  + the bash shell is so \e[1m Epic \e[0m"
    

    上一个命令行将在终端屏幕上提供以下输出:

    Formatting the terminal output

  • [2m: This will dim the text being printed, following is a demonstration:

    echo –e "Other operating system are so \e[2m dim \e[0m"
    
    

    以下是输出的外观:

    Formatting the terminal output

  • [4m:此将在其后的任何文本下划线。

  • [5m:在某些终端上,这将导致其后面的文本闪烁开和关。

  • [7m: This causes the video or colors following it to be inverted. Consider the following example:

    echo –e "White on black \e[7mBlack on White \e[0m"
    
    

    上一个命令行将在终端屏幕上提供以下输出:

    Formatting the terminal output

  • [8m:这将隐藏它后面的任何文本,这意味着该文本根本不会被打印。

请不要忘记,只有在前面有\e转义字符的情况下,这些控制序列才起作用。编写此转义字符的另一种方法是使用八进制格式\033,这在一些旧版本的 bash 终端上是受支持的。

这些控制序列的另一个有用功能是可以重置给定属性。例如,如果在一段文本上加下划线并加壮胆,并且只希望删除给定文本部分的下划线,则可以按以下示例所示执行此操作:

echo –e "\e[1;4m Underlined and Emboldened \e[24m Only Emboldened \e[0m"

上述命令应在终端上打印以下文本:

Formatting the terminal output

不难理解这些重置转义序列的其余部分是如何工作的;如果要关闭给定的格式规则,只需在控件编号前面加上一个2,如下所示:

  • [21m壮胆轮番
  • [22m关闭调光
  • [25m关闭闪烁

等等等等。

我们还没完呢!您还可以使用其他控制序列控制正在打印的文本的颜色。就像重置控制序列一样,它们的工作原理是将一个控制颜色种类的给定数字前缀为另一个控制所选颜色的数字。以下是它们的工作原理:

  • [3xm只需将文本更改为数字x索引的颜色。编号x可以是以下任意一种:
    • 0黑色
    • 1红色
    • 2绿色
    • 3为黄色
    • 4蓝色
    • 5品红
    • 6青色
    • 7用于浅灰色

考虑下面的例子:

echo –e "\033[31m Red Red Red \033[0m"
echo –e "\033[32m Green Green Green \033[0m"
echo –e "\033[34m Blue \033[31m Red \033[36m Cyan \033[0m"

您还可以将这些选项与其他格式选项结合使用,如下所示:

echo –e "\033[1;31 Bold-Red \033[21m \033[3;36m Underlined Cyan \033[0m"

提示字符串

提示字符串是标记或分隔 bash 命令行的字符串。Kali Linux 的默认提示字符串为root@kali:#。此字符串不是静态值,可以更改为任何您希望的值。本节将介绍您可以对提示字符串进行的一些非常有用的修改。我们将让它显示一些关于 Linux 系统的有用信息。

要控制显示为提示字符串的值,需要修改 PS1 变量的值,如以下屏幕截图所示:

The prompt string

因此,您可能想知道何时以及如何为 bash 终端设置此值。事实证明,~/.bashrc文件中设置了提示字符串,通常在终端启动后立即执行。以下是.bashrc文件中提到提示字符串的部分:

if [ "$color_prompt" = yes ]; then
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\n\$'
else
 PS1='${debian_chroot:+($debian_chroot)}{\j}\u@[\w]\n\$'
fi
unset color_prompt force_color_prompt

# If this is an xterm set the title to user@host:dir
case "$TERM" in
xterm*|rxvt*)
 PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: [\w]\a\]\n$PS1"
    ;;
*)
    ;;
esac

提示

下载示例代码

您可以下载您在[账户购买的所有 Packt 书籍的示例代码文件 http://www.packtpub.com](http:// http://www.packtpub.com) 。如果您在其他地方购买了本书,您可以访问http://www.packtpub.com/support 并注册,将文件直接通过电子邮件发送给您。

在前面的代码中,我们可以看到提示字符串有三种可能的设置,以便您的终端能够适应彩色打印,尽管它需要确保实际的 shell 能够支持它。这就是为什么它首先检查color_prompt变量是否被确定设置的原因。让我们使用以下代码详细了解第一个可能的PS1设置(应支持彩色打印):

PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\n\$'

前面的代码工作如下:

代码的${debian_chroot:+($debian_chroot)}部分使用变量扩展来获取有关 shell 是否在 chrooted 文件系统上执行的详细信息,并显示指示这一点的信息。现在理解这一点还不完全重要,因为在大多数情况下,你可能永远不会利用这一点。

如前一节所述,\[\033[01;32m\]部分使终端打印粗体绿色文本。这里的格式与上一节中讨论的示例略有不同,因为转义括号用于划分控制序列的开始和结束。正如我们在前面的示例中所看到的,对于以后的 bashshell 版本来说,这并不是一个硬性要求。

\u部分是另一个非常有用的转义字符。这是您的用户名或当前用户的用户名的简写。

这个转义字符的\h部分跟在@符号后面,在这个例子中@符号只是纯文本,没有什么特别之处。显示提示字符串时,\h转义字符将在其位置打印当前主机名。

前一节讨论的\[\033[00m\]部分。这将重置所有格式规则,以便随后的所有内容都作为普通文本打印。重置格式后,我们看到\[\033[01;34m\]。这将格式化它前面的所有文本,使其以蓝色显示。

\w部分是当前工作目录的简写。直接在工作目录之后是一个很好的旧换行符,使用\n转义字符速记打印。下面是\$转义字符,这是一种速记,如果根用户之外的任何人当前正在使用 shell,则会打印一个$符号,当根用户登录时,会打印一个#

bashshell 提供了一些其他有用的速记,可以在提示字符串中使用,每种速记都会直接将不同的信息打印到提示字符串中。欲了解更多信息,请参阅本章进一步阅读部分提供的链接。

提示字符串自定义

既然您已经了解了文本格式和编辑提示字符串的一般过程,那么让我们来了解一些有用的自定义设置。

您应该将提示字符串视为应该为您提供一般信息的东西,这些信息在大多数情况下都会很有用。为了让您能够修改自己的提示字符串,我们将讨论如何在终端提示中整齐地显示这些信息。

我们可以添加如下信息:

  • 使用\w转义符返回当前工作目录
  • 通过使用 date 命令和少量命令替换来显示当前日期时间
  • 使用\j转义字符在后台运行的作业数
  • 当前用户使用\$转义字符的权限级别
  • 使用\$?转义字符返回上一个命令的返回码

以下是添加这些详细信息后提示字符串的外观:

PS1="\e[33m{$(date)}\e[0m\e[1;36m[\j]\e[0m\e[1;32m<$?>\e[0m\e[2;36m(\u\e[0m@\e[1;34m\w)\e[0m\n\$>"

如果仔细观察,应该会看到提示字符串中使用了我们提到的所有转义字符。如果一切顺利,并且您成功地设置了与示例中完全相同的提示字符串,您应该会在终端屏幕上看到以下代码:

Prompt string customizations

在前面的截图中,我们可以看到\$?逃逸角色的动作。用户访问一个不存在的目录,返回码设置为1,表示之前的命令在错误条件下退出或未成功。

您可以进行许多出色的修改。这里演示的内容仅作为一个示例(尽管它本身很有用),目的是让您尝试自己的修改。请参阅进一步阅读部分,了解您可以对提示字符串进行的更强大、更令人眼花缭乱的修改。

别名

别名是一种有效地将名称分配给给定命令集合或单个命令行的方法。每个标准问题 bashshell 附带的.bashrc文件默认包含一些有用的文件。其中有几项是:

# enable color support of ls and also add handy aliases
if [ -x /usr/bin/dircolors ]; then
    test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
    alias ls='ls --color=auto'
    #alias dir='dir --color=auto'
    #alias vdir='vdir --color=auto'

    alias grep='grep --color=auto'
    alias fgrep='fgrep --color=auto'
    alias egrep='egrep --color=auto'
fi

# some more ls aliases
alias ll='ls -alF'
alias la='ls -A'

它们允许您使用一个通常更简单的命令来调用许多复杂的命令。因此,对于前面的代码,您可以使用grep调用grep –-color=auto,这将启用文本输出高亮显示或彩色打印。

别名的一般用途或目的是使事情更简单。因此,例如,如果您需要经常 SSH 到某个给定主机,并且希望避免重复输入该主机的 IP 地址或域名,您可以在您的.bashrc中添加一个别名,如下所示:

alias ssh2wserver='ssh  -v root@192.168.10.34'

另一个例子是,如果你与开膛手约翰一起练习密码破解,你想经常使用给定的密码和破解模式;您可以添加这些别名,使以所需方式调用john变得不那么繁琐:

alias john-mysql='john –-format=mysql-fast '

否则,如果您想使用特定的单词列表,也可以使用它们,例如:

alias john-winwlist='john  --wordlist=windows-commons.txt'

您应该立即看到依赖alias简化某些复杂命令的触发的好处。

自定义命令历史记录

通常,在渗透测试期间,或者当您使用一些相当长的命令行来完成任务时,您可能希望经常重用这些命令行或召回它们以备将来使用。确保终端记录了有关命令的正确详细信息,更重要的是记录了足够的命令,这是一项重要的修改。

与讨论的其他主题一样,当然有一个主页专门用于定制命令历史行为。您可以通过执行以下命令来访问此手册页:

man bash 

查找提到HISTORY变量及其相关变量的部分。

当然,与 bash 终端的大多数其他组件和功能一样,在命令日志记录方面,您有很大的发言权。控制记录内容和方式的这些环境变量讨论如下:

  • HISTSIZE:此控制初始化为历史记录的命令数量。
  • HISTFILE:此指定初始化命令历史时应使用哪个文件。
  • HISTFILEZIE:此指定HISTFILE中的命令应该用于初始化命令历史记录的数量。如果HISTFILEHISTFILESIZE行长,则会被截断。
  • HISTCONTROL:此确定了某个命令的某些属性,例如:
    • 如果设置为ignorespace,它将忽略(而不是记录到历史记录中)所有以空格开头的命令,例如:

       HISTCONTROL=ignorepsace
      
      
    • 如果设置为ignoredups,bash 将不会记录任何与前一个命令具有相同调用的命令

    • If set to erasedups, bash will completely erase any duplicate commands throughout the entire history

      您还可以通过使用冒号分隔来组合不同的选项,例如:

       HISTCONTROL=ignoredups:ignorespaces
      
      

尝试在.bashrc文件末尾添加一些您自己的设置,以便在启动终端时自动应用。

保护敏感信息不被泄露

.bash_history文件是保存所有命令的地方。通常,位于您的主文件夹的根目录中;对于 Kali Linux 用户,这是/root文件夹。关于这个文件需要记住的一件重要事情是,它可能包含终端使用期间在机器上执行的所有命令。这意味着,如果您在命令行中输入了任何敏感信息,例如密码、用户名或任何重要和敏感信息,则该文件将包含它。

最好确保这些信息不被复制,并且始终保存在与其保护相关的位置,即需要与所保护的资源相同的工作量或知识才能泄露或访问的位置。例如,如果您需要保护网站的密码,那么未经授权的一方访问保护该密码的存储应该与实际使用该密码的网站一样困难。在信息安全行业,如果不是这样,我们会说存储不安全或不充分。

为了确保不将任何敏感信息保存到命令行,可能需要将敏感信息卸载到更安全的位置,并在必要时将其包含在 bash 环境中。执行以下步骤以执行此操作:

  1. 为敏感环境变量创建一个文件。在这里,我们将调用我们的sens_env.sh,如下命令所示:

    touch sens_env.sh
    
    
  2. 将其保存在安全位置,并尽可能加密。尝试使用TrueCrypt进行此操作,有关使用TrueCrypt的信息,请参阅进一步阅读部分。

  3. 针对需要安全保存的每个用户名、密码或安全凭据,在此文件中输入以下命令:

    SITE_USERNAME=foofoo
    SITE_PASSWORD=barbar
    
    
  4. Each time you need to use the information saved in this file, all you need to do is decrypt, unzip, or access it anyway you are required to, and then execute the following command:

    . sens_env.sh
    
    

    这将执行这些命令,而不会将敏感信息暴露到您的.bash_history文件中。

您可以通过将这些信息替换为用于引用这些信息的变量来使用这些信息,例如,如以下命令所示:

echo "the site password is : $SITE_USERNAME"

这样,只有执行的命令才会保存在历史记录中,它不会包含实际的用户名,而是包含用于引用它的变量。

另一个需要记住的重要事项是,如果您需要在.bash_history文件中保存敏感信息,或者出于任何其他原因想要备份或复制.bash_history文件,您可以通过执行以下命令来执行此操作:

history –w [FILENAME]

历史记录命令允许您发出影响历史记录文件的命令。这里,我们使用的是–w switch,它告诉它将当前内容的副本保存到[FILENAME]参数指定的文件中。

命令历史就是这样。更多信息请参见进一步阅读部分。

定制页签完成

Tab completion 是当您键入命令并按键盘上的Tab键两次时发生的情况。显示的可能选项列表是完成建议。信不信由你,你实际上可以控制命令,甚至是使用制表符完成时显示的参数,这取决于你正在执行的命令。在 bash 的日常体验中,能够控制制表符的完成是一项非常宝贵的技能。因此,我们不必太长时间地讨论这个问题,我们来了解一下 tab 补全实际上是如何工作的。

当您按两次Tab键时,bash shell 将执行一个特殊的预定义函数。此函数确定您正在执行的命令(如果有的话),并将另一个定义的函数(这只是计划的行话)挂钩,该函数负责确定哪些选项显示为建议。在本节中,我们将实际利用其中一个或两个功能,以使 Kali bash 命令行上的一些工具更加用户友好,并再次设计另一种方法,将更多有用的信息放在您的指尖。

以下是一个完成函数的示例(此函数用于tcpdump

_tcpdump()
{
    local cur prev

    COMPREPLY=()
    cur=`_get_cword`
    prev=${COMP_WORDS[COMP_CWORD-1]}

    case "$prev" in
        -@(r|w|F))
            _filedir
            return 0
            ;;
        -i)
            _available_interfaces -a
            return 0
            ;;
    esac

    if [[ "$cur" == -* ]]; then
        COMPREPLY=( $( compgen -W '-a -d -e -f -l -n -N -O -p \
            -q -R -S -t -u -v -x -C -F -i -m -r -s -T -w -E' -- "$cur" ) )
    fi

} &&
complete -F _tcpdump tcpdump

在上一个例子中,有几点需要注意。首先,正在定义的_tcpdump函数是在命令行中键入tcpdump后按TAB两次时将被调用的函数。这是因为上一个示例中的最后一行:

complete -F _tcpdump tcpdump

这表示在确定tcpdump的完成建议时,–F选项指定要调用的函数是_tcpdump。完成函数的唯一目的是用完成命令所需的建议填充COMPREPLY环境变量。当您需要建议时,COMPREPLY变量会卡在命令行中。还有许多其他非常有用的环境变量,旨在帮助您编写完成函数的脚本。详情如下:

  • COMP_LINE,当前命令行。

  • COMP_WORDS,它是一个数组,包含当前出现在命令行上的单个单词。

  • COMP_CWORD,输入命令行的最后一个单词的索引。此索引用于使用COMP_WORDS数组计算当前单词,如下所示:

    ${COMP_WORDS[$COMP_CWORD]}
    
    

因此,基本上,当你为一个给定的命令利用一个完成函数时,你玩的游戏是检查最后输入的单词,或者检查输入的任何单词,以确定要放入COMPREPLY数组的确切内容。当然,这只是一个正在执行的 bash 脚本。如果您想确定以另一种方式显示的建议,当然可以这样做。例如,您可以使用history命令将给定命令的所有调用记录到一个特殊文件中,然后根据提供的选项建议执行host common命令。如果您对自然语言处理或机器学习稍有了解,那么这个简单功能的应用将变得无穷无尽。例如,设想一个 bash 终端,它学习在一天中的某个特定时间建议您最喜欢的命令,即使是根据您正在听的音乐或您机器上当前活动的网络连接。

利用自己的完成函数可能需要的另一个重要信息是,完成后将函数粘贴到何处。当前安装在您系统上的大多数完成功能出现在/etc/bash_completion.d/处。但是,如果您要利用自己的完成系统扩展,您可能希望将脚本放在您可以控制的地方。常用的惯例是使用以下命令在home文件夹的根目录中创建一个名为.bash_completion.d/的目录:

mkdir ~/.bash_completion.d/

您自己的所有完成脚本都应显示在此文件夹中,并保存在与其完成的命令对应的名称下。例如,我们将为 John 利用的一个裂土器在命令行上指定为john,称为john。此外,为了使完成函数生效,您可能希望避免在使用任何受影响的命令之前自己执行它们。因此,为了使此操作变得简单和自主,您应该将此命令粘贴到您的.bashrc文件中,如下所示:

echo ". ~/.bash_completion.d/*" >> ~/.bashrc

执行上述命令后,您可能希望使用以下命令行代码解压缩 Kali Linux 安装附带的rockyou.txt.gz字列表:

cd /usr/share/wordlists
gunzip rockyou.txt.gz

您现在可以为john编写一个完成函数了。下面是它应该是什么样子

(以下代码将在本书网站上提供):

_john()
{
  local cur=${COMP_WORDS[COMP_CWORD]}
  local prev=${COMP_WORDS[COMP_CWORD-1]}
  case "$prev" in
    --format)
      COMPREPLY=($( compgen -W "bsdi md5 bf afs lm dynamic_n bfegg dmd5 dominosec epi hdaa ipb2 krb4 krb5 mschapv2 netlm netlmv2 netntlm netntlmv2 nethalflm md5ns nt phps po xsha crc32 gost keychain lotus5 md4-gen mediawiki mscash mscash2 mskrb5 mssql mssql05 mysql-sha1 mysql nsldap nt2 odf office oracle11 oracle osc phpass pix-md5 pkzip racf raw-md4 raw-md5 raw-sha1 raw-sha1-linkedin raw-md5u salted-sha1 sapb sapg sha1-gen sip vnc wbb3 hmac-md5 hmac-sha1 raw-sha raw-sha224 raw-sha256 raw-sha384 raw-sha512 hmac-sha224 hmac-sha256 hmac-sha384 hmac-sha512 xsha512 hmailserver sybasease dragonfly3-64 dragonfly4-64 dragonfly3-32 dragonfly4-32 drupal7 sha256crypt sha512crypt episerver keepass pwsafe django raw-sha1-ng crypt trip ssh pdf wpapsk rar zip dummy" -- $cur))
    return 0
    ;;
    --wordlist)
      COMPREPLY=($( compgen -W "`ls /usr/share/wordlists`" --$cur))
    return 0
    ;;
  esac
  if [[ "$cur" == -* ]]; then
    COMPREPLY=($( compgen -W "-i -s -u -w --shell --user --show --format --wordlist --incremental" -- $cur))
  fi
}
complete -F _john john

在函数的前几行中,脚本获取当前单词和前一个单词—当前单词前面的单词,然后分别存储在curprev变量中。然后,它所做的是逐步进入一个 case 语句,它基本上是一个复合 if 语句,具有许多比较和许多唯一的逻辑出口点,并将单词与以下字符串进行比较:

  • --format:这是裂土器用来指定被破解的密码格式的选项。脚本使用与当前单词$cur名称相似的所有格式填充COMPREPLY数组。
  • --wordlist:这是开膛手 John 用来指定要使用的单词(如果有)的选项。在这里,脚本只需获取/usr/share/wordlists目录中的所有文件,并将它们用作要返回的建议。

后面是一个if语句,用于匹配输入到命令行中的任何选项,该命令行可以是以连字符开头的任何选项。然后,它用与当前数组足够接近的匹配项填充COMPREPLY数组。

请注意,此脚本仅用于演示;john的其他命令行参数缺少完成建议。作为练习,您可以通过在switch语句中添加一些事例来填写 John the Ripper 的其余命令行选项和这些函数的可能参数。您可以从手册页面或通过执行man john了解更多关于开膛手约翰的论点。

另一个非常有用的应用程序是 Metasploit 命令行界面。我们将在后面的章节中介绍这些工具,您可能会发现为它们编写一组制表符完成规则非常有用。

总结

在本章中,我们介绍了文本输出格式化和终端文本着色。然后,我们了解了如何使用文本格式来修改 bash 提示字符串,并讨论了使用prompt字符串显示一些有用信息的新技巧和技巧。然后,我们讨论了别名,并讨论了通过使用简单的助记符别名使一些复杂而繁琐的命令变得更简单。最后,我们讨论了 tab 完成,并学习了如何修改它以满足我们的需要。我们还讨论了一个涉及 John the Ripper 密码和散列破解工具的示例。

希望您已经从本章中学习了一些有用的技巧,能够对终端进行非常必要和有效的修改,以便在渗透测试期间有效地使用它。一个很好的练习是查看安装在 Kali-Linux 命令行上的一些工具,并考虑如何通过使用本章中介绍的一两个技巧使它们更容易、更高效地使用。例如,考虑一些有用的别名、制表符完成脚本和文本格式技巧,以便与命令 Nmap、Wireshark、airrack NG 或 Netcat 一起使用。

下一章将重点介绍如何使用一些 Kali Linux 工具来确保您的数据,特别是来自渗透测试和敏感信息安全相关工作的证据,始终受到保护。

进一步阅读