LD_PRELOAD เจฆเฉ€ เจญเจพเจฒ เจ•เฉ€เจคเฉ€ เจœเจพ เจฐเจนเฉ€ เจนเฉˆ

เจ‡เจน เจจเฉ‹เจŸ 2014 เจตเจฟเฉฑเจš เจฒเจฟเจ–เจฟเจ† เจ—เจฟเจ† เจธเฉ€, เจชเจฐ เจฎเฉˆเจ‚ เจนเฉเจฃเฉ‡ เจนเฉ€ เจนเฉˆเจฌเจฐเฉ‡ 'เจคเฉ‡ เจœเจฌเจฐ เจฆเฉ‡ เจ…เจงเฉ€เจจ เจ†เจ‡เจ† เจนเจพเจ‚ เจ…เจคเฉ‡ เจ‡เจธ เจจเฉ‡ เจฆเจฟเจจ เจฆเฉ€ เจฐเฉŒเจธเจผเจจเฉ€ เจจเจนเฉ€เจ‚ เจตเฉ‡เจ–เฉ€เฅค เจชเจพเจฌเฉฐเจฆเฉ€ เจฆเฉ‡ เจฆเฉŒเจฐเจพเจจ เจฎเฉˆเจ‚ เจ‡เจธ เจฌเจพเจฐเฉ‡ เจญเฉเฉฑเจฒ เจ—เจฟเจ† เจธเฉ€, เจชเจฐ เจนเฉเจฃ เจฎเฉˆเจ‚ เจ‡เจธเจจเฉ‚เฉฐ เจกเจฐเจพเจซเจŸ เจตเจฟเฉฑเจš เจชเจพเจ‡เจ† เจนเฉˆ. เจฎเฉˆเจ‚ เจ‡เจธเจจเฉ‚เฉฐ เจฎเจฟเจŸเจพเจ‰เจฃ เจฌเจพเจฐเฉ‡ เจธเฉ‹เจšเจฟเจ†, เจชเจฐ เจธเจผเจพเจ‡เจฆ เจ‡เจน เจ•เจฟเจธเฉ‡ เจฒเจˆ เจฒเจพเจญเจฆเจพเจ‡เจ• เจนเฉ‹เจตเฉ‡เจ—เจพ.

LD_PRELOAD เจฆเฉ€ เจญเจพเจฒ เจ•เฉ€เจคเฉ€ เจœเจพ เจฐเจนเฉ€ เจนเฉˆ

เจ†เจฎ เจคเฉŒเจฐ 'เจคเฉ‡, "เจธเจผเจพเจฎเจฒ" เจฆเฉ€ เจ–เฉ‹เจœ เจ•เจฐเจจ เจฆเฉ‡ เจตเจฟเจธเจผเฉ‡ 'เจคเฉ‡ เจฅเฉ‹เฉœเจพ เจœเจฟเจนเจพ เจธเจผเฉเฉฑเจ•เจฐเจตเจพเจฐ เจเจกเจฎเจฟเจจ เจฐเฉ€เจกเจฟเฉฐเจ— 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, &regs);
                        // 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, &regs);
                    }
                }
                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

เจฌเจนเฉเจค เจธเจพเจฐเจพ เจงเฉฐเจจเจตเจพเจฆ

เจšเจพเจฐเจฒเจธ เจนเฉเจฌเฉ‡เจจ
เจšเฉ‹เจ•เจชเฉเจ†เจ‡เฉฐเจŸ
ValdikSS
เจซเจฟเจฒเจฟเจช เจŸเฉ‚เจตเฉ‡เจจ
derhass

, เจœเจฟเจจเฉเจนเจพเจ‚ เจฆเฉ‡ เจฒเฉ‡เจ–เจพเจ‚, เจธเจฐเฉ‹เจคเจพเจ‚ เจ…เจคเฉ‡ เจŸเจฟเฉฑเจชเจฃเฉ€เจ†เจ‚ เจจเฉ‡ เจ‡เจธ เจจเฉ‹เจŸ เจจเฉ‚เฉฐ เจ‡เฉฑเจฅเฉ‡ เจชเฉเจฐเจ—เจŸ เจ•เจฐเจจ เจฒเจˆ เจฎเฉ‡เจฐเฉ‡ เจจเจพเจฒเฉ‹เจ‚ เจ•เจฟเจคเฉ‡ เจตเฉฑเจง เจ•เฉ€เจคเจพ เจนเฉˆเฅค

เจธเจฐเฉ‹เจค: www.habr.com

DDoS เจธเฉเจฐเฉฑเจ–เจฟเจ†, VPS VDS เจธเจฐเจตเจฐเจพเจ‚ เจตเจพเจฒเฉ€เจ†เจ‚ เจธเจพเจˆเจŸเจพเจ‚ เจฒเจˆ เจญเจฐเฉ‹เจธเฉ‡เจฏเฉ‹เจ— เจนเฉ‹เจธเจŸเจฟเฉฐเจ— เจ–เจฐเฉ€เจฆเฉ‹ ๐Ÿ”ฅ DDoS เจธเฉเจฐเฉฑเจ–เจฟเจ†, VPS VDS เจธเจฐเจตเจฐเจพเจ‚ เจจเจพเจฒ เจญเจฐเฉ‹เจธเฉ‡เจฏเฉ‹เจ— เจตเฉˆเฉฑเจฌเจธเจพเจˆเจŸ เจนเฉ‹เจธเจŸเจฟเฉฐเจ— เจ–เจฐเฉ€เจฆเฉ‹ | ProHoster