เจเจน เจจเฉเจ 2014 เจตเจฟเฉฑเจ เจฒเจฟเจเจฟเจ เจเจฟเจ เจธเฉ, เจชเจฐ เจฎเฉเจ เจนเฉเจฃเฉ เจนเฉ เจนเฉเจฌเจฐเฉ 'เจคเฉ เจเจฌเจฐ เจฆเฉ เจ เจงเฉเจจ เจเจเจ เจนเจพเจ เจ เจคเฉ เจเจธ เจจเฉ เจฆเจฟเจจ เจฆเฉ เจฐเฉเจธเจผเจจเฉ เจจเจนเฉเจ เจตเฉเจเฉเฅค เจชเจพเจฌเฉฐเจฆเฉ เจฆเฉ เจฆเฉเจฐเจพเจจ เจฎเฉเจ เจเจธ เจฌเจพเจฐเฉ เจญเฉเฉฑเจฒ เจเจฟเจ เจธเฉ, เจชเจฐ เจนเฉเจฃ เจฎเฉเจ เจเจธเจจเฉเฉฐ เจกเจฐเจพเจซเจ เจตเจฟเฉฑเจ เจชเจพเจเจ เจนเฉ. เจฎเฉเจ เจเจธเจจเฉเฉฐ เจฎเจฟเจเจพเจเจฃ เจฌเจพเจฐเฉ เจธเฉเจเจฟเจ, เจชเจฐ เจธเจผเจพเจเจฆ เจเจน เจเจฟเจธเฉ เจฒเจ เจฒเจพเจญเจฆเจพเจเจ เจนเฉเจตเฉเจเจพ.

