Я хотел бы увидеть минимальный пример бэкдора XZ.
Как я понимаю:
Вот что-то вроде этого (пока не работает!)
main.c (действующий как sshd)
#include <stdio.h>
void critical_function() {
printf("critical_function uncompromised.\n");
}
int main() {
critical_function();
return 0;
}
бэкдор.с
#include <stdio.h>
void compromised_critical_function() {
printf("critical_function COMPROMISED.\n");
}
void *resolve_critical_function() {
return compromised_critical_function;
}
__attribute__((visibility("default")))
void critical_function() __attribute__((ifunc("resolve_critical_function")));
gcc-13 -o prog main.c
gcc-13 -shared -fPIC -o libbackdoor.so backdoor.c
LD_PRELOAD=./libbackdoor.so ./prog
это печатается critical_function uncompromised.
но я бы хотел, чтобы это печаталось critical_function COMPROMISED.
🤔 А знаете ли вы, что...
C компилируется в нативный код, что делает его быстрым и эффективным на большинстве аппаратных платформ.
Я не думаю, что это работает с символами, статически объединенными в двоичный код. Эти символы определены в текстовом разделе двоичного файла и разрешаются статически:
nm prog | grep critical_function
T critical_function
Чтобы поиск символа происходил во время выполнения с помощью редактора динамических ссылок (ld.so), вам нужно оставить символ неопределенным (U
в номенклатуре nm
). Вы можете сделать это, извлекая critical_function
в отдельную единицу перевода и скомпилировав ее как общую библиотеку, связанную с вашим двоичным файлом:
main.c
:void critical_function(void);
int main(void) {
critical_function();
}
func.c
:#include <stdio.h>
void critical_function(void) {
printf("critical_function uncompromised.\n");
}
backdoor.c
:#include <stdio.h>
void compromised_critical_function(void) {
printf("critical_function COMPROMISED.\n");
}
void *resolve_critical_function(void) {
return compromised_critical_function;
}
__attribute__((visibility("default")))
void critical_function(void) __attribute__((ifunc("resolve_critical_function")));
Скомпилировано через (Makefile
):
CFLAGS += -fPIC
all: prog libbackdoor.so
prog: main.o libfunc.so
$(CC) -o $@ $+
lib%.so: %.o
$(CC) -shared -o $@ $+
И выполнить через:
LD_PRELOAD=./libbackdoor.so LD_LIBRARY_PATH=$PWD ./prog
critical_function COMPROMISED.
Для полноты картины вам не нужно использовать здесь механизм IFUNC; IFUNC полезен для динамического вычисления адреса функции во время выполнения, но мы могли бы просто переопределить его безоговорочно:
backdoor.c
(альтернатива)#include <stdio.h>
void critical_function(void) {
printf("critical_function COMPROMISED.\n");
}