Создать минимальный XZ-бэкдор

Я хотел бы увидеть минимальный пример бэкдора 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 компилируется в нативный код, что делает его быстрым и эффективным на большинстве аппаратных платформ.


2
130
1

Ответ:

Решено

Я не думаю, что это работает с символами, статически объединенными в двоичный код. Эти символы определены в текстовом разделе двоичного файла и разрешаются статически:

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");
}