เจเจฎ เจคเฉเจฐ 'เจคเฉ, "เจธเจผเจพเจฎเจฒ" เจฆเฉ เจเฉเจ เจเจฐเจจ เจฆเฉ เจตเจฟเจธเจผเฉ 'เจคเฉ เจฅเฉเฉเจพ เจเจฟเจนเจพ เจธเจผเฉเฉฑเจเจฐเจตเจพเจฐ เจเจกเจฎเจฟเจจ เจฐเฉเจกเจฟเฉฐเจ LD_PRELOAD.
1. เจเจนเจจเจพเจ เจฒเจ เจเฉฑเจ เจเฉเจเจพ เจตเจฟเจธเจผเจพ เจเฉ เจซเฉฐเจเจธเจผเจจ เจฌเจฆเจฒ เจคเฉเจ เจเจพเจฃเฉ เจจเจนเฉเจ เจนเจจ
เจฌเจพเจเฉ เจธเจฟเฉฑเจงเฉ เจเจพ เจธเจเจฆเฉ เจนเจจ ะฟ...
เจเจ เจเฉฑเจ เจเจฒเจพเจธเจฟเจ เจเจฆเจพเจนเจฐเจจ เจจเจพเจฒ เจธเจผเฉเจฐเฉ เจเจฐเฉเจ:
#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);
}
}
เจ เจธเฉเจ เจฌเจฟเจจเจพเจ เจเจฟเจธเฉ เจเฉฐเจกเฉ เจฆเฉ เจเฉฐเจชเจพเจเจฒ เจเจฐเจฆเฉ เจนเจพเจ:
$ gcc ./ld_rand.c -o ld_rand
เจ เจคเฉ, เจเจฟเจตเฉเจ เจเจฟ เจเจฎเฉเจฆ เจเฉเจคเฉ เจเจพเจเจฆเฉ เจธเฉ, เจธเจพเจจเฉเฉฐ 5 เจคเฉเจ เจเฉฑเจ 100 เจฌเฉเจคเจฐเจคเฉเจฌเฉ เจจเฉฐเจฌเจฐ เจชเฉเจฐเจพเจชเจค เจนเฉเฉฐเจฆเฉ เจนเจจ:
$ ./ld_rand
53
93
48
57
20
เจชเจฐ เจเจ เจเจฒเจชเจจเจพ เจเจฐเฉเจ เจเจฟ เจธเจพเจกเฉ เจเฉเจฒ เจชเฉเจฐเฉเจเจฐเจพเจฎ เจฆเจพ เจธเจฐเฉเจค เจเฉเจก เจจเจนเฉเจ เจนเฉ, เจชเจฐ เจธเจพเจจเฉเฉฐ เจตเจฟเจตเจนเจพเจฐ เจจเฉเฉฐ เจฌเจฆเจฒเจฃ เจฆเฉ เจฒเฉเฉ เจนเฉเฅค
เจเจ เจเจชเจฃเฉ เจเฉเจฆ เจฆเฉ เจซเฉฐเจเจธเจผเจจ เจชเฉเจฐเฉเจเฉเจเจพเจเจช เจจเจพเจฒ เจเจชเจฃเฉ เจฒเจพเจเจฌเฉเจฐเฉเจฐเฉ เจฌเจฃเจพเจเจ, เจเจฆเจพเจนเจฐเจจ เจฒเจ:
int rand(){
return 42;
}
$ gcc -shared -fPIC ./o_rand.c -o ld_rand.so
เจ เจคเฉ เจนเฉเจฃ เจธเจพเจกเฉ เจฌเฉเจคเจฐเจคเฉเจฌ เจเฉเจฃ เจเจพเจซเจผเฉ เจ เจจเฉเจฎเจพเจจเจฏเฉเจ เจนเฉ:
# LD_PRELOAD=$PWD/ld_rand.so ./ld_rand
42
42
42
42
42
เจเจน เจเจพเจฒ เจนเฉเจฐ เจตเฉ เจชเฉเจฐเจญเจพเจตเจธเจผเจพเจฒเฉ เจฆเจฟเจเจพเจ เจฆเจฟเฉฐเจฆเฉ เจนเฉ เจเฉเจเจฐ เจ เจธเฉเจ เจชเจนเจฟเจฒเจพเจ เจเจชเจฃเฉ เจฒเจพเจเจฌเฉเจฐเฉเจฐเฉ เจจเฉเฉฐ เจเจธ เจฐเจพเจนเฉเจ เจจเจฟเจฐเจฏเจพเจค เจเจฐเจฆเฉ เจนเจพเจ
$ export LD_PRELOAD=$PWD/ld_rand.so
เจเจพเจ เจ เจธเฉเจ เจเจธเจจเฉเฉฐ เจชเจนเจฟเจฒเจพเจ เจเจฐเจพเจเจเฉ
# echo "$PWD/ld_rand.so" > /etc/ld.so.preload
เจ เจคเฉ เจซเจฟเจฐ เจชเฉเจฐเฉเจเจฐเจพเจฎ เจจเฉเฉฐ เจเจฎ เจตเจพเจเจ เจเจฒเจพเจเฅค เจ เจธเฉเจ เจชเฉเจฐเฉเจเจฐเจพเจฎ เจตเจฟเฉฑเจ เจเฉเจก เจฆเฉ เจเฉฑเจ เจฒเจพเจเจจ เจจเฉเฉฐ เจจเจนเฉเจ เจฌเจฆเจฒเจฟเจ เจนเฉ, เจชเจฐ เจเจธเจฆเจพ เจตเจฟเจตเจนเจพเจฐ เจนเฉเจฃ เจธเจพเจกเฉ เจฒเจพเจเจฌเฉเจฐเฉเจฐเฉ เจตเจฟเฉฑเจ เจเฉฑเจ เจเฉเจเฉ เจซเฉฐเจเจธเจผเจจ 'เจคเฉ เจจเจฟเจฐเจญเจฐ เจเจฐเจฆเจพ เจนเฉเฅค เจเจธ เจคเฉเจ เจเจฒเจพเจตเจพ, เจชเฉเจฐเฉเจเจฐเจพเจฎ เจฒเจฟเจเจฃ เจฆเฉ เจธเจฎเฉเจ, เจฆ เจฐเฉเจก เจฎเฉเจเฉเจฆ เจตเฉ เจจเจนเฉเจ เจธเฉเฅค
เจธเจพเจกเฉ เจชเฉเจฐเฉเจเจฐเจพเจฎ เจจเฉเฉฐ เจเฉฑเจ เจจเจเจฒเฉ เจตเจฐเจคเจฃ เจฒเจ เจเฉ เจฌเจฃเจพเจเจ เจฐเฉเจก? เจเจ เจเจธ เจจเฉเฉฐ เจเจฆเจฎ เจฆเจฐ เจเจฆเจฎ เจเฉเฉฑเจเฉเจเฅค
เจเจฆเฉเจ เจเฉเจ เจเจชเจฒเฉเจเฉเจธเจผเจจ เจธเจผเฉเจฐเฉ เจนเฉเฉฐเจฆเฉ เจนเฉ, เจเฉเจ เจฒเจพเจเจฌเฉเจฐเฉเจฐเฉเจเจ เจฒเฉเจก เจนเฉเฉฐเจฆเฉเจเจ เจนเจจ เจเจฟเจจเฉเจนเจพเจ เจตเจฟเฉฑเจ เจชเฉเจฐเฉเจเจฐเจพเจฎ เจฆเฉเจเจฐเจพ เจฒเฉเฉเฉเจเจฆเฉ เจซเฉฐเจเจธเจผเจจ เจนเฉเฉฐเจฆเฉ เจนเจจเฅค เจ
เจธเฉเจ เจเจนเจจเจพเจ เจฆเฉ เจตเจฐเจคเฉเจ เจเจฐเจเฉ เจฆเฉเจ เจธเจเจฆเฉ เจนเจพเจ 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)
เจเจน เจธเฉเจเฉ OS เจธเฉฐเจธเจเจฐเจฃ เจฆเฉ เจเจงเจพเจฐ 'เจคเฉ เจตเฉฑเจเจฐเฉ เจนเฉ เจธเจเจฆเฉ เจนเฉ, เจชเจฐ เจเฉฑเจฅเฉ เจเฉฑเจ เจซเจพเจเจฒ เจนเฉเจฃเฉ เจเจพเจนเฉเจฆเฉ เจนเฉ libc.so. เจเจน เจเจน เจฒเจพเจเจฌเฉเจฐเฉเจฐเฉ เจนเฉ เจเฉ เจธเจฟเจธเจเจฎ เจเจพเจฒเจพเจ เจ เจคเฉ เจฌเฉเจจเจฟเจเจฆเฉ เจซเฉฐเจเจธเจผเจจ เจชเฉเจฐเจฆเจพเจจ เจเจฐเจฆเฉ เจนเฉ เจเจฟเจตเฉเจ เจเจฟ เจเจชเจจ, malloc, printf เจเจฆเจฟ เจธเจพเจกเฉ เจฐเฉเจก เจตเฉ เจเจจเฉเจนเจพเจ เจตเจฟเฉฑเจเฉเจ เจนเฉเฅค เจเจ เจเจน เจฏเจเฉเจจเฉ เจเจฐเฉเจ:
# nm -D /lib/x86_64-linux-gnu/libc.so.6 | grep " rand$"
000000000003aef0 T rand
เจเจ เจฆเฉเจเฉเจ เจเจฟ เจเฉ เจฒเจพเจเจฌเฉเจฐเฉเจฐเฉเจเจ เจฆเจพ เจธเฉเฉฑเจ เจตเจฐเจคเจฟเจ เจเจพเจเจฆเจพ เจนเฉ 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)
เจชเจคเจพ เจเจฒเจฆเจพ เจนเฉ เจเจฟ เจตเฉเจฐเฉเจเจฌเจฒ เจธเฉเฉฑเจ เจนเฉ LD_PRELOAD เจธเจพเจจเฉเฉฐ เจฒเฉเจก เจเจฐเจจ เจฒเจ เจฎเจเจฌเฉเจฐ เจเจฐเจฆเจพ เจนเฉ ld_rand.so เจเจธ เจคเฉฑเจฅ เจฆเฉ เจฌเจพเจตเจเฉเจฆ เจเจฟ เจชเฉเจฐเฉเจเจฐเจพเจฎ เจจเฉเฉฐ เจเฉเจฆ เจเจธเจฆเฉ เจฒเฉเฉ เจจเจนเฉเจ เจนเฉ. เจ เจคเฉ, เจธเจพเจกเฉ เจซเฉฐเจเจธเจผเจจ เจคเฉเจ "เจฐเฉเจเจก" เจคเฉเจ เจชเจนเจฟเจฒเจพเจ เจฒเฉเจก เจนเฉเฉฐเจฆเจพ เจนเฉ เจฐเฉเจก เจคเฉฑเจ libc.so, เจซเจฟเจฐ เจเจน เจฐเฉเจธเจ 'เจคเฉ เจฐเจพเจ เจเจฐเจฆเฉ เจนเฉเฅค
เจ เฉเจ เจนเฉ, เจ เจธเฉเจ เจจเฉเจเจฟเจต เจซเฉฐเจเจธเจผเจจ เจจเฉเฉฐ เจฌเจฆเจฒเจฃ เจฆเจพ เจชเฉเจฐเจฌเฉฐเจง เจเฉเจคเจพ เจนเฉ, เจชเจฐ เจ เจธเฉเจ เจเจน เจเจฟเจตเฉเจ เจฏเจเฉเจจเฉ เจฌเจฃเจพ เจธเจเจฆเฉ เจนเจพเจ เจเจฟ เจเจธเจฆเฉ เจเจพเจฐเจเจธเจผเฉเจฒเจคเจพ เจจเฉเฉฐ เจธเฉเจฐเฉฑเจเจฟเจ เจค เจฐเฉฑเจเจฟเจ เจเจฟเจ เจนเฉ เจ เจคเฉ เจเฉเจ เจเจฟเจฐเจฟเจเจตเจพเจ เจเฉเฉเฉเจเจ เจเจเจเจ เจนเจจเฅค เจเจ เจธเจพเจกเฉ เจฌเฉเจคเจฐเจคเฉเจฌเฉ เจจเฉเฉฐ เจธเฉฐเจธเจผเฉเจงเจฟเจค เจเจฐเฉเจ:
#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();
}
เจเฉฑเจฅเฉ, เจธเจพเจกเฉ "เจเฉเฉ" เจตเจเฉเจ, เจ เจธเฉเจ เจเฉเจเจธเจ เจฆเฉ เจธเจฟเจฐเจซ เจเฉฑเจ เจฒเจพเจเจจ เจจเฉเฉฐ เจชเฉเจฐเจฟเฉฐเจ เจเจฐเจฆเฉ เจนเจพเจ, เจเจฟเจธ เจคเฉเจ เจฌเจพเจ เจฆ เจ เจธเฉเจ เจ เจธเจฒ เจซเฉฐเจเจธเจผเจจ เจฒเจ เจเฉฑเจ เจชเฉเจเจเฉฐเจเจฐ เจฌเจฃเจพเจเจเจฆเฉ เจนเจพเจ เจฐเฉเจก. เจเจธ เจซเฉฐเจเจธเจผเจจ เจฆเจพ เจชเจคเจพ เจชเฉเจฐเจพเจชเจค เจเจฐเจจ เจฒเจ เจธเจพเจจเฉเฉฐ เจฒเฉเฉ เจนเฉ dlsym เจฒเจพเจเจฌเฉเจฐเฉเจฐเฉ เจฆเจพ เจเฉฑเจ เจซเฉฐเจเจธเจผเจจ เจนเฉ libdlเจเฉ เจธเจพเจกเฉ เจฒเฉฑเจญ เจเจพเจตเฉเจเจพ เจฐเฉเจก เจเจคเฉเจธเจผเฉเจฒ เจฒเจพเจเจฌเฉเจฐเฉเจฐเฉเจเจ เจฆเฉ เจธเจเฉเจ เจตเจฟเฉฑเจ. เจเจฟเจธ เจคเฉเจ เจฌเจพเจ เจฆ เจ เจธเฉเจ เจเจธ เจซเฉฐเจเจธเจผเจจ เจจเฉเฉฐ เจเจพเจฒ เจเจฐเจพเจเจเฉ เจ เจคเฉ เจเจธเจฆเจพ เจฎเฉเฉฑเจฒ เจตเจพเจชเจธ เจเจฐเจพเจเจเฉเฅค เจเจธ เจ เจจเฉเจธเจพเจฐ, เจธเจพเจจเฉเฉฐ เจเฉเฉเจจ เจฆเฉ เจเจผเจฐเฉเจฐเจค เจนเฉเจเจเฉ "-ldl" เจ เจธเฉเจเจฌเจฒเฉ เจฆเฉ เจฆเฉเจฐเจพเจจ:
$ 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
เจ เจคเฉ เจธเจพเจกเจพ เจชเฉเจฐเฉเจเจฐเจพเจฎ "เจฆเฉเจธเฉ" เจฆเฉ เจตเจฐเจคเฉเจ เจเจฐเจฆเจพ เจนเฉ เจฐเฉเจก, เจชเจนเจฟเจฒเจพเจ เจเฉเจ เจ เจธเจผเจฒเฉเจฒ เจนเจฐเจเจคเจพเจ เจเจฐ เจเฉเฉฑเจเฉ เจนเจจเฅค
2. เจเฉเจ เจฆเจพ เจฆเจฐเจฆ
เจเจฟเจธเฉ เจธเฉฐเจญเจพเจตเฉ เจเจคเจฐเฉ เจฌเจพเจฐเฉ เจเจพเจฃเจฆเฉ เจนเฉเจ, เจ เจธเฉเจ เจเจธเจฆเจพ เจชเจคเจพ เจฒเจเจพเจเจฃเจพ เจเจพเจนเฉเฉฐเจฆเฉ เจนเจพเจ เจชเฉเจฐเฉเจฒเฉเจก เจชเฉเจฐเจพ เจเฉเจคเจพ เจเจฟเจ เจธเฉ. เจเจน เจธเจชเฉฑเจธเจผเจ เจนเฉ เจเจฟ เจเฉเจ เจเจฐเจจ เจฆเจพ เจธเจญ เจคเฉเจ เจตเจงเฉเจ เจคเจฐเฉเจเจพ เจเจธ เจจเฉเฉฐ เจเจฐเจจเจฒ เจตเจฟเฉฑเจ เจงเฉฑเจเจฃเจพ เจนเฉ, เจชเจฐ เจฎเฉเจ เจฏเฉเจเจผเจฐเจธเจชเฉเจธ เจตเจฟเฉฑเจ เจเฉเจ เจตเจฟเจเจฒเจชเจพเจ เจตเจฟเฉฑเจ เจฆเจฟเจฒเจเจธเจชเฉ เจฐเฉฑเจเจฆเจพ เจธเฉ.
เจ เฉฑเจเฉ, เจเฉเจ เจ เจคเฉ เจเจนเจจเจพเจ เจฆเฉ เจเฉฐเจกเจจ เจฒเจ เจนเฉฑเจฒ เจเฉเฉเจฟเจเจ เจตเจฟเฉฑเจ เจเจเจฃเจเฉเฅค
2.1 เจเจ เจธเจงเจพเจฐเจจ เจธเจผเฉเจฐเฉ เจเจฐเฉเจ
เจเจฟเจตเฉเจ เจชเจนเจฟเจฒเจพเจ เจฆเฉฑเจธเจฟเจ เจเจฟเจ เจนเฉ, เจคเฉเจธเฉเจ เจตเฉเจฐเฉเจเจฌเจฒ เจฆเฉ เจตเจฐเจคเฉเจ เจเจฐเจเฉ เจฒเฉเจก เจเจฐเจจ เจฒเจ เจฒเจพเจเจฌเฉเจฐเฉเจฐเฉ เจจเฉเฉฐ เจจเจฟเจธเจผเจเจฟเจค เจเจฐ เจธเจเจฆเฉ เจนเฉ LD_PRELOAD เจเจพเจ เจเจธเจจเฉเฉฐ เจเฉฑเจ เจซเจพเจเจฒ เจตเจฟเฉฑเจ เจฒเจฟเจ เจเฉ /etc/ld.so.preload. เจเจ เจฆเฉ เจธเจงเจพเจฐเจจ เจกเจฟเจเฉเจเจเจฐ เจฌเจฃเจพเจ.
เจธเจญ เจคเฉเจ เจชเจนเจฟเจฒเจพเจ เจธเฉเฉฑเจ เจตเจพเจคเจพเจตเจฐเจจ เจตเฉเจฐเฉเจเจฌเจฒ เจฆเฉ เจเจพเจเจ เจเจฐเจจเจพ เจนเฉ:
#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");
}
เจฆเฉเจเจพ เจเจน เจเจพเจเจ เจเจฐเจจเจพ เจนเฉ เจเจฟ เจเฉ เจซเจพเจเจฒ เจเฉเฉฑเจฒเฉเจนเฉ เจนเฉ:
#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");
}
เจเจ เจฒเจพเจเจฌเฉเจฐเฉเจฐเฉเจเจ เจจเฉเฉฐ เจฒเฉเจก เจเจฐเฉเจ:
$ 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) [+]
เจเฉฑเจฅเฉ เจ
เจคเฉ เจนเฉเจ เจพเจ, [+] เจธเจซเจฒ เจเฉเจ เจจเฉเฉฐ เจฆเจฐเจธเจพเจเจเจฆเจพ เจนเฉเฅค
เจเจธ เจ
เจจเฉเจธเจพเจฐ, [-] เจฆเจพ เจ
เจฐเจฅ เจนเฉ เจเฉเจ เจจเฉเฉฐ เจฌเจพเจเจชเจพเจธ เจเจฐเจจเจพเฅค
เจ เจเจฟเจนเจพ เจกเจฟเจเฉเจเจเจฐ เจเจฟเฉฐเจจเจพ เจชเฉเจฐเจญเจพเจตเจธเจผเจพเจฒเฉ เจนเฉ? เจเจ เจชเจนเจฟเจฒเจพเจ เจตเจพเจคเจพเจตเจฐเจฃ เจตเฉเจฐเฉเจเจฌเจฒ 'เจคเฉ เจเฉฑเจ เจจเจเจผเจฐ เจฎเจพเจฐเฉเจ:
#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) [-]
เจเจธเฉ เจคเจฐเฉเจนเจพเจ, เจ เจธเฉเจ เจเฉเฉฑเจ เจคเฉเจ เจเฉเจเจเจพเจฐเจพ เจชเจพเจเจเจฆเฉ เจนเจพเจ เจเจชเจจ:
#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) [-]
เจนเจพเจ, เจซเจพเจเจฒ เจคเฉฑเจ เจชเจนเฉเฉฐเจ เจเจฐเจจ เจฆเฉ เจนเฉเจฐ เจคเจฐเฉเจเฉ เจเฉฑเจฅเฉ เจตเจฐเจคเฉ เจเจพ เจธเจเจฆเฉ เจนเจจ, เจเจฟเจตเฉเจ เจเจฟ, open64, เจธเจเฉเจ เจเจฆเจฟ, เจชเจฐ, เจ เจธเจฒ เจตเจฟเฉฑเจ, เจเจนเจจเจพเจ เจจเฉเฉฐ เจงเฉเจเจพ เจฆเฉเจฃ เจฒเจ เจเฉเจก เจฆเฉเจเจ เจเจนเฉ 5-10 เจฒเจพเจเจจเจพเจ เจฆเฉ เจฒเฉเฉ เจนเฉเฉฐเจฆเฉ เจนเฉเฅค
2.2 เจเจฒเฉ เจ เฉฑเจเฉ เจตเจงเจฆเฉ เจนเจพเจ
เจเฉฑเจชเจฐ เจ เจธเฉเจ เจตเจฐเจคเจฟเจ getenv() เจฎเฉเฉฑเจฒ เจชเฉเจฐเจพเจชเจค เจเจฐเจจ เจฒเจ LD_PRELOAD, เจชเจฐ เจชเจนเฉเฉฐเจเจฃ เจฒเจ เจเฉฑเจ เจนเฉเจฐ "เจจเฉเจตเฉเจ-เจชเฉฑเจงเจฐ" เจฆเจพ เจคเจฐเฉเจเจพ เจตเฉ เจนเฉ ENV- เจตเฉเจฐเฉเจเจฌเจฒเฅค เจ เจธเฉเจ เจตเจฟเจเจเจพเจฐเจฒเฉ เจซเฉฐเจเจธเจผเจจเจพเจ เจฆเฉ เจตเจฐเจคเฉเจ เจจเจนเฉเจ เจเจฐเจพเจเจเฉ, เจชเจฐ เจเจฐเฉ เจฆเจพ เจนเจตเจพเจฒเจพ เจฆเฉเจตเจพเจเจเฉ ** เจตเจพเจคเจพเจตเจฐเจฃ, เจเฉ เจตเจพเจคเจพเจตเจฐเจฃ เจฆเฉ เจเฉฑเจ เจเจพเจชเฉ เจธเจเฉเจฐ เจเจฐเจฆเจพ เจนเฉ:
#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;
}
เจเจฟเจเจเจเจฟ เจเฉฑเจฅเฉ เจ เจธเฉเจ เจฎเฉเจฎเฉเจฐเฉ เจคเฉเจ เจธเจฟเฉฑเจงเจพ เจกเฉเจเจพ เจชเฉเฉเจน เจฐเจนเฉ เจนเจพเจ, เจ เจเจฟเจนเฉ เจเจพเจฒ เจจเฉเฉฐ เจฐเฉเจเจฟเจ เจจเจนเฉเจ เจเจพ เจธเจเจฆเจพ, เจ เจคเฉ เจธเจพเจกเฉ undetect_getenv เจเจน เจนเฉเจฃ เจเฉเจธเจชเฉเจ เจฆเฉ เจชเจเจพเจฃ เจเจฐเจจ เจตเจฟเฉฑเจ เจฆเจเจฒ เจจเจนเฉเจ เจฆเจฟเฉฐเจฆเจพเฅค
$ LD_PRELOAD=./ld_undetect_getenv.so ./detect_environ
LD_PRELOAD (**environ) [+]
เจ เจเจฟเจนเจพ เจฒเจเจฆเจพ เจนเฉ เจเจฟ เจเจน เจธเจฎเฉฑเจธเจฟเจ เจนเฉฑเจฒ เจนเฉ เจเจ เจนเฉ? เจเจน เจ เจเฉ เจคเจพเจ เจธเจผเฉเจฐเฉเจเจค เจนเฉเฅค
เจชเฉเจฐเฉเจเจฐเจพเจฎ เจธเจผเฉเจฐเฉ เจนเฉเจฃ เจคเฉเจ เจฌเจพเจ เจฆ, เจตเฉเจฐเฉเจเจฌเจฒ เจฆเจพ เจฎเฉเฉฑเจฒ LD_PRELOAD เจนเฉเจเจฐเจพเจ เจจเฉเฉฐ เจนเฉเจฃ เจฎเฉเจฎเฉเจฐเฉ เจตเจฟเฉฑเจ เจเจธเจฆเฉ เจฒเฉเฉ เจจเจนเฉเจ เจนเฉ, เจฏเจพเจจเฉ เจเจน เจเจธเจจเฉเฉฐ เจชเฉเฉเจน เจธเจเจฆเฉ เจนเจจ เจ เจคเฉ เจเจฟเจธเฉ เจตเฉ เจจเจฟเจฐเจฆเฉเจธเจผ เจจเฉเฉฐ เจฒเจพเจเฉ เจเจฐเจจ เจคเฉเจ เจชเจนเจฟเจฒเจพเจ เจเจธเจจเฉเฉฐ เจฎเจฟเจเจพ เจธเจเจฆเฉ เจนเจจเฅค เจฌเฉเจธเจผเฉฑเจ, เจฎเฉเจฎเฉเจฐเฉ เจตเจฟเฉฑเจ เจเฉฑเจ เจเจฐเฉ เจจเฉเฉฐ เจธเฉฐเจชเจพเจฆเจฟเจค เจเจฐเจจเจพ, เจเฉฑเจเฉ เจเฉฑเจ, เจเฉฑเจ เจฎเจพเฉเฉ เจชเฉเจฐเฉเจเฉเจฐเจพเจฎเจฟเฉฐเจ เจธเจผเฉเจฒเฉ เจนเฉ, เจชเจฐ เจเจน เจเจฟเจธเฉ เจ เจเจฟเจนเฉ เจตเจฟเจ เจเจคเฉ เจจเฉเฉฐ เจเจฟเจตเฉเจ เจฐเฉเจ เจธเจเจฆเจพ เจนเฉ เจเฉ เจ เจธเจฒ เจตเจฟเฉฑเจ เจธเจพเจกเฉ เจญเจฒเจพเจ เจจเจนเฉเจ เจเจพเจนเฉเฉฐเจฆเจพ เจนเฉ?
เจ เจเจฟเจนเจพ เจเจฐเจจ เจฒเจ เจธเจพเจจเฉเฉฐ เจเจชเจฃเจพ เจซเจฐเจเจผเฉ เจซเฉฐเจเจธเจผเจจ เจฌเจฃเจพเจเจฃ เจฆเฉ เจฒเฉเฉ เจนเฉ เจเจธ เจตเจฟเฉฑเจ(), เจเจฟเจธ เจตเจฟเฉฑเจ เจ เจธเฉเจ เจเฉฐเจธเจเจพเจฒ เจจเฉเฉฐ เจฐเฉเจเจฆเฉ เจนเจพเจ LD_PRELOAD เจ เจคเฉ เจเจธเจจเฉเฉฐ เจธเจพเจกเฉ เจฒเจฟเฉฐเจเจฐ เจจเฉเฉฐ เจญเฉเจเฉ:
#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;
}
เจ เจธเฉเจ เจเจฒเจพเจเจเจฆเฉ เจนเจพเจ เจ เจคเฉ เจเจพเจเจ เจเจฐเจฆเฉ เจนเจพเจ:
$ 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/
เจนเจพเจฒเจพเจเจเจฟ, เจฎเฉเจฎเฉเจฐเฉ เจเจเจฐเฉ เจฅเจพเจ เจจเจนเฉเจ เจนเฉ เจเจฟเฉฑเจฅเฉ เจคเฉเจธเฉเจ เจเฉฑเจ เจฌเจฆเจฒ เจฒเฉฑเจญ เจธเจเจฆเฉ เจนเฉ LD_PRELOAD, เจตเฉ เจนเฉ /proc/. เจเจ เจธเจชเฉฑเจธเจผเจ เจจเจพเจฒ เจธเจผเฉเจฐเฉ เจเจฐเฉเจ /proc/{PID}/เจตเจพเจคเจพเจตเจฐเจฃ.
เจตเจพเจธเจคเจต เจตเจฟเฉฑเจ, เจฒเจ เจเฉฑเจ เจตเจฟเจเจชเจ เจนเฉฑเจฒ เจนเฉ เจชเจคเจพ เจฒเจเจพเจเจฃเจพ ** เจตเจพเจคเจพเจตเจฐเจฃ ะธ /proc/self/environ. เจธเจฎเฉฑเจธเจฟเจ "เจเจฒเจค" เจตเจฟเจตเจนเจพเจฐ เจนเฉ unsetenv(env).
เจธเจนเฉ เจเฉเจฃ
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
$
เจชเจฐ เจเจ เจเจฒเจชเจจเจพ เจเจฐเฉเจ เจเจฟ เจธเจพเจจเฉเฉฐ เจเจน เจจเจนเฉเจ เจฎเจฟเจฒเจฟเจ เจ เจคเฉ /proc/self/environ "เจธเจฎเฉฑเจธเจฟเจ เจตเจพเจฒเจพ" เจกเฉเจเจพ เจฐเฉฑเจเจฆเจพ เจนเฉเฅค
เจชเจนเจฟเจฒเจพเจ เจเจชเจฃเฉ เจชเจฟเจเจฒเฉ "เจญเฉเจธ" เจจเจพเจฒ เจเฉเจธเจผเจฟเจธเจผ เจเจฐเฉเจ:
$ (LD_PRELOAD=./ld_undetect_environ.so cat /proc/self/environ; echo) | tr " 00" "n" | grep -F LD_PRELOAD
LD_PRELOAD=./ld_undetect_environ.so
เจฌเจฟเฉฑเจฒเฉ เจซเจพเจเจฒ เจจเฉเฉฐ เจเฉเจฒเฉเจนเจฃ เจฒเจ เจเจธเฉ เจจเฉเฉฐ เจตเจฐเจคเจฆเจพ เจนเฉ เจเฉเจฒเฉเจนเฉ(), เจเจธ เจฒเจ เจนเฉฑเจฒ เจเจธเฉ เจคเจฐเฉเจนเจพเจ เจฆเจพ เจนเฉ เจเฉ เจชเจนเจฟเจฒเจพเจ เจนเฉ เจธเฉเจเจธเจผเจจ 2.1 เจตเจฟเฉฑเจ เจเฉเจคเจพ เจเจฟเจ เจธเฉ, เจชเจฐ เจนเฉเจฃ เจ เจธเฉเจ เจเฉฑเจ เจ เจธเจฅเจพเจ เจซเจพเจเจฒ เจฌเจฃเจพเจเจเจฆเฉ เจนเจพเจ เจเจฟเฉฑเจฅเฉ เจ เจธเฉเจ เจธเฉฑเจเฉ เจฎเฉเจฎเฉเจฐเฉ เจฆเฉ เจฎเฉเฉฑเจฒเจพเจ เจจเฉเฉฐ เจฌเจฟเจจเจพเจ เจฒเจพเจเจจเจพเจ เจฆเฉ เจเจพเจชเฉ เจเจฐเจฆเฉ เจนเจพเจ 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);
}
เจ เจคเฉ เจเจน เจชเฉเจพเจ เจชเจพเจธ เจเฉเจคเจพ เจเจฟเจ เจนเฉ:
$ (LD_PRELOAD=./ld_undetect_proc_environ.so cat /proc/self/environ; echo) | tr " 00" "n" | grep -F LD_PRELOAD
$
เจ เจเจฒเจพ เจธเจชเฉฑเจธเจผเจ เจธเจฅเจพเจจ เจนเฉ /proc/self/maps. เจเจธ 'เจคเฉ เจเจฟเจเฉ เจฐเจนเจฟเจฃ เจฆเจพ เจเฉเจ เจฎเจคเจฒเจฌ เจจเจนเฉเจ เจนเฉเฅค เจนเฉฑเจฒ เจฌเจฟเจฒเจเฉเจฒ เจชเจฟเจเจฒเฉ เจเฉฑเจ เจฆเฉ เจธเจฎเจพเจจ เจนเฉ: เจซเจพเจเจฒ เจคเฉเจ เจกเฉเจเจพ เจจเฉเฉฐ เจเจพเจชเฉ เจเจฐเฉ libc.so ะธ ld.so.
2.4 เจเฉเจเจชเฉเจเจเฉฐเจ เจคเฉเจ เจตเจฟเจเจฒเจช
เจฎเฉเจจเฉเฉฐ เจเจพเจธ เจคเฉเจฐ 'เจคเฉ เจเจธเจฆเฉ เจธเจพเจฆเจเฉ เจฒเจ เจเจน เจนเฉฑเจฒ เจชเจธเฉฐเจฆ เจเจเจ. เจ เจธเฉเจ เจธเจฟเฉฑเจงเฉ เจฒเฉเจก เจเฉเจคเฉ เจซเฉฐเจเจธเจผเจจเจพเจ เจฆเฉ เจชเจคเจฟเจเจ เจฆเฉ เจคเฉเจฒเจจเจพ เจเจฐเจฆเฉ เจนเจพเจ libc, เจ เจคเฉ "เจ เฉฑเจเฉ" เจชเจคเฉเฅค
#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;
}
เจเฉฐเจเจฐเจธเฉเจชเจธเจผเจจ เจจเจพเจฒ เจฒเจพเจเจฌเฉเจฐเฉเจฐเฉ เจจเฉเฉฐ เจฒเฉเจก เจเฉเจคเจพ เจเจพ เจฐเจฟเจนเจพ เจนเฉ "เจเจชเจจ()" เจ เจคเฉ เจเจพเจเจ เจเจฐเฉ:
$ export LD_PRELOAD=$PWD/ld_undetect_open.so
$ ./detect_chokepoint
LD_PRELOAD (syscall - open) [+]
Libc address: 0x7fa86893b160
Next address: 0x7fa868a26135
เจเฉฐเจกเจจ เจนเฉเจฐ เจตเฉ เจธเจฐเจฒ เจจเจฟเจเจฒเจฟเจ:
#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 เจธเจฟเจธเจเฉเจฒเจธ
เจเจน เจฒเจเจฆเจพ เจนเฉ เจเจฟ เจเจน เจธเจญ เจนเฉ, เจชเจฐ เจ เจธเฉเจ เจซเจฟเจฐ เจตเฉ เจญเจเจ เจเจพเจตเจพเจเจเฉ. เจเฉเจเจฐ เจ เจธเฉเจ เจธเจฟเจธเจเจฎ เจเจพเจฒ เจจเฉเฉฐ เจธเจฟเฉฑเจงเจพ เจเจฐเจจเจฒ 'เจคเฉ เจญเฉเจเจฆเฉ เจนเจพเจ, เจคเจพเจ เจเจน เจชเฉเจฐเฉ เจเฉฐเจเจฐเจธเฉเจชเจธเจผเจจ เจชเฉเจฐเจเจฟเจฐเจฟเจ เจจเฉเฉฐ เจฌเจพเจเจชเจพเจธ เจเจฐ เจฆเฉเจตเฉเจเจพเฅค เจนเฉเจ เจพเจ เจฆเจฟเฉฑเจคเจพ เจนเฉฑเจฒ เจนเฉ, เจฌเฉเจธเจผเจ, เจเจฐเจเฉเจเฉเจเจเจฐ-เจจเจฟเจฐเจญเจฐ (x86_64). เจเจ เจเฉฑเจ เจเฉเฉฑเจฒเจฃ เจฆเจพ เจชเจคเจพ เจฒเจเจพเจเจฃ เจฒเจ เจเจธเจจเฉเฉฐ เจฒเจพเจเฉ เจเจฐเจจ เจฆเฉ เจเฉเจธเจผเจฟเจธเจผ เจเจฐเฉเจ 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) [+]
เจ เจคเฉ เจเจธ เจธเจฎเฉฑเจธเจฟเจ เจฆเจพ เจเฉฑเจ เจนเฉฑเจฒ เจนเฉ. เจคเฉเจ เจ เฉฐเจธเจผ เจเจฆเจฎเฉ'เจ:
ptrace เจเฉฑเจ เจ เจเจฟเจนเจพ เจเฉเจฒ เจนเฉ เจเฉ เจเฉฑเจ เจชเฉเจฐเฉเจเจ เจชเฉเจฐเจเจฟเจฐเจฟเจ เจจเฉเฉฐ เจเจฟเจธเฉ เจนเฉเจฐ เจชเฉเจฐเจเจฟเจฐเจฟเจ เจฆเฉ เจชเฉเจฐเจเจคเฉ เจจเฉเฉฐ เจฆเฉเจเจฃ เจ เจคเฉ เจจเจฟเจฏเฉฐเจคเจฐเจฃ เจเจฐเจจ, เจเจธเจฆเฉ เจกเฉเจเจพ เจ เจคเฉ เจฐเจเจฟเจธเจเจฐเจพเจ เจจเฉเฉฐ เจตเฉเจเจฃ เจ เจคเฉ เจฌเจฆเจฒเจฃ เจฆเฉ เจเจเจฟเจ เจฆเจฟเฉฐเจฆเจพ เจนเฉเฅค เจเจฎ เจคเฉเจฐ 'เจคเฉ เจเจน เจซเฉฐเจเจธเจผเจจ เจกเฉเจฌเฉฑเจเจฟเฉฐเจ เจชเฉเจฐเฉเจเจฐเจพเจฎ เจตเจฟเฉฑเจ เจฌเฉเจฐเฉเจเจชเฉเจเจเฉฐเจ เจฌเจฃเจพเจเจฃ เจ เจคเฉ เจธเจฟเจธเจเจฎ เจเจพเจฒเจพเจ เจฆเฉ เจจเจฟเจเจฐเจพเจจเฉ เจเจฐเจจ เจฒเจ เจตเจฐเจคเจฟเจ เจเจพเจเจฆเจพ เจนเฉเฅค
เจชเฉเจฐเฉเจเจ เจชเฉเจฐเจเจฟเจฐเจฟเจ เจชเจนเจฟเจฒเจพเจ เจซเฉเจฐเจ (2) เจจเฉเฉฐ เจเจพเจฒ เจเจฐเจเฉ เจเจฐเฉเจธเจฟเฉฐเจ เจธเจผเฉเจฐเฉ เจเจฐ เจธเจเจฆเฉ เจนเฉ, เจ เจคเฉ เจซเจฟเจฐ เจจเจคเฉเจเฉ เจตเจเฉเจ เจเจพเจเจฒเจก เจชเฉเจฐเจเจฟเจฐเจฟเจ PTRACE_TRACEME เจจเฉเฉฐ เจเจฒเจพ เจธเจเจฆเฉ เจนเฉ, (เจเจฎ เจคเฉเจฐ 'เจคเฉ) exec(3) เจจเฉเฉฐ เจฒเจพเจเฉ เจเจฐเจเฉเฅค เจฆเฉเจเฉ เจชเจพเจธเฉ, เจเฉฑเจ เจชเฉเจฐเฉเจเจ เจชเฉเจฐเจเจฟเจฐเจฟเจ PTRACE_ATTACH เจฆเฉ เจตเจฐเจคเฉเจ เจเจฐเจเฉ เจฎเฉเจเฉเจฆเจพ เจชเฉเจฐเจเจฟเจฐเจฟเจ เจจเฉเฉฐ เจกเฉเจฌเฉฑเจ เจเจฐเจจเจพ เจธเจผเฉเจฐเฉ เจเจฐ เจธเจเจฆเฉ เจนเฉเฅค
เจเจฆเฉเจ เจเจฐเฉเจธเจฟเฉฐเจ เจเฉเจคเฉ เจเจพเจเจฆเฉ เจนเฉ, เจคเจพเจ เจฌเฉฑเจเฉ เจฆเฉ เจชเฉเจฐเจเจฟเจฐเจฟเจ เจนเจฐ เจตเจพเจฐ เจธเจฟเจเจจเจฒ เจชเฉเจฐเจพเจชเจค เจเจฐเจจ 'เจคเฉ เจฌเฉฐเจฆ เจนเฉ เจเจพเจเจฆเฉ เจนเฉ, เจญเจพเจตเฉเจ เจธเจฟเจเจจเจฒ เจจเฉเฉฐ เจ เจฃเจกเจฟเฉฑเจ เจเฉเจคเจพ เจเจฟเจ เจนเฉเจตเฉเฅค (เจ เจชเจตเจพเจฆ SIGKILL เจนเฉ, เจเฉ เจเจฎ เจคเฉเจฐ 'เจคเฉ เจเฉฐเจฎ เจเจฐเจฆเจพ เจนเฉเฅค) เจฎเจพเจคเจพ-เจชเจฟเจคเจพ เจฆเฉ เจชเฉเจฐเจเจฟเจฐเจฟเจ เจจเฉเฉฐ เจเจกเฉเจ (2) เจจเฉเฉฐ เจเจพเจฒ เจเจฐเจเฉ เจเจธ เจฌเจพเจฐเฉ เจธเฉเจเจฟเจค เจเฉเจคเจพ เจเจพเจตเฉเจเจพ, เจเจฟเจธ เจคเฉเจ เจฌเจพเจ เจฆ เจเจน เจธเจผเฉเจฐเฉ เจนเฉเจฃ เจคเฉเจ เจชเจนเจฟเจฒเจพเจ เจฌเฉฑเจเฉ เจฆเฉ เจชเฉเจฐเจเจฟเจฐเจฟเจ เจฆเฉ เจธเจฎเฉฑเจเจฐเฉ เจจเฉเฉฐ เจฆเฉเจ เจ เจคเฉ เจธเฉเจง เจธเจเจฆเจพ เจนเฉเฅค เจฎเจพเจคเจพ-เจชเจฟเจคเจพ เจฆเฉ เจชเฉเจฐเจเจฟเจฐเจฟเจ เจซเจฟเจฐ เจฌเฉฑเจเฉ เจจเฉเฉฐ เจฆเฉเฉเจจเจพ เจเจพเจฐเฉ เจฐเฉฑเจเจฃ เจฆเฉ เจเจเจพเจเจผเจค เจฆเจฟเฉฐเจฆเฉ เจนเฉ, เจเฉเจ เจฎเจพเจฎเจฒเจฟเจเจ เจตเจฟเฉฑเจ เจเจธ เจจเฉเฉฐ เจญเฉเจเฉ เจเจ เจธเจฟเจเจจเจฒ เจจเฉเฉฐ เจจเจเจผเจฐเจ เฉฐเจฆเจพเจเจผ เจเจฐเจจเจพ เจเจพเจ เจเจธ เจฆเฉ เจฌเจเจพเจ เจเฉเจ เจนเฉเจฐ เจธเจฟเจเจจเจฒ เจญเฉเจเจฃเจพ)เฅค
เจเจธ เจคเจฐเฉเจนเจพเจ, เจนเฉฑเจฒ เจชเฉเจฐเจเจฟเจฐเจฟเจ เจฆเฉ เจจเจฟเจเจฐเจพเจจเฉ เจเจฐเจจเจพ เจนเฉ, เจนเจฐเฉเจ เจธเจฟเจธเจเจฎ เจเจพเจฒ เจคเฉเจ เจชเจนเจฟเจฒเจพเจ เจเจธ เจจเฉเฉฐ เจฌเฉฐเจฆ เจเจฐเจจเจพ เจ เจคเฉ, เจเฉ เจเจฐเฉเจฐเฉ เจนเฉ, เจคเจพเจ เจฅเจฐเจฟเฉฑเจก เจจเฉเฉฐ เจนเฉเฉฑเจ เจซเฉฐเจเจธเจผเจจ เจคเฉ เจฐเฉเจกเจพเจเจฐเฉเจเจ เจเจฐเจจเจพ เจนเฉเฅค
#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);
}
}
เจ เจธเฉเจ เจเจพเจเจเจฆเฉ เจนเจพเจ:
$ ./detect_syscall
LD_PRELOAD (open syscall) [+]
$ LD_PRELOAD=./ld_undetect_syscall.so ./detect_syscall
LD_PRELOAD (open syscall) [-]
+0-0=5
เจฌเจนเฉเจค เจธเจพเจฐเจพ เจงเฉฐเจจเจตเจพเจฆ
, เจเจฟเจจเฉเจนเจพเจ เจฆเฉ เจฒเฉเจเจพเจ, เจธเจฐเฉเจคเจพเจ เจ
เจคเฉ เจเจฟเฉฑเจชเจฃเฉเจเจ เจจเฉ เจเจธ เจจเฉเจ เจจเฉเฉฐ เจเฉฑเจฅเฉ เจชเฉเจฐเจเจ เจเจฐเจจ เจฒเจ เจฎเฉเจฐเฉ เจจเจพเจฒเฉเจ เจเจฟเจคเฉ เจตเฉฑเจง เจเฉเจคเจพ เจนเฉเฅค
เจธเจฐเฉเจค: www.habr.com
