Skip to content

Commit 5e364c8

Browse files
committed
security: detect and copy guest libc
1 parent f097734 commit 5e364c8

File tree

2 files changed

+56
-9
lines changed

2 files changed

+56
-9
lines changed

hooks/filesystem.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@
88
from pathlib import Path
99
from tempfile import NamedTemporaryFile
1010

11+
# 3rd
12+
import guestfs
1113
import magic
1214
from git import Repo
1315
from git.exc import GitCommandError
1416
from see import Hook
1517

16-
# 3rd
17-
import guestfs
1818
# local
1919
from oswatcher.model import GraphInode, InodeType, OSType
2020
from oswatcher.utils import get_hard_drive_path
@@ -320,7 +320,7 @@ def capture_fs(self, event):
320320
self.logger.info('Capturing filesystem')
321321
self.time_last_update = time.time()
322322

323-
self.context.trigger('filesystem_capture_begin')
323+
self.context.trigger('filesystem_capture_begin', gfs=self.gfs)
324324
root_inode = self.walk_capture(root)
325325
# cleanup inode related resources
326326
root_inode.close()

hooks/security.py

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,15 @@
1-
# sys
2-
import json
31
import re
42
import shutil
5-
import subprocess
63
from collections import Counter
74
from dataclasses import dataclass
85
from pathlib import Path
6+
from tempfile import NamedTemporaryFile
97

10-
# 3rd
11-
from see import Hook
128
from checksec.elf import ELFSecurity, PIEType, RelroType
139
from checksec.errors import ErrorNotAnElf, ErrorParsingFailed
10+
from see import Hook
1411

15-
# local
12+
from hooks.filesystem import Inode
1613
from oswatcher.model import OSType
1714

1815

@@ -49,6 +46,7 @@ def __init__(self, parameters):
4946
self.os_info = None
5047
self.stats = Counter()
5148
self.stats['total'] = 0
49+
self.local_guest_libc = NamedTemporaryFile()
5250
self.neo4j_enabled = self.configuration.get('neo4j', False)
5351
if self.neo4j_enabled:
5452
self.os_node = self.configuration['neo4j']['OS']
@@ -62,11 +60,60 @@ def __init__(self, parameters):
6260
self.keep_binaries_dir = self.configuration.get('keep_failed_dir', default_checksec_failed_dir)
6361

6462
self.context.subscribe('detected_os_info', self.get_os_info)
63+
self.context.subscribe('filesystem_capture_begin', self.download_libc)
6564
self.context.subscribe('filesystem_new_file', self.check_file)
6665

6766
def get_os_info(self, event):
6867
self.os_info = event.os_info
6968

69+
def download_libc(self, event):
70+
"""Locate and download the libc"""
71+
gfs = event.gfs
72+
73+
if not self.os_info:
74+
raise RuntimeError('Expected OS Info')
75+
76+
if not self.os_info['os_type'] == OSType.Linux:
77+
return
78+
79+
# find ldd
80+
cmd = ['which', 'ldd']
81+
try:
82+
ldd_path = gfs.command(cmd).strip()
83+
except RuntimeError:
84+
self.logger.warning("Libc detection: command %s failed", cmd)
85+
return
86+
# find ls
87+
cmd = ['which', 'ls']
88+
try:
89+
ls_path = gfs.command(cmd).strip()
90+
except RuntimeError:
91+
self.logger.warning("Libc detection: command %s failed", cmd)
92+
return
93+
cmd = [ldd_path, ls_path]
94+
try:
95+
ldd_output = gfs.command(cmd).strip()
96+
except RuntimeError:
97+
self.logger.warning("Libc detection: command %s failed", cmd)
98+
return
99+
100+
libc_inode = None
101+
for ldd_line in ldd_output.splitlines():
102+
m = re.match(r'\t*(?P<libname>.*)\s+(=>)?\s+(?P<libpath>\S+)?\s+\((?P<addr>.*)\)$', ldd_line)
103+
if not m:
104+
self.logger.warn("Libc detection: line \"%s\" doesn't match LDD regex", ldd_line)
105+
continue
106+
if m.group('libname').startswith('libc.so'):
107+
# found guest libc
108+
libc_inode = Inode(self.logger, gfs, Path(m.group('libpath')))
109+
break
110+
if libc_inode is None:
111+
self.logger.warning("Libc detection: Couldn't locate libc !")
112+
return
113+
# copy libc
114+
shutil.copy(libc_inode.local_file, self.local_guest_libc.name)
115+
self.logger.info("Copied guest libc %s to %s", libc_inode.path, self.local_guest_libc.name)
116+
70117
def check_file(self, event):
71118
# event args
72119
inode = event.inode

0 commit comments

Comments
 (0)