freeBuf
主站

分类

云安全 AI安全 开发安全 终端安全 数据安全 Web安全 基础安全 企业安全 关基安全 移动安全 系统安全 其他安全

特色

热点 工具 漏洞 人物志 活动 安全招聘 攻防演练 政策法规

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

lynis插件编写:从入门到放弃
2018-09-18 08:30:23

*本文作者:nancce,本文属 FreeBuf 原创奖励计划,未经许可禁止转载。

前言

lynis是一款采用shell脚本编写,适用于Linux,macOS和基于UNIX的系统的安全审核工具,相信小伙伴们在网上搜索lynis会有很多介绍lynis如何使用的文章,但是关于lynis插件编写的文章却很少,本文就来讨论下lynis的插件编写。

lynis-.jpg

lynis的使用也很是简单方便,一般来说我们使用以下的命令就可以了:

cd lynis; ./lynis audit system

除了使用lynis默认的规则来加固linux之外,lynis还提供了插件的功能,通过自己编写插件,我们可以把lynis改装成一款linux提权信息的收集器,或者将其改装成恶意程序的检测工具,本文我们将先介绍编写lynis插件的语法,然后基于lynis编写一个linux提权信息收集插件,希望通过这个案例可以启发小伙伴们开发出更精彩的插件。

插件介绍

脚本语言

Lynis采用shell脚本编写的,这是一种多功能脚本语言,可在在Linux或基于UNIX的操作系统的所有系统上运行。

Lynis执行步骤

我们先看看lynis完整的运行周期如下:

[Initialization] → [OS detection] → [Detection of binaries] → [Plugins phase 1] → [Built-in tests] → [Custom tests] → [Plugins phase 2] → [Report]

可以发现,在lynis中有两个阶段可以去运行插件,它们分别是Plugins phase 1,Plugins phase 2。

lynis SDK

lynis同时也提供lynis SDK的开发方式及下载。

开发步骤

第一步:找到插件目录

第一步是就了解Lynis的安装位置,特别是您的插件存储的目录。当运行Lynis时,插件目录就会显示在屏幕上,并存储在日志文件中(通常为/var/log/lynis.log),所以我们可以通过下面的命令来查看插件的目录文章:

grep -i plugin /var/log/lynis.log

第二步:决定加载插件的阶段

第一阶段

在第一阶段运行的插件将在内置测试之前执行。此阶段非常适合仅收集数据的测试。这有可能是获取已安装的软件包列表或系统上运行的进程。

第二阶段

插件的第二阶段发生在正常测试结束时。这是你希望分析先前发现的信息,处理它并可选择在屏幕上显示的时候。

提示:如果您是第一次创建插件,请使用第二阶段。这样你就可以使所有测试数据可用的同时向屏幕输出,因为它在审计周期最后阶段执行。

第三步:创建插件文件

在plugins目录,将customplugin.template文件复制到plugin [name] _phase [number]文件中。

Plugin Name and Phase

[name]的值应替换为插件的唯一名称。仅使用小写字符,数字和(可选)短划线( - )来链接两个单词。 [number]用以定义插件阶段,即1或2。

例如name的取值可为:companyname, custom-tests, iso27001, personal

命令:

cp custom_plugin.template plugin_custom-tests_phase2

第四步:配置插件

修改文件标题

对此文件的第一次调整就是修改标题。这些细节用于插件的部分说明,用于验证插件的正确格式。

#########################################################################
#
#    * DO NOT REMOVE *
#-----------------------------------------------------
# PLUGIN_AUTHOR=Mr Auditor <auditor@company.example.org>
# PLUGIN_CATEGORY=Custom
# PLUGIN_DESC=This are my custom tests
# PLUGIN_NAME=custom-tests
# PLUGIN_REQUIRED_TESTS=
#-----------------------------------------------------
#########################################################################

PLUGIN_AUTHOR: 作者字段定义谁负责创建和更新此文件。

PLUGIN_CATEGORY: 这个字段描述了此插件所属的测试类型(例如,network)。可以使用“custom”。

PLUGIN_DESC: 描述字段,带有可选的解释,说明为什么创建此插件及其目标。

PLUGIN_NAME: 应该和你用作文件名的名称相同。

PLUGIN_REQUIRED_TESTS: 描述在执行该插件之前应该已经执行的依赖检测。通常可以跳过。

Tips:

检查是否正确定义了PLUGIN_NAME字段。

