osquery初識
ofollow,noindex">osquery 是一個由FaceBook開源用於對系統進行查詢、監控以及分析的一款軟體。osquery對其的說明如下:
osquery exposes an operating system as a high-performance relational database. This allows you to write SQL-based queries to explore operating system data. With osquery, SQL tables represent abstract concepts such as running processes, loaded kernel modules, open network connections, browser plugins, hardware events or file hashes.
我們知道當你們在Linux中使用諸如ps
、top
、ls -l
等等命令的時候,可以發下其實他們的輸出結果的格式都是很固定的很像一張表。或許是基於這樣的想法,facebook開發了osquery
。osquery
將作業系統當作是一個高效能的關係型資料庫。使用osquery
執行我們能夠使用類似於SQL語句的方式去查詢資料庫中的資訊,比如正在執行的程序資訊,載入的核心模組,網路連線,瀏覽器外掛等等資訊(一切查詢的資訊的粒度取決於osquery
的實現粒度了)。
osquery
也廣泛地支援多個平臺,包括MacOS
、CentOS
、Ubuntu
、Windows 10
以及FreeBSD
,具體所支援的版本的資訊也可以在osquery主頁
檢視。除此之外,osquery
的配套文件/網站也是一應俱全,包括主頁
、Github
、readthedocs
、slack
。
本篇文章以CentOS
為例說明Osquery
的安裝以及使用。
安裝
在主頁
上面提供了不同作業系統的安裝包,我們下載CentOS對應的rpm檔案即可。在本例中檔名是osquery-3.3.0-1.linux.x86_64.rpm
,使用命令sudo yum install osquery-3.3.0-1.linux.x86_64.rpm
安裝。安裝成功之後會出現:
Installed: osquery.x86_64 0:3.3.0-1.linux Complete!
執行
osquery
存在兩種執行模式,分別是osqueryi(互動式模式)、osqueryd(後臺程序模式)。
- osqueryi,與osqueryd安全獨立,不需要以管理員的身份執行,能夠及時地檢視當前作業系統的狀態資訊。
-
osqueryd,我們能夠利用
osqueryd
執行定時查詢記錄作業系統的變化,例如在第一次執行和第二次執行之間的程序變化(增加/減少),osqueryd
會將程序執行的結果儲存(檔案或者是直接打到kafka中)。osqueryd
還會利用作業系統的API來記錄檔案目錄的變化、硬體事件、網路行為的變化等等。osqueryd
在Linux中是以系統服務的方式來執行。
為了便於演示,我們使用osqueyi
來展示osquery
強大的功能。我們直接在terminal中輸入osqueryi
即可進入到osqueryi
的互動模式中(osqueryi
採用的是sqlite
的shell的語法,所以我們也可以使用在sqlite
中的所有的內建函式)。
[user@localhost Desktop]$ osqueryi Using a virtual database. Need help, type '.help' osquery> .help Welcome to the osquery shell. Please explore your OS! You are connected to a transient 'in-memory' virtual database. .all [TABLE]Select all from a table .bail ON|OFFStop after hitting an error .echo ON|OFFTurn command echo on or off .exitExit this program .featuresList osquery's features and their statuses .headers ON|OFFTurn display of headers on or off .helpShow this message .mode MODESet output mode where MODE is one of: csvComma-separated values columnLeft-aligned columns see .width lineOne value per line listValues delimited by .separator string prettyPretty printed SQL results (default) .nullvalue STRUse STRING in place of NULL values .print STR...Print literal STRING .quitExit this program .schema [TABLE]Show the CREATE statements .separator STRChange separator used by output mode .socketShow the osquery extensions socket path .showShow the current values for various settings .summaryAlias for the show meta command .tables [TABLE]List names of tables .width [NUM1]+Set column widths for "column" mode .timer ON|OFFTurn the CPU timer measurement on or off
通過.help
,我們能夠檢視在osqueryi
模式下的一些基本操作。比如.exit
表示退出osqueryi
,.mode
切換osqueryi
的輸出結果,.show
展示目前osqueryi
的配置資訊,.tables
展示在當前的作業系統中能夠支援的所有的表名。.schema [TABLE]
顯示具體的表的結構資訊。
osquery> .show osquery - being built, with love, at Facebook ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ osquery 3.3.0 using SQLite 3.19.3 General settings: Flagfile: Config: filesystem (/etc/osquery/osquery.conf) Logger: filesystem (/var/log/osquery/) Distributed: tls Database: ephemeral Extensions: core Socket: /home/xingjun/.osquery/shell.em Shell settings: echo: off headers: on mode: pretty nullvalue: "" output: stdout separator: "|" width: Non-default flags/options: database_path: /home/xingjun/.osquery/shell.db disable_database: true disable_events: true disable_logging: true disable_watchdog: true extensions_socket: /home/xingjun/.osquery/shell.em hash_delay: 0 logtostderr: true stderrthreshold: 3
可以看到設定包括常規設定(General settings)、shell設定(Shell settings)、非預設選項(Non-default flags/options)。在常規設定中主要是顯示了各種配置檔案的位置(配置檔案/儲存日誌檔案的路徑)。 在shell設定
中包括了是否需要表頭資訊(headers
),顯示方式(mode: pretty
),分隔符(separator: "|"
)。
.table
可以檢視在當前作業系統中所支援的所有的表,雖然在schema
中列出了所有的表(包括了win平臺,MacOS平臺,Linux平臺)。但是具體到某一個平臺上面是不會包含其他平臺上的表。下方顯示的就是我在CentOS7
下顯示的表。
osquery> .table => acpi_tables => apt_sources => arp_cache => augeas => authorized_keys => block_devices => carbon_black_info => carves => chrome_extensions => cpu_time => cpuid => crontab ...
.schema [TABLE]
可以用於檢視具體的表的結構資訊。如下所示:
osquery> .schema users CREATE TABLE users(`uid` BIGINT, `gid` BIGINT, `uid_signed` BIGINT, `gid_signed` BIGINT, `username` TEXT, `description` TEXT, `directory` TEXT, `shell` TEXT, `uuid` TEXT, `type` TEXT HIDDEN, PRIMARY KEY (`uid`, `username`)) WITHOUT ROWID; osquery> .schema processes CREATE TABLE processes(`pid` BIGINT, `name` TEXT, `path` TEXT, `cmdline` TEXT, `state` TEXT, `cwd` TEXT, `root` TEXT, `uid` BIGINT, `gid` BIGINT, `euid` BIGINT, `egid` BIGINT, `suid` BIGINT, `sgid` BIGINT, `on_disk` INTEGER, `wired_size` BIGINT, `resident_size` BIGINT, `total_size` BIGINT, `user_time` BIGINT, `system_time` BIGINT, `disk_bytes_read` BIGINT, `disk_bytes_written` BIGINT, `start_time` BIGINT, `parent` BIGINT, `pgroup` BIGINT, `threads` INTEGER, `nice` INTEGER, `is_elevated_token` INTEGER HIDDEN, `upid` BIGINT HIDDEN, `uppid` BIGINT HIDDEN, `cpu_type` INTEGER HIDDEN, `cpu_subtype` INTEGER HIDDEN, `phys_footprint` BIGINT HIDDEN, PRIMARY KEY (`pid`)) WITHOUT ROWID;
上面通過.schema
檢視users
和processes
表的資訊,結果輸出的是他們對應的DDL。
基本使用
在本章節中,將會演示使用osqueryi
來實時查詢作業系統中的資訊(為了方便展示查詢結果使用的是.mode line
模式)。
檢視系統資訊
osquery> select * from system_info; hostname = localhost uuid = 4ee0ad05-c2b2-47ce-aea1-c307e421fa88 cpu_type = x86_64 cpu_subtype = 158 cpu_brand = Intel(R) Core(TM) i5-8400 CPU @ 2.80GHz cpu_physical_cores = 1 cpu_logical_cores = 1 cpu_microcode = 0x84 physical_memory = 2924228608 hardware_vendor = hardware_model = hardware_version = hardware_serial = computer_name = localhost.localdomain local_hostname = localhost
查詢的結果包括了CPU的型號,核數,記憶體大小,計算機名稱等等;
檢視OS版本
osquery> select * from os_version; name = CentOS Linux version = CentOS Linux release 7.4.1708 (Core) major = 7 minor = 4 patch = 1708 build = platform = rhel platform_like = rhel codename =
可以看到我的本機的作業系統的版本是CentOS Linux release 7.4.1708 (Core)
檢視核心資訊版本
osquery> SELECT * FROM kernel_info; version = 3.10.0-693.el7.x86_64 arguments = ro crashkernel=auto rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb quiet LANG=en_US.UTF-8 path = /vmlinuz-3.10.0-693.el7.x86_64 device = /dev/mapper/centos-root osquery> SELECT * FROM kernel_modules LIMIT 3; name = tcp_lp size = 12663 used_by = - status = Live address = 0xffffffffc06cf000 name = fuse size = 91874 used_by = - status = Live address = 0xffffffffc06ae000 name = xt_CHECKSUM size = 12549 used_by = - status = Live address = 0xffffffffc06a9000
查詢repo和pkg資訊
osquery提供查詢系統中的repo和okg相關資訊的表。在Ubuntu中對應的是apt
相關的包資訊,在Centos中對應的是yum
相關的包資訊。本例均以yum
包為例進行說明。
osquery> SELECT * FROM yum_sourceslimit 2; name = CentOS-$releasever - Base baseurl = enabled = gpgcheck = 1 gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 name = CentOS-$releasever - Updates baseurl = enabled = gpgcheck = 1 gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
我們可以直接利用yum_sources
來檢視作業系統的yum源相關的資訊。
osquery> SELECT name, version FROM rpm_packages order by name limit 3; name = GConf2 version = 3.2.6 name = GeoIP version = 1.5.0 name = ModemManager version = 1.6.0
利用rpm_packages
檢視系統中已經安裝的rpm包資訊。我們也可以通過name
對我們需要查詢的包進行過濾,如下:
osquery> SELECT name, version FROM rpm_packages where name="osquery"; name = osquery version = 3.3.0
掛載資訊
我們可以使用mounts
表來查詢系統中的具體的驅動資訊。例如我們可以如下的SQL語句進行查詢:
SELECT * FROM mounts; SELECT device, path, type, inodes_free, flags FROM mounts;
我們也可以使用where
語句查詢摸一個具體的驅動資訊,例如ext4
或者是tmpfs
資訊。如下:
osquery> SELECT device, path, type, inodes_free, flags FROM mounts WHERE type="ext4"; osquery> SELECT device, path, type, inodes_free, flags FROM mounts WHERE type="tmpfs"; device = tmpfs path = /dev/shm type = tmpfs inodes_free = 356960 flags = rw,seclabel,nosuid,nodev device = tmpfs path = /run type = tmpfs inodes_free = 356386 flags = rw,seclabel,nosuid,nodev,mode=755 device = tmpfs path = /sys/fs/cgroup type = tmpfs inodes_free = 356945 flags = ro,seclabel,nosuid,nodev,noexec,mode=755 device = tmpfs path = /run/user/42 type = tmpfs inodes_free = 356955 flags = rw,seclabel,nosuid,nodev,relatime,size=285572k,mode=700,uid=42,gid=42 device = tmpfs path = /run/user/1000 type = tmpfs inodes_free = 356939 flags = rw,seclabel,nosuid,nodev,relatime,size=285572k,mode=700,uid=1000,gid=1000
記憶體資訊
使用memory_info
檢視記憶體資訊,如下:
osquery> select * from memory_info; memory_total = 2924228608 memory_free = 996024320 buffers = 4280320 cached = 899137536 swap_cached = 0 active = 985657344 inactive = 629919744 swap_total = 2684350464 swap_free = 2684350464
網絡卡資訊
使用interface_addresses
檢視網絡卡資訊,如下:
osquery> SELECT * FROM interface_addresses; interface = lo address = 127.0.0.1 mask = 255.0.0.0 broadcast = point_to_point = 127.0.0.1 type = interface = virbr0 address = 192.168.122.1 mask = 255.255.255.0 broadcast = 192.168.122.255 point_to_point = type = interface = lo address = ::1 mask = ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff broadcast = point_to_point = type =
還可以使用interface_details
檢視更加具體的網絡卡資訊。
SELECT * FROM interface_details; SELECT interface, mac, ipackets, opackets, ibytes, obytes FROM interface_details;
查詢結果如下
osquery> SELECT * FROM interface_details; interface = lo mac = 00:00:00:00:00:00 type = 4 mtu = 65536 metric = 0 flags = 65609 ipackets = 688 opackets = 688 ibytes = 59792 obytes = 59792 ierrors = 0 oerrors = 0 idrops = 0 odrops = 0 collisions = 0 last_change = -1 link_speed = pci_slot = ....
系統啟動時間
osquery> select * from uptime; days = 0 hours = 2 minutes = 23 seconds = 51 total_seconds = 8631
查詢使用者資訊
osquery
提供了多個表用於查詢使用者的資訊,包括使用users
表檢索系統中所有的使用者,使用last
表檢視使用者上次登入的資訊,使用logged_in_user
查詢具有活動shell的使用者資訊。
使用select * from users
檢視所有使用者資訊,使用類似於uid>1000
的方式過濾使用者。
osquery> select * from users where uid>1000; uid = 65534 gid = 65534 uid_signed = 65534 gid_signed = 65534 username = nfsnobody description = Anonymous NFS User directory = /var/lib/nfs shell = /sbin/nologin uuid =
我們可以使用last
表查詢最終的登入資訊,如SELECT * FROM last;
。對於普通使用者來說,其type
值為7。那麼我們的查詢條件如下:
osquery> SELECT * FROM last where type=7; username = user tty = :0 pid = 12776 type = 7 time = 1539882439 host = :0 username = user tty = pts/0 pid = 13754 type = 7 time = 1539882466 host = :0
其中的time是時間戳型別,轉換為具體的日期之後就可以看到具體的登入時間了。
使用SELECT * FROM logged_in_users;
檢視當前已經登入的使用者資訊。
防火牆資訊
我們可以使用iptables
來檢視具體的防火牆資訊,如select * from iptables;
,也可以進行過濾查詢具體的防火牆資訊。如SELECT chain, policy, src_ip, dst_ip FROM iptables WHERE chain="POSTROUTING" order by src_ip;
程序資訊
我們可以使用processes
來查詢系統上程序的資訊,包括pid,name,path,command等等。
可以使用select * from processes;
或者檢視具體的某幾項資訊,select pid,name,path,cmdline from processes;
osquery> select pid,name,path,cmdline from processes limit 2; pid = 1 name = systemd path = cmdline = /usr/lib/systemd/systemd --switched-root --system --deserialize 21 pid = 10 name = watchdog/0 path = cmdline =
檢查計劃任務
我們可以使用crontab
來檢查系統中的計劃任務。
osquery> select * from crontab; event = minute = 01 hour = * day_of_month = * month = * day_of_week = * command = root run-parts /etc/cron.hourly path = /etc/cron.d/0hourly event = minute = 0 hour = 1 day_of_month = * month = * day_of_week = Sun command = root /usr/sbin/raid-check path = /etc/cron.d/raid-check
其他
在Linux中還存在其他很多的表能夠幫助我們更好地進行入侵檢測相關的工作,包括process_events
、socket_events
、process_open_sockets
等等,這些表可供我們進行入侵檢測的確認工作。至於這些表的工作原理,有待閱讀osquery
的原始碼進行進一步分析。
總結
本文主要是對Osquery的基礎功能進行了介紹。Oquery的強大功能需要進一步地挖掘和發現。總體來說,Osquery將作業系統中的資訊抽象成為一張張表,對於進行基線檢查,系統監控是一個非常優雅的方式。當然由於Osquery在這方面的優勢,也可以考慮將其作為HIDS的客戶端,但是如果HIDS僅僅只有Osquery
也顯然是不夠的。
以上