существуют При ежедневном анализе внешнего программного обеспечения,Появляется все больше и больше средств защиты от отладки/инъекций.,Доиспользоватьизна основе frida Легкая песочница APP Выполните комплексный мониторинг и обход. Эта статья представляет собой исследование и практику таких решений.
Чтобы обеспечить всесторонний мониторинг Android-приложения, необходимо знать, к каким файлам обращается/открывает целевое приложение и какие операции выполняются, а возвращаемые результаты этих операций можно изменять и контролировать. Интуитивная идея состоит в том, чтобы использовать libc в качестве унифицированного интерфейса для сбора данных о поведении приложений, например, взять на себя управление open/openat/faccess/fstatat для реализации мониторинга доступа к файлам и дальнейшего перенаправления файлов.
Однако сегодня многие умные подкрепления APP Оба использования имеют встроенную сборку системных вызовов для обхода libc Чтобы добиться темноты в Чэнцане, binary уровень плюс обфускация потока управления, цветочные инструкции, шифрование кода и даже VMP зрелая из мер защиты,позволяют идентифицировать такие скрытыевызовстать очень трудным。Неизвестный исследователь безопасностиоднажды сказал:
Never to wrestle with a pig. You get dirty, and besides, the pig likes it.
Поэтому нам следует не бороться с производителями арматуры на прикладном уровне, а искать точки прорыва и достигать цели четырьмя способами. Конечно, если вы хотите только потренироваться, вы также можете отодрать виртуальную машину вручную. :)
Прежде чем представить технологию мониторинга ядра, давайте сначала рассмотрим некоторые существующие решения и их недостатки.
strace да Linux Известный в Китае инструмент отслеживания системных вызовов пользовательского режима. Вы можете ввести имя и параметры системного вызова, выполняемого целевым процессом. Он часто используется для быстрой отладки и диагностики приложений. след Пример вывода выглядит следующим образом:
$ strace echo evilpan
execve("/usr/bin/echo", ["echo", "evilpan"], 0x7fe55d5d18 /* 56 vars */) = 0
brk(NULL) = 0x57b1bd2000
faccessat(AT_FDCWD, "/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=19285, ...}) = 0
mmap(NULL, 19285, PROT_READ, MAP_PRIVATE, 3, 0) = 0x79aecf8000
close(3) = 0
openat(AT_FDCWD, "/lib/aarch64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0\267\0\1\0\0\0p\16\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0777, st_size=1439544, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x79aecf6000
mmap(NULL, 1511520, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x79aeb5e000
mprotect(0x79aecb7000, 61440, PROT_NONE) = 0
mmap(0x79aecc6000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x158000) = 0x79aecc6000
mmap(0x79aeccc000, 12384, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x79aeccc000
close(3) = 0
mprotect(0x79aecc6000, 16384, PROT_READ) = 0
mprotect(0x5787f5f000, 4096, PROT_READ) = 0
mprotect(0x79aecff000, 4096, PROT_READ) = 0
munmap(0x79aecf8000, 19285) = 0
brk(NULL) = 0x57b1bd2000
brk(0x57b1bf3000) = 0x57b1bf3000
fstat(1, {st_mode=S_IFCHR|0600, st_rdev=makedev(0x88, 0x2), ...}) = 0
write(1, "evilpan\n", 8evilpan
) = 8
close(1) = 0
close(2) = 0
exit_group(0) = ?
+++ exited with 0 +++
В сценариях, когда необходимо отслеживать системные вызовы, используйте strace даиндивидуальный очень подходит из инструментов, потому что для него основе PTRACE_SYSCALL
отслеживать и на на основесередина перерыв из-за способа взять на себя управление всеми системными вызовами, даже если целевое использование не зависит libc в соответствии svc Также можно узнать. Однако очевидны и недостатки этого индивидуума. Из названия также видно, что он по своей сути программдана. основе ptrace Цель отслеживается, поэтому, если в коде другой стороны есть меры по борьбе с отладкой, вероятность ее обнаружения возрастает.
Также в Android В системе приложение Все процессы состоят из zygote fork вне, поэтому используйте strace Определить, когда отслеживать, труднее, а поскольку многие приложения имеют несколько процессов, требуется дополнительная фильтрация и очистка выходных данных.
подробнее о strace извыполнитьпринцип Можеткссылка: How does strace work?
в первые дни strace Программа его пока не поддерживает рука64, поэтому Jonathan Levin Письмо Android Internal Написано в одной книге jtrace Этот инструмент предназначен для использования Android Отслеживание заявок. Хотя сейчас Google Также там AOSP Поддерживается в след, но jtrace Все же имеет свои уникальные преимущества:
Хотя jtrace да имеет закрытый исходный код, но предоставляет уникальные функции подключаемого модуля. Пользователь может использовать его для написания индивидуального подключаемого модуля (динамической библиотеки) на основе предоставляемого им интерфейса и использования. --plugin
параметры или JTRACE_EXT_PATH
Путь, указанный переменной среды, загружает плагин для реализации настраиваемой обработки анализа параметров системного вызова.
Хотя соотношение преимуществ strace Их гораздо больше, но ее недостатки не решены, jtrace Сама еще дана основе PTRACE_SYSCALL Выполняет отслеживание системы и поэтому легко обнаруживается средствами защиты от отладки приложений.
Подробности см.: http://newandroidbook.com/tools/jtrace.html
frida да На данный момент это самый известный в мире набор инструментов для динамического отслеживания. (Instrumentation),поддерживатьиспользовать js Скрипт для динамического отслеживания целевого приложения. Я думаю, читателям будет интересно frida Он не новичок в этом, поэтому я не буду здесь рассказывать об этом слишком подробно. Нет сомнений в том, что его функции богаты, но есть и некоторые недостатки, такие как:
сродни Instrumentation Также есть инструменты QDBI,hookzz и т. д.
Помимо упомянутых выше инструментов,,Существует также множество других инструментов для динамичного мониторинга.,например ltrace、gdb и т. д. Но ни один из этих инструментов не отвечает моим потребностям в полной мере. Если мы хотим, чтобы лошадь бегала быстро (низко над головой) и не ела траву (без вторжения), то мы можем сосредоточиться только на ядре.
Если целью дадля является реализация мониторинга системных вызовов и некоторые параметры системных вызовов изменяются (например, IO Redirect), затем возникает интуитивная идея изменить исходный код Yadro, в настоящее время мы заинтересованы в том, чтобы из входа в систему вставить свой собственный код для достижения определенных функций. Но это очень неэффективно. Во-первых, нам нужно добавить код в различные функции, связанные с системными вызовами середина. Введение слишком большого количества модификаций затруднит обновление Ядро и объединение исходных материалов, во-вторых, нам нужно перекомпилировать Ядро каждый раз, когда мы вносим изменения. И соответствующее из. AOSP код (потому что ядро boot.img (подробнее см. ниже), а затем записать его в мобильный телефон или симулятор, процесс слишком сложен.
Еще одна уникальная идея, представленная Кодексом существования Ядро середина одноразового использования. батут, а затем существование впоследствии увеличивается и уменьшается системный вызов мониторинга входа через модуль Ядро из метода внесения изменений. Это кажется несколько более разумным, но на самом деле у Ядросередина уже есть много сродни Планов. Диптихи, это просто изобретение велосипеда. Это не только неэффективно, но и может быть введено в любой момент. kernel panic。
Итак, что же есть у Ядросередина? Диптихи? На самом деле это непростой вопрос. Мы слышали об этом в ходе повседневной эксплуатации и технического обслуживания. kprobe、jprobe、uprobe、eBPF、tracefs、systemtab、perf,...Какие между ними отношения?,Какая польза от каждого?
Вот рекомендуемая статья: Linux tracing systems & how they fit together,Согласно его серединаизовому введению,Эти Ядро План Диптихи/инструменты можно разделить на три категории:
trace
Эти решения для мониторинга будут кратко представлены позже.
Проще говоря, kprobe может реализовать динамическое внедрение ядра, вставлять код отслеживания в любую инструкцию на основе метода прерывания и получать обратные вызовы через pre_handler/post_handler/fault_handler.
ссылка Linux в исходном коде samples/kprobes/kprobe_example.c,одининдивидуальный Простойиз kprobe Модуль ядра реализован следующим образом:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/kprobes.h>
#define MAX_SYMBOL_LEN 64
static char symbol[MAX_SYMBOL_LEN] = "_do_fork";
module_param_string(symbol, symbol, sizeof(symbol), 0644);
/* For each probe you need to allocate a kprobe structure */
static struct kprobe kp = {
.symbol_name = symbol,
};
/* kprobe pre_handler: called just before the probed instruction is executed */
static int handler_pre(struct kprobe *p, struct pt_regs *regs)
{
pr_info("<%s> pre_handler: p->addr = 0x%p, pc = 0x%lx\n", p->symbol_name, p->addr, (long)regs->pc);
/* A dump_stack() here will give a stack backtrace */
return 0;
}
/* kprobe post_handler: called after the probed instruction is executed */
static void handler_post(struct kprobe *p, struct pt_regs *regs, unsigned long flags)
{
pr_info("<%s> post_handler: p->addr = 0x%p\n", p->symbol_name, p->addr);
}
/*
* fault_handler: this is called if an exception is generated for any
* instruction within the pre- or post-handler, or when Kprobes
* single-steps the probed instruction.
*/
static int handler_fault(struct kprobe *p, struct pt_regs *regs, int trapnr)
{
pr_info("fault_handler: p->addr = 0x%p, trap #%dn", p->addr, trapnr);
/* Return 0 because we don't handle the fault. */
return 0;
}
static int __init kprobe_init(void)
{
int ret;
kp.pre_handler = handler_pre;
kp.post_handler = handler_post;
kp.fault_handler = handler_fault;
ret = register_kprobe(&kp);
if (ret < 0) {
pr_err("register_kprobe failed, returned %d\n", ret);
return ret;
}
pr_info("Planted kprobe at %p\n", kp.addr);
return 0;
}
static void __exit kprobe_exit(void)
{
unregister_kprobe(&kp);
pr_info("kprobe at %p unregistered\n", kp.addr);
}
module_init(kprobe_init)
module_exit(kprobe_exit)
MODULE_LICENSE("GPL");
После установки этого модуля ядра каждый раз, когда процесс в системе вызывает форк вызовет наш обработчик, таким образом, в dmesg середина выводит соответствующую информацию журнала. Примечательно изда, kprobe Модули зависят от конкретной архитектуры системы. pre_handler серединанаш адрес инструкции по печатииспользованияизда regs->pc
,Да ARM64 из ситуации, если да X86 среду, соответствующую regs->ip
,Может查看对应 arch из struct pt_regs
выполнить.
kprobe рамка на основесерединаперерыввыполнить.когда kprobe После замены на команду «Зарегистрироваться» Ядро скопирует соответствующий адрес Воли из инструкции и заменит инструкцию для точки останова (например, X86 серединаиз int 3
),Затем, когда Ядро будет выполнено по соответствующему адресу,серединаперерыв会被触发从而执行流程会被重定向到我们зарегистрироватьсяиз pre_handler
Функция: когда исходная инструкция, соответствующая адресу из, будет выполнена, Ядро будет выполнено снова. post_handler
(Может选),从而выполнитькомандный уровеньиз Ядродинамичныймонитор。То естьдаобъяснять,kprobe может не только отслеживать любую функцию с помощью символов из Ядро,Вы также можете отслеживать любые инструкции между функциями.
другой kprobe изродственникда kretprobe,Просто да следит за уровнем функции из Ядро,в соответствии спользовательзарегистрироватьсядоступен, когдаиз entry_handler
и ret_handler
Обратные вызовы выполняются при входе в функцию и перед возвратом. Конечно, это можно реализовать kprobe Также есть разница: не да проходит точку останова, а да проходит trampoline Реализация может немного сократить накладные расходы.
кто-то, возможно, слышал о Джей-проба, это рано Linux Ядроизизодининдивидуальный мониторинг реализован и был Kprobe заменять.
Дальнейшее чтение:
uprobe Как следует из названия, относительно Ядро функция/адрес измонитора, в основном используется дляпользовательстатус функция/адрес мониторинга. Звучит так, будто «да» не «да», это немного волшебно. Как Ядро контролирует функцию состояния пользователя и звызов?
стоятьсуществоватьпользовательперспектива,Давайте сначала рассмотрим простой пример индивидуального,假设有этот么индивидуальныйодининдивидуальныйпользовательпрограмма:
// test.c
#include <stdio.h>
void foo() {
printf("hello, uprobe!\n");
}
int main() {
foo();
return 0;
}
После компиляции,Посмотреть адрес определенного индивидуального символа из,Тогда скажите Ядро, что я хочу отслеживать этот индивидуальный адрес извызов:
$ gcc test.c -o test
$ readelf -s test | grep foo
87: 0000000000000764 32 FUNC GLOBAL DEFAULT 13 foo
$ echo 'p /root/test:0x764' > /sys/kernel/debug/tracing/uprobe_events
$ echo 1 > /sys/kernel/debug/tracing/events/uprobes/p_test_0x764/enable
$ echo 1 > /sys/kernel/debug/tracing/tracing_on
Затем запустите пользовательскую программу и проверьте, возвращается ли монитор Ядроиз:
$ ./test && ./test
hello, uprobe!
hello, uprobe!
$ cat /sys/kernel/debug/tracing/trace
# tracer: nop
#
# WARNING: FUNCTION TRACING IS CORRUPTED
# MAY BE MISSING FUNCTION EVENTS
# entries-in-buffer/entries-written: 3/3 #P:8
#
# _-----=> irqs-off
# / _----=> need-resched
# | / _---=> hardirq/softirq
# || / _--=> preempt-depth
# ||| / delay
# TASK-PID CPU# |||| TIMESTAMP FUNCTION
# | | | |||| | |
test-7958 [006] .... 34213.780750: p_test_0x764: (0x6236218764)
test-7966 [006] .... 34229.054039: p_test_0x764: (0x5f586cb764)
Конечно, не забудьте в конце отключить мониторинг:
$ echo 0 > /sys/kernel/debug/tracing/tracing_on
$ echo 0 > /sys/kernel/debug/tracing/events/uprobes/p_test_0x764/enable
$ echo > /sys/kernel/debug/tracing/uprobe_events
Выше из интерфейса дана основе debugfs (существоватьновееиз Ядросерединаиспользовать Tracefs), то есть читать и записывать файлы для достижения интерактивной реализации. uprobe монитор. который пишет uprobe_events
пройдет серию вызовов ядра:
Когда уже зарегистрирован uprobe из ELF При запуске программы исполняемый файл будет иметь вид mmap Сопоставляется процессу с адресным пространством, и Ядро будет использовать виртуальное адресное пространство процесса середина, соответствующее из uprobe Адрес заменяется инструкцией точки останова. Когда целевая программа указывает на соответствующий из uprobe адрес, будет срабатывать точка останова, тем самым запуская uprobe изсередина прерывает процесс обработки (arch_uprobe_exception_notify),а потомсуществовать Ядросередина Распечатать Перепискаинформация。
и kprobe Аналогичным образом мы можем вызвать uprobe В это время текущая информация контекста выполнения извлекается в соответствии с соответствующим регистром, например, параметром функции ожидания. в то же время uprobe Есть и сродни родственники: uretprobe。использовать uprobe из Преимущества: мы можем получить много относительно абстрактной информации о состояниях Ядро, таких как bash середина readline Функция возврата, SSL_read/write из Открытое текстовое сообщение ждать.
Дальнейшее чтение:
tracepont да Ядросередина предоставляет облегченный план кода мониторинга,Может внедрить динамичныйвызовпользователь для обеспечения функций мониторинга.,Однако специалистам по сопровождению подсистемы необходимо при необходимости добавлять его в свой код.
tracepoint изиспользоватьи uprobe Аналогично, в основном на основе debugfs/tracefs из чтения и записи файлов для проверки Индивидуальная разница существует. uprobe использоватьизизпользователь определите собственную точку наблюдения (событие) и tracepoint использоватьизда Ядро код середина, заданный для точки наблюдения.
Посмотреть определение Ядро(илиDrive)середина из всех наблюдений:
$ cat /sys/kernel/debug/tracing/available_events
sctp:sctp_probe
sctp:sctp_probe_path
sde:sde_perf_uidle_status
....
random:random_read
random:urandom_read
...
Соответствующий каталог существующих событий содержит организацию структуры подсистемы и каталог точек наблюдения:
$ ls /sys/kernel/debug/tracing/events/random/
add_device_randomness credit_entropy_bits extract_entropy get_random_bytes mix_pool_bytes_nolock urandom_read
add_disk_randomness debit_entropy extract_entropy_user get_random_bytes_arch push_to_pool xfer_secondary_pool
add_input_randomness enable filter mix_pool_bytes random_read
$ ls /sys/kernel/debug/tracing/events/random/random_read/
enable filter format id trigger
к urandom дляпример,Это да Ядроиз функция генерации псевдослучайных чисел,Следуйте этому:
$ echo 1 > /sys/kernel/debug/tracing/events/random/urandom_read/enable
$ echo 1 > /sys/kernel/debug/tracing/tracing_on
$ head -c1 /dev/urandom
$ cat /sys/kernel/debug/tracing/trace_pipe
head-9949 [006] .... 101453.641087: urandom_read: got_bits 40 nonblocking_pool_entropy_left 0 input_entropy_left 2053
Чтосередина trace_pipe да вывод из конвейера, к блокировка из режима чтения, поэтому вам нужно сначала начать чтение, а затем получить /dev/urandom
,然后就Можетк Посмотрите что-то вроде вышеизвыход。здесьвыходиз Форматдасуществовать Ядросерединаопределениеиз,Посмотрим ниже.
Конечно, не забудьте отключить трассировку в конце.
Согласно документации Ядро,Специалисты по сопровождению подсистемы могут добавлять точки трассировки, если они хотят добавить точки трассировки в свои функции.,Требуется два шага:
Ядродля точки трассировки согласно предоставленному определению TRACE_EVENT
Макро. пока urandom_read этотиндивидуальныйточка отслеживаниядляпример,Чтосуществовать Ядросерединаизопределениесуществовать include/trace/events/random.h:
#undef TRACE_SYSTEM
#define TRACE_SYSTEM random
TRACE_EVENT(random_read,
TP_PROTO(int got_bits, int need_bits, int pool_left, int input_left),
TP_ARGS(got_bits, need_bits, pool_left, input_left),
TP_STRUCT__entry(
__field( int, got_bits )
__field( int, need_bits )
__field( int, pool_left )
__field( int, input_left )
),
TP_fast_assign(
__entry->got_bits = got_bits;
__entry->need_bits = need_bits;
__entry->pool_left = pool_left;
__entry->input_left = input_left;
),
TP_printk("got_bits %d still_needed_bits %d "
"blocking_pool_entropy_left %d input_entropy_left %d",
__entry->got_bits, __entry->got_bits, __entry->pool_left,
__entry->input_left)
);
Чтосередина:
TRACE_SYSTEM
определение макроса);TRACE_EVENT Макрос не вставляет автоматически соответствующую функцию, а определяет индивидуальное имя для расширения. trace_urandom_read из функции требуется, чтобы разработчики Ядро выполняли существующий код середина самостоятельно вызовом. Вышеупомянутая точка отслеживания на самом деле дасуществовать. drivers/char/random.c Файлы середина перенесли вызов:
static ssize_t
urandom_read_nowarn(struct file *file, char __user *buf, size_t nbytes,
loff_t *ppos)
{
int ret;
nbytes = min_t(size_t, nbytes, INT_MAX >> (ENTROPY_SHIFT + 3));
ret = extract_crng_user(buf, nbytes);
trace_urandom_read(8 * nbytes, 0, ENTROPY_BITS(&input_pool)); // <-- здесь
return ret;
}
static ssize_t
urandom_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
{
unsigned long flags;
static int maxwarn = 10;
if (!crng_ready() && maxwarn > 0) {
maxwarn--;
if (__ratelimit(&urandom_warning))
pr_notice("%s: uninitialized urandom read (%zd bytes read)\n",
current->comm, nbytes);
spin_lock_irqsave(&primary_crng.lock, flags);
crng_init_cnt = 0;
spin_unlock_irqrestore(&primary_crng.lock, flags);
}
return urandom_read_nowarn(file, buf, nbytes, ppos);
}
Примечательно издафактически дасуществовать urandom_read_nowarn функция середина вместо да urandom_read функциясерединавызовиз,Таким образом, также можно видеть, что имя точки внедрения не связано напрямую с фактическим именем функции.,Просто его должно быть легко идентифицировать и найти.
Согласно приведенному выше введению, мы можем понять, что зонд точки трассировки:
Кроме того, точка трассировки Кромесуществовать Ядрокодсерединапрямойопределение,Вы также можете добавить ксуществовать драйвер середина для динамичности.,используется Разработчикам драйверов удобно отлаживать и повторно использовать существующие файлы. debugfs окончательная архитектура。здесь有одининдивидуальный ПростойизПример пользовательской точки трассировки,Можетиспользуется для углубления пары tracepoint использоватьизпонимать。
Дальнейшее чтение:
USDT выражать Userland Statically Defined Tracing,Прямо сейчаспользовательстатическийопределение追踪 (Первыми уйдут товарищи из валютного круга). Возник из Sun из Dtrace инструмент, поэтому USDT probe также часто называют Dtrace probe。Можеткпониматьдля kernel tracepoint версия изпользовательского слоя, созданная самим разработчиком приложения, существует изпрограммсередина, добавлена ключевая функция Настроить точку трассировки, немного Похоже на: printf Метод отладки (неправильный).
поддаодининдивидуальный Простойиз Пример:
#include "sys/sdt.h"
int main() {
DTRACE_PROBE("hello_usdt", "enter");
int reval = 0;
DTRACE_PROBE1("hello_usdt", "exit", reval);
}
DTRACE_PROBEn
да UDST (systemtap) Предоставьте определение точки отслеживания + вставьте вспомогательный макрос, n выразить параметр индивидуальный номер. После компиляции приведенного выше кода вы увидите, что введенный код USDT probe информация:
$ apt-get install systemtap-sdt-dev
$ gcc hello-usdt.c -o hello-usdt
$ readelf -n ./hello-usdt
...
Displaying notes found in: .note.stapsdt
Owner Data size Description
stapsdt 0x0000002e NT_STAPSDT (SystemTap probe descriptors)
Provider: "hello_usdt"
Name: "enter"
Location: 0x0000000000001131, Base: 0x0000000000002004, Semaphore: 0x0000000000000000
Arguments:
stapsdt 0x00000038 NT_STAPSDT (SystemTap probe descriptors)
Provider: "hello_usdt"
Name: "exit"
Location: 0x0000000000001139, Base: 0x0000000000002004, Semaphore: 0x0000000000000000
Arguments: -4@-4(%rbp)
readelf -n
выражатьвыход ELF середина NOTE Раздел информации.
существоватьиспользовать trace инструменты (например, BCC、SystemTap、dtrace) При отслеживании приложения процесс запуска середина изменит соответствующий адрес целевого процесса и заменит его на для. probe , когда существующее вызывает вызов, генерируется соответствующее событие для завершения сбора данных. обычно добавляют probe из Способда на основе uprobe Осознайте из.
использовать USDT Преимущества: Разработчики приложений могут самостоятельно определять точки отслеживания более высокого уровня, чтобы облегчить мониторинг и анализ на функциональном уровне, например node.js server Просто принеси это с собой USDT probe Баллы можно использовать для отслеживания HTTP запрос и выведите запрос из информации об ожидании пути. потому что USDT Требуется сотрудничество с разработчикомиспользовать,Не отвечает нашим первоначальным потребностям в обратном анализе,поэтому Я не буду представлять слишком много.。(Что实да Слишком ленив, чтобы соответствовать окружающей среде)
Дальнейшее чтение:
Вышеупомянутое введение из четырех распространенных Ядро План мониторинга,В соответствии со статическим/динамическим типом.,Для обзора вы можете использовать следующую таблицу:
План мониторинга | статический | динамичный | Ядро | пользователь |
---|---|---|---|---|
Kprobes | ✔ | ✔ | ||
Uprobes | ✔ | ✔ | ||
Tracepoints | ✔ | ✔ | ||
USDT | ✔ | ✔ |
Если быть точным USDT Это не независимый источник данных мониторинга, поскольку его реализация по-прежнему зависит от uprobe,Но для симметрично и да положить существованиездесь,И каталог так выглядит лучше.
Выше мы представили несколько основных источников данных мониторинга в сегодняшней Ядросередине.,По сути, он может удовлетворить все потребности в мониторинге. Однако с точки зрения удобства использования,Только да реализует базовую архитектуру,использовать Естьиздана основа Ядро обеспечивает интерфейс системных вызовов/драйверов с издана основе debugfs/tracefs не очень дружелюбен к пользователю, поэтому существует множество инкапсуляций и повторных инкапсуляций внешнего мониторинга. интерфейса, в этом разделе представлено краткое введение в эти основные инструменты.
ftrace да Ядросерединаиспользуется для реализует набор фреймворков для внутреннего отслеживания, что немного абстрактно, но на самом деле мы уже использовали его раньше, просто да tracefs серединаизиспользоватьизметод。
существоватьстарая версиясередина Ядросередина(4.1 До)использовать debugfs,обычно монтируемый в /sys/kernel/debug/tracing;существоватьновая версиясерединаиспользоватьнезависимыйиз трассировки, смонтированные в /sys/ядро/трассировка. Однако из соображений совместимости исходный путь по-прежнему сохраняется, поэтому мы называем его коллективно. tracefs。
ftrace обычно называется function tracer,Но помимо функции отслеживания,Также поддерживаются многие другие сведения о событиях из трека:
Android середина предоставляет индивидуальное краткое руководство по добавлению документа для Yadro ftrace поддерживать,Подробности см.: Using ftrace。
perf да Linux Дистрибутив середина предоставляет отдельную программу мониторинга производительности, основе Ядропоставлятьиз perf_event_open Системные вызовы для выборки процессов и получения информации. Линукс серединаиз perf Подсистемы могут реализовывать CPU Инструкция по отслеживанию и подсчету, к и сбору kprobe、uprobe и tracepoints из информации для достижения производительности системы из анализа.
существовать Android середина предоставляет простую версию индивидуального perf программа simpleperf,интерфейси perf похожий.
Хотя может контролировать системный вызов,Но недостаток в том, что да не может получить параметры системного вызова.,Тем более запрещено модифицировать Ядро кдинамичный. Поэтому он малопригоден для тестирования безопасности.,Больше дай APP Разработчик и производитель мобильных телефонов используют для анализа горячих точек производительности. Стоит упомянуть изда, перформанс В подсистеме было много лазеек, существуют Android История подъема власти в Ядро тоже оставила следы. :D
eBPF для extended Berkeley Packet Filter из аббревиатуры БПФ Самое раннее даиспользуется для фильтрации пакетов из оптимизированной виртуальной машины имеет собственный набор инструкций, которые мы обычно используем tcpdump
Внутри инструмента входные данные Воли из правил фильтра будут преобразованы в формат для BPF Инструкции, такие как:
$ tcpdump -i lo0 'src 1.2.3.4' -d
(000) ld [0]
(001) jeq #0x2000000 jt 2 jf 5
(002) ld [16]
(003) jeq #0x1020304 jt 4 jf 5
(004) ret #262144
(005) ret #0
Директива ассемблера выражать сообщает фильтру принимать только IP пакет и исходный код IP 地址для 1.2.3.4. Его набор инструкций серединаиз может кссссылку Linux Socket Filtering aka Berkeley Packet Filter (BPF)。eBPF существовать BPF В набор инструкций было внесено множество улучшений:
Ядрожитьсуществоватьодининдивидуальный eBPF Интерпретатор также поддерживает JIT-компиляцию для увеличения скорости выполнения, но существуют важные индивидуальные ограничения. eBPF Программа не может повлиять на нормальное функционирование ядра Ядронагрузка eBPF программа前会对Что进行один次语义检查,Обеспечить безопасность кода,Основные ограничениядля:
Все стратегии ограничения существуют в Ядроиз. eBPF verifier середина, в разных версиях есть небольшие различия. Стоит отметить, что в последние годы Linux Ядро много появлялся eBPF из уязвимостей, в основном да verifier из Ошибки логики проверки, многие из них все еще публикуются Pwn2Own,нодаиз-за разрешенийизпределсуществовать Android середина Обычные приложения не могут быть выполнены bpf(2)
системные вызовы и поэтому не затрагиваются.
eBPF и perf_event Аналогично, фильтрация кода мониторинга, а также подключение и отключение реализованы с помощью метода виртуальной машины Ядро, который очень эффективен во многих сценариях. Для обычного пользователя в принципе напрямую не написано eBPF из команды для мониторинга, Хотя Ядро предоставляет несколько макросов для помощи eBPF программаиз написана, но на самом деле больше издаиспользовать верхнюю часть структуры инкапсуляции приходится на вызов, середина которого является самой известной из индивидуальных на да BCC。
BCC (BPF Compiler Collection) Содержит ряд инструментов, помогающих эксплуатационному и техническому персоналу писать код мониторинга, среди которых множество Python Привязка. Индивидуальный простой из Примерпрограмма выглядит следующим образом:
from bcc import BPF
prog="""
int kprobe__sys_clone(void *ctx) {
bpf_trace_printk("Hello, World!\\n");
return 0;
}
"""
BPF(text=prog).trace_print()
выполнить это python После кода, всякий раз, когда система серединаиз процесса вызова clone Системный вызов, программа напечатает “Hello World” Выводная информация. Вы можете видеть, что это очень полезно для динамического мониторинга кода. Например, мы можем передать. python Входящие параметры определяют интересующую систему печати и ее параметры без частой модификации кода.
eBPF Можно получить практически все источники данных мониторинга в Ядросередине, в том числе kprobes、uprobes、tracepoints Подожди, это официально repo середина дает множество примеров программы, например opensnoop Мониторинг строк открытия файлов для, execsnoop Мониторинг выполнения программ. Позже мы будем существовать Android Получите практическую демонстрацию системы, чтобы почувствовать ее мощь.
img-bcc
bpftrace да eBPF Фреймворк издругой инкапсуляции верхнего уровня, и BCC Разное изда bpftrace Определите набор себя из DSL Язык сценариев, синтаксис (также) аналогичен awk,Это упрощает реализацию богатых функций непосредственно через командную строку.,Перехватило несколько официальных заявлений:
# Отслеживайте все открытые файлы в системе (открыть/открыть) и распечатывайте процесс открытия файла и путь к открытому файлу.
bpftrace -e 'tracepoint:syscalls:sys_enter_open { printf("%s %s\n", comm, str(args->filename)); }'
# Система статистики середина выполнение отдельных процессов из системных вызовов общее количество
bpftrace -e 'tracepoint:raw_syscalls:sys_enter { @[comm] = count(); }'
Чиновник также дал много .bt Сценарии можно изучать и писать с помощью их кодов.
Дальнейшее чтение:
SystemTap(stab) да Linux серединаиз-индивидуальный инструмент командной строки, который может выполнять структурированный вывод различной исходной информации мониторинга Ядро. В то же время я также осознал свой собственный набор DSL Скрипт, синтаксис аналогичен awk может реализовать быстрое программирование команд мониторинга системы.
использовать systemtap Необходимо включить исходный код Ядро, поскольку для требуется динамичная компиляция и загрузка модуля Ядро. существовать Android середина Еще не официальноизподдерживать,но有один些Открытый исходный код из пересадки systemtap。
Дальнейшее чтение: Comparing SystemTap and bpftrace
В дополнение к приведенному выше введению, эти,Существует также множество внешних интерфейсов мониторинга с открытым исходным кодом.,например LTTng、trace-cmd、kernelsharkждать,Результаты мониторинга сохраняются, обрабатываются и визуализируются в структурированном виде.,Очень полезно для больших объемов данных. Из-за ограниченности места эти инструменты не будут представлены по одному.,И авторов не так уж и много.,В будущем будут проводиться дальнейшие исследования.
начальство面объяснять了Такмного,Ведь только да Linux Релизная версия живая, поэтому эти trace методсуществовать Android Будет ли это работать? Теоретически AOSP Код с открытым исходным кодом, и код с открытым исходным кодом. Просто скомпилируйте его. Но на практике мы столкнемся с несколькими трудностями:
Так как наша основная цель — провести обратный анализ Android-приложений,Поэтому лучше всего запускать его в реальной машинной среде.,Поскольку для многих приложений недоступна поддержка среды x86, конечно, также доступен эмулятор ARM.,Однако при атаке и защите от существования может потребоваться дополнительное обнаружение и обход эмулятора.
авториспользоватьизда Google Pixel 5,использоватьдругой сотовый телефон из слов необходимо соответствующим образом настроить.
Android Сама система не предназначена для разработки, поэтому только простые встроенные busybox(toybox) Инструменты, и некоторые программы, связанные с управлением пакетами, такие как pm/am/dumpsys/input ждать. Чтобы создать полноценную среду разработки на основе существующего, нам необходимо иметь возможность запускать существующий Android-середина. gcc/clang、python、Makefile ждать, индивидуальный интуитивный из идеи да через песочницу, способ ожидания существует выше обычного обычного из Linux распространение, например Ubuntu или Debian。
androdeb Просто эта индивидуальная идея является индивидуальной реализацией, ее суть дана. основе chroot существовать Android середина运行了одининдивидуальный Debian aarch64 зеркало, и можно пройти apt Инструмент управления пакетами ожидания необходим для установки цепочки инструментов компиляции, чтобы существующее можно было скомпилировать и запустить. bcc ждать Linux проект.
существовать Android беги дальше Debian Система из Примерследующее:
Running Debian on Android
Главное правильно смонтировать родной Android серединаиз картографирования, например procfs、devfs、debugfs ждать。
решеносуществовать Android беги дальше инструменты разработки из После решения проблемы нам также нужен индивидуальный управляющийдинамичный отладчик из Ядро среды. существуют Большая часть официальных прошивок середина поставляется с из Ядровключением KPROBES изпод поддержка, а это значит, что мы сами компилируем и загружаем Ядро.
Для поддержки функции ожидания KPROBES, UPROBES, TRACEPOINTS вам необходимо существование Ядроиз конфигурации середина, чтобы добавить следующие параметры:
Отключите функции безопасности Ядроиз, включая отладку поддержки:
-d CONFIG_LTO \
-d CONFIG_LTO_CLANG \
-d CONFIG_CFI_CLANG \
-d CFI_PERMISSIVE \
-d CFI_CLANG \
-e CONFIG_IRQSOFF_TRACER \
-e CONFIG_PREEMPT_TRACER \
-e CONFIG_DEBUG_FS \
-e CONFIG_CHECKPOINT_RESTORE \
-d CONFIG_RANDOMIZE_BASE \
Включите поддержку eBPF:
-e CONFIG_BPF \
-e CONFIG_BPF_SYSCALL \
-e CONFIG_BPF_JIT \
-e CONFIG_HAVE_EBPF_JIT \
-e CONFIG_IKHEADERS \
Включите поддержку kprobes:
-e CONFIG_HAVE_KPROBES \
-e CONFIG_KPROBES \
-e CONFIG_KPROBE_EVENT \
Включите поддержку kretprobe:
-e CONFIG_KRETPROBES \
-e CONFIG_HAVE_KRETPROBES \
-d CONFIG_SHADOW_CALL_STACK \
-e CONFIG_ROP_PROTECTION_NONE \
Включите поддержку ftrace:
-e CONFIG_FTRACE_SYSCALLS \
-e CONFIG_FUNCTION_TRACER \
-e CONFIG_HAVE_DYNAMIC_FTRACE \
-e CONFIG_DYNAMIC_FTRACE \
Включить поддержку uprobes:
-e CONFIG_UPROBES \
-e CONFIG_UPROBE_EVENT \
-e CONFIG_BPF_EVENTS \
BCC рекомендует установить опцию из:
-e CONFIG_DEBUG_PREEMPT \
-e CONFIG_PREEMPTIRQ_EVENTS \
-d CONFIG_PROVE_LOCKING \
-d CONFIG_LOCKDEP
для Во избежание различных экологических проблем,Я предлагаю для среды компиляции лучше всего выбрать чистую английскую виртуальную машину.,илипрямойиспользовать Docker Зеркало, составленное согласно официальному руководству, см.: Building Kernels。
Скомпилируйте Ядро common из зависимостей:
$ pkg --add-architecture i386
$ apt install git ccache automake flex lzop bison \
gperf build-essential zip curl zlib1g-dev zlib1g-dev:i386 \
g++-multilib python-networkx libxml2-utils bzip2 libbz2-dev \
libbz2-1.0 libghc-bzlib-dev squashfs-tools pngcrush \
schedtool dpkg-dev liblz4-tool make optipng maven libssl-dev \
pwgen libswitch-perl policycoreutils minicom libxml-sax-base-perl \
libxml-simple-perl bc libc6-dev-i386 lib32ncurses5-dev \
x11proto-core-dev libx11-dev lib32z-dev libgl1-mesa-dev xsltproc unzip
Дальнейшее чтение:
После того, как вы успешно скомпилируете и запустите Ядро, вы, вероятно, обнаружите некоторые инструменты анализа Ядро, такие как BCC На существованиеиспользовать возникают различные проблемы, которые обычно вызваны да Ядро версией из. потому что eBPF в настоящий моментсуществовать Ядросередина Также там Частые обновления,поэтому许много新из特性并没有Увеличивать到когда前Ядроначальство。
Например,существовать Pixel 5 последняя поддержка Ядрода 4.19 Версия,существоватьэтотиндивидуальный Версиясередина,bpf_probe_read_user (issue#3175) Функция еще не добавлена в Ядро, поэтому используйте BCC вернется к bpf_probe_read_kernel
,Это существование Ядро вызовет ошибки при непосредственном чтении пользовательского пространства из данных (например, параметров системного вызова).,Поэтому нам нужно идти вручную cherry-pick Переписка commit,Прямо сейчассуществовать Linux 5.5 серединадобавить виз 6ae08ae3dea2。
BCC Список всех необходимых функций Ядро и их представленных версий можно найти по адресу: BCC/kernel-versions.md,Неполный список показан ниже:
img-commit
поэтомудля了减少Может能遇到из Проблемы совместимости,Попробуйте использовать последнюю версию из Ядро,Конечно, обычно производители поддерживают только более старую версию LTS.,Выполняйте только необходимые обновления безопасности,Если вы не будете осторожны при покупке машины, вам придется постоять за себя.
проходитьсуществоватьначальство述 Android Debian Окружение составлено хорошо BCC После этого мы сможем киспользовать Python писать Переписка Применить скрипт анализа отслеживания。один般дапроходить应用名去过滤系统вызов,нодасуществовать Android середина и индивидуальный специальный метод фильтрации для да через пользователя ID, т.к. для приложения да получается по динамичной установке UID Перейти на изоляцию в песочнице.
к Некоторые отдельные слои усиления являются вредоносными APK например, получить его после установки UID для u0_a142
,Преобразовать в числада 10142
,对Что进行 exec Мониторинг системных вызовов:
img-exec
Вы можете увидеть вызов целевого приложения ps、getprop、pm программа ожидания, используемая для обнаружения текущей системы adb Статус к и установленных из приложений, таких как их серединапасс pm path com.topjohnwu.magisk
судить Magisk инструментда否житьсуществовать,поэтомужитьсуществовать root Проверьте строку для. Картинка выше середина pm
вообще-то позвонил cmd
программа для поиска, потому что для pm 本质начальство只даодининдивидуальный shell Скрипт:
$ cat `which pm`
#!/system/bin/sh
cmd package "$@"
использовать UID Фильтрация преимуществ позволяет отслеживать все fork издочерний процесс и внуковый процесс, это дана основе PID или Отслеживание имени процесса несравнимо. Кроме exec, мы также можем проследить другую функцию Ядро, например root При тестировании часто используются openat или доступ, как показано ниже:
img-su
на основе Ядроуровень Мониторинг,Сделать все защитные меры приложения по усилению/скрытию/встроенной сборке ожидания неэффективными.,И вы можете наблюдать это на ранней стадии запуска приложения.,Пусть приложению из всего, что вы делаете для существовать середина, нечего скрывать от наших глаз.
PS: еслисуществоватьиспользовать BCC изпроцесссерединанайден без фильтрации UID из этого варианта вам может потребоваться переключиться на последнюю версию release Версия или master Ветка, потому что для этого индивидуального варианта автор только недавно добавил из.
img-pr
:D
Дальнейшее чтение:
Эта статья Подвести подвел итоги и проанализировал несколько основных из Планов Ядро мониторинга,Они обычноиспользуется для мониторинга производительности и отладки, но мы также можем использовать его для анализа безопасности и существования Android середина провела реальные наступательные и оборонительные испытания и добилась реальных боевых эффектов, превзошедших ожидания. Помимо мониторинга уровня Ядро, мы также можем основе uprobes Обеспечьте мониторинг любого адреса в приложении, например существующего SSL_read/write Получите все по адресу SSL шифрованиеизданные。Воспользуйтесь Ядропоставлятьиз丰富монитор原语,Мы можем реализовать мобильную песочницу уровня Ядро.,Комплексный мониторинг работы мобильных приложений,Вы также можете изменять параметры системы с помощью примитивов чтения и записи Ядро.,Это позволяет моделировать и формировать среду выполнения приложения.