保留#符号,只更改每行的值。

第五步:创建插件

每个插件都包含一个或多个单独的检测单元。它们标有唯一的ID,以便正确的记录和存储测试结果。出于同样的原因,您创建的所有测试都应以“CUST-”开头,然后是四个数字(例如CUST-0010)。

检测单元使用通用的shell脚本语言创建。为了简化操作,lynis预先实现了几个函数(include / functions)。示例包括向屏幕,日志文件或报告文件添加文本。它还包括用于检查权限的检测等。

基础的函数:

Display: 向屏幕输出、打印

LogText: 向log文件中输出

Register: 测试单元队列执行

Report: 向report中输出

检测流程:

设置可选的先决条件;

注册检测(注册功能)。然后Lynis将检查是否需要执行或跳过;

检查注册功能的状态(if [ ${SKIPTEST} -eq 0 ]; then);

运行检测代码5、关闭检测(fi)。

可以在include/tests_custom.template文件中看到测试和函数的一些示例。另一个很好的资源是Lynis中的常规检测,也可以在include目录中找到。

第六步:运行lynis

在运行lynis之后,插件会被载入。

常见问题

如果,插件没有被激活,请按检查以下的项目:

在profile(.prf)中是否被开启;

插件名和插件代码中是否一致;

插件文件是否有权限。

日志文件(/var/log/lynis.log)中也将记录忽略该插件的原因。

linux提权信息收集插件

如何运行插件

虽然在上面的章节中我们介绍了在运行lynis后,插件会被载入,但是这样的话会在运行我们的插件的同时运行lynis自带的插件和很多其他的信息收集脚本,所以lynis提供了一种单独运行插件的选项--tests。

./lynis audit system --tests CUST-id1,CUST-id2

这里的id就是编写插件时自定义的独一无二的值

确认收集什么信息

目前该插件已经完成收集的信息有:

判断/etc/passwd中是否有hash的password,如果有提取出来后续可以使用hashcat等破解(插件id:PASS-0001,plugin_check_passwd_shadow_phase2);

判断/etc/shadow文件root之外的用户是否有权限读取,如果有提取出来后续可以使用hashcat等破解(插件id:PASS-0002,plugin_check_passwd_shadow_phase2);

判断/etc/passwd文件root之外的用户是否有写入的权限,可以直接修改密码(插件id:PASS-0003,plugin_check_passwd_shadow_phase2);

检测当前用户可以执行并且可被用以提权的程序(插件id:PWN-0001,plugin_check_pwnable_binary_phase2);

发现隐藏文件(插件id:HIDDEN-0001,plugin_check_hidden_file_phase2);

发现suid文件,经典提权(插件id:SUID-0001,plugin_check_suid_file_phase2);

检测是否有docker用户组并列出其中的用户(插件id:GROUP-0001,plugin_check_docker_group_phase2)。

目前收集的信息还是比较少的,后续会逐步的添加。

实战Lin.security

首先,简单介绍下插件的内容,定义检查/etc/passwd文件中是否有密文的函数:

check_password_hashes() {
    # define some constant
    IFS_OLD=$IFS
    IFS=$'\n'
    ENCRYPTEDPASS='x' 
    #start
    LogText "Test:obtain /etc/passwd file content"
    passwd_content=$(${AWKBINARY} '{print $0}' /etc/passwd)
    for each_passwd in ${passwd_content};
    do
        IFS=':'
        passwd_split_colon=($each_passwd)
        if [ "${passwd_split_colon[1]}" != "$ENCRYPTEDPASS" ];then
            IFS=$'\n'
            Report "sensetive_passwd_hashes[]=$each_passwd"
        fi
    done
    IFS=$IFS_OLD
}

然后在注册代码块里调用该函数在插件加载时运行:

#################################################################################
#
    # Test        : PASS-0001
    # Description : We show some lines on the screen

    # Register our first custom test
    # We consider it to be a lightweight test (no heavy IO, or long searches), no network connection needed
    Register --test-no PASS-0001 --weight L --network NO --description "A test for check if there is password hashess stored in /etc/passwd"
    if [ ${SKIPTEST} -eq 0 ]; then
        # The Display function makes it easy to show something on screen, with colors.
        # --indent  defines amount of spaces
        # --text    text to be displayed on screen
        # --result  text at end of line
        # --color   color of result text
        Display --indent 2 --text "- Checking if there is a password hashes on /etc/passwd file" --result OK --color GREEN
        check_password_hashes;
    fi
#

运行命令:

./lynis audit system --tests PASS-0001

查看收集结果的报告:

cat /var/log/lynis-report.dat | grep sensetive_passwd_hashes

Lin.security是一款提权练习的虚拟机,通过模拟真实漏洞,将帮助您完善本地权限提升技能,技术和工具集。

通过bob/secret登入到Lin.security中,ifconfig查看虚拟机的ip:

bob@linsecurity:~/lynis-master/plugins$ ifconfig
docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:8a:eb:21:07  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.137.196  netmask 255.255.255.0  broadcast 192.168.137.255
        inet6 fe80::a00:27ff:fed8:9fd6  prefixlen 64  scopeid 0x20<link>
        ether 08:00:27:d8:9f:d6  txqueuelen 1000  (Ethernet)
        RX packets 180  bytes 18259 (18.2 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 753  bytes 69400 (69.4 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 373  bytes 27495 (27.4 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 373  bytes 27495 (27.4 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

将插件拷贝进虚拟机plugins目录下:

scp plugin_check_* bob@192.168.137.196:/home/bob/lynis-master/plugins/
bob@192.168.137.196's password: 
plugin_check_docker_group_phase2              100% 3858   899.2KB/s   00:00    
plugin_check_hidden_file_phase2               100% 3628     3.7MB/s   00:00    
plugin_check_passwd_shadow_phase2             100% 5010     6.4MB/s   00:00    
plugin_check_pwnable_binary_phase2            100% 4970     6.5MB/s   00:00    
plugin_check_suid_file_phase2                 100% 3578     3.7MB/s   00:00

记得将default.prf也拷贝进去,覆盖原来的配置:

scp default.prf bob@192.168.137.196:/home/bob/lynis-master/
bob@192.168.137.196's password: 
default.prf                                   100%   20KB   6.7MB/s   00:00

运行lynis:

bob@linsecurity:~/lynis-master$ bash lynis audit system

查看插件收集到的信息:

cat /tmp/lynis-report.dat | grep -E 'suid_file|pwnable_programs|sensetive_passwd_hashes|hidden_file|docker_group'

plugin_enabled_phase2[]=check_hidden_file||
hidden_file[]=/snap/core/4917/etc/.pwd.lock
hidden_file[]=/snap/core/4917/etc/cron.d/.placeholder
hidden_file[]=/snap/core/4917/etc/cron.daily/.placeholder
hidden_file[]=/snap/core/4917/etc/cron.hourly/.placeholder
hidden_file[]=/snap/core/4917/etc/cron.monthly/.placeholder
hidden_file[]=/snap/core/4917/etc/cron.weekly/.placeholder
hidden_file[]=/snap/core/4917/etc/init.d/.depend.boot
hidden_file[]=/snap/core/4917/etc/init.d/.depend.start
hidden_file[]=/snap/core/4917/etc/init.d/.depend.stop
hidden_file[]=/snap/core/4917/etc/skel/.bash_logout
hidden_file[]=/snap/core/4917/etc/skel/.bashrc
hidden_file[]=/snap/core/4917/etc/skel/.profile
hidden_file[]=/snap/core/4917/var/lib/apparmor/profiles/.apparmor.md5sums
hidden_file[]=/snap/core/4486/etc/.pwd.lock
hidden_file[]=/snap/core/4486/etc/cron.d/.placeholder
hidden_file[]=/snap/core/4486/etc/cron.daily/.placeholder
hidden_file[]=/snap/core/4486/etc/cron.hourly/.placeholder
hidden_file[]=/snap/core/4486/etc/cron.monthly/.placeholder
hidden_file[]=/snap/core/4486/etc/cron.weekly/.placeholder
hidden_file[]=/snap/core/4486/etc/init.d/.depend.boot
hidden_file[]=/snap/core/4486/etc/init.d/.depend.start
hidden_file[]=/snap/core/4486/etc/init.d/.depend.stop
hidden_file[]=/snap/core/4486/etc/skel/.bash_logout
hidden_file[]=/snap/core/4486/etc/skel/.bashrc
hidden_file[]=/snap/core/4486/etc/skel/.profile
hidden_file[]=/snap/core/4486/var/lib/apparmor/profiles/.apparmor.md5sums
hidden_file[]=/snap/core/5328/etc/.pwd.lock
hidden_file[]=/snap/core/5328/etc/cron.d/.placeholder
...

我们可以聚焦于最简便的pwnable_program部分:

pwnable_programs[]=/bin/ash (For more details, visit:https://gtfobins.github.io/gtfobins/ash)
pwnable_programs[]=/usr/bin/awk (For more details, visit:https://gtfobins.github.io/gtfobins/awk)
pwnable_programs[]=/bin/bash (For more details, visit:https://gtfobins.github.io/gtfobins/bash)
pwnable_programs[]=/bin/csh (For more details, visit:https://gtfobins.github.io/gtfobins/csh)
pwnable_programs[]=/usr/bin/curl (For more details, visit:https://gtfobins.github.io/gtfobins/curl)
pwnable_programs[]=/bin/dash (For more details, visit:https://gtfobins.github.io/gtfobins/dash)
pwnable_programs[]=/bin/ed (For more details, visit:https://gtfobins.github.io/gtfobins/ed)
pwnable_programs[]=/usr/bin/env (For more details, visit:https://gtfobins.github.io/gtfobins/env)
pwnable_programs[]=/usr/bin/expect (For more details, visit:https://gtfobins.github.io/gtfobins/expect)
pwnable_programs[]=/usr/bin/find (For more details, visit:https://gtfobins.github.io/gtfobins/find)
pwnable_programs[]=/usr/bin/ftp (For more details, visit:https://gtfobins.github.io/gtfobins/ftp)
pwnable_programs[]=/usr/bin/less (For more details, visit:https://gtfobins.github.io/gtfobins/less)
pwnable_programs[]=/usr/bin/man (For more details, visit:https://gtfobins.github.io/gtfobins/man)
pwnable_programs[]=/bin/more (For more details, visit:https://gtfobins.github.io/gtfobins/more)
pwnable_programs[]=/usr/bin/scp (For more details, visit:https://gtfobins.github.io/gtfobins/scp)
pwnable_programs[]=/usr/bin/socat (For more details, visit:https://gtfobins.github.io/gtfobins/socat)
pwnable_programs[]=/usr/bin/ssh (For more details, visit:https://gtfobins.github.io/gtfobins/ssh)
pwnable_programs[]=/usr/bin/vi (For more details, visit:https://gtfobins.github.io/gtfobins/vi)
pwnable_programs[]=/usr/bin/zsh (For more details, visit:https://gtfobins.github.io/gtfobins/zsh)
pwnable_programs[]=/usr/bin/pico (For more details, visit:https://gtfobins.github.io/gtfobins/pico)
pwnable_programs[]=/usr/bin/perl (For more details, visit:https://gtfobins.github.io/gtfobins/perl)
pwnable_programs[]=/usr/bin/tclsh (For more details, visit:https://gtfobins.github.io/gtfobins/tclsh)
pwnable_programs[]=/usr/bin/git (For more details, visit:https://gtfobins.github.io/gtfobins/git)
pwnable_programs[]=/usr/bin/scp (For more details, visit:https://gtfobins.github.io/gtfobins/scp)

访问链接https://gtfobins.github.io/gtfobins/awk/,用以下命令提权:

bob@linsecurity:~/lynis-master$ sudo awk 'BEGIN {system("/bin/sh")}'
# id
uid=0(root) gid=0(root) groups=0(root)

当然,可以使用插件发现的其他信息进行提权

结语

本文总结了一下lynis的插件编写的过程,借助lynis我们可以开发出各种用途的lynis插件包括但不局限于攻击溯源,提权信息收集等等,希望可以给小伙伴以启发开发出更多提高工作效率的插件

完整的代码:https://github.com/nancheal/lynis-plugins,欢迎点star~

*本文作者:nancce,本文属 FreeBuf 原创奖励计划,未经许可禁止转载。

# Lynis # lynis插件
免责声明
1.一般免责声明:本文所提供的技术信息仅供参考,不构成任何专业建议。读者应根据自身情况谨慎使用且应遵守《中华人民共和国网络安全法》,作者及发布平台不对因使用本文信息而导致的任何直接或间接责任或损失负责。
2. 适用性声明:文中技术内容可能不适用于所有情况或系统,在实际应用前请充分测试和评估。若因使用不当造成的任何问题,相关方不承担责任。
3. 更新声明:技术发展迅速,文章内容可能存在滞后性。读者需自行判断信息的时效性,因依据过时内容产生的后果,作者及发布平台不承担责任。
本文为 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
  • 0 文章数
  • 0 关注者
文章目录