파일접근에대한 시스템 콜을 후킹하려합니다.

yshkorea의 이미지

파일접근에 대한 시스템 콜을 후킹하려하는데요..

리눅스에서 후킹이 가능한가요?

단. 애플리케이션 영역에서만 해야합니다.

커널 수정 이런건 절대 안되고요..

가능할까요? 가능하다면 어떻게 해야하죠?

익명 사용자의 이미지

LD_PRELOAD 로 시작해보시지요.
메카니즘으로 보면 윈도우랑 비슷하니..
몇몇 한계가 있지만, 시작으로 좋아 보입니다.

그외 gdb등 디버거 프로그램을 보면 이런 유형에 도움이 많이 됩니다.
파일시스템 모니터링에는 tripwire , aide등 hids(호스트 기반 ids)류들도 보탬이 될 수 있을것입니다.

익명 사용자의 이미지

부록을 만들어 봤습니다.
잠시 기억을 더듬고 옛글도 보고해서리 ㅎㅎ

부록....
Makefile은 아래와 같습니다.

CC = gcc
CFLAGS = -O -Wall -g
 
OBJS = test.o myopen.o
 
SRCS =  test.c
 
LIBHOOK = ./libmy.so.1
HEADERS =
 
test:   $(OBJS) $(LIBHOOK)
            $(CC)   $(CFLAGS) -o test   $(OBJS) -L. $(LIBHOOK)
 
$(OBJS):    $(HERADERS) Makefile
 
all:    test
 
$(LIBHOOK): myopen.c
    $(CC) -fPIC -rdynamic -g -c -Wall myopen.c
    $(CC) -shared -Wl,-soname,libmy.so.1 -o $(LIBHOOK) myopen.o -lc -ldl
    export LD_PRELOAD=$(LIBHOOK)
 
 
clean:
    rm -f $(OBJS) test $(LIBHOOK)

다음은 open() 함수만을 후킹한 경우입니다. myopen.c로 저장하세요
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <dlfcn.h>
#include <unistd.h>
 
#include <stdarg.h>
#include <time.h>
 
 char timeBuf[1024]; // TODO: Global~~~ --;
 
char *timeStr()
{
    time_t now;
    char *fmt =  "%Y-%m-%d %H:%M:%S";
    int len;
 
 
    time(&now);
 
    len = strftime(timeBuf,sizeof timeBuf, fmt, localtime(&now));
 
    return timeBuf;
}
 
int open(const char *path, int oflag, ...  )
{
    va_list argptr;
    static int (*orig_open)(const char *path, int oflag, ...) = NULL;
    char *error;
    int result;
 
    if(!orig_open){
        orig_open = dlsym(RTLD_NEXT, "open");
        if((error=dlerror()) != NULL){
            //fputs("error",stderr);
            write(2, "error \n", 7);
            exit(EXIT_FAILURE);
        }
    }
    fprintf(stderr, ">>%s   uid = %d getcwd= %s open '%s' file\n", timeStr(), getuid(), get_current_dir_name(), path);
 
    va_start(argptr, oflag);
    result = (*orig_open)(path, oflag, argptr);
    va_end(argptr);
 
    return result;
}

다음은 테스트 파일입니다. test.c로 저장
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
 
int main()
{
    int fd;
    char buf[1024];
    int ret;
 
   fd = open("test.c", O_RDONLY, 0666);
   if ( fd < 0 ) {
        perror("open");
        exit(0);
    }
    while(1) {
        ret = read(fd, buf, 1024);
        if ( ret < 0 ) {
            perror("read");
            break;
        }
        else if (ret == 0 ) {
            //perror("EOF !");
            break;
        }
        else {
        //  write(1, buf, ret); // TODO : return value. check.
        }
 
    }
 
   close(fd);
    return 0;
}

프로그램이 하는일
일단, 위 프로그램은 현재 디렉터리에서 test.c 파일을 open()해서, open() 성공시에는 열심히, 읽어서 읽은 내용을 화면에 출력하지 않는다(주석처리했음). 라는 로직을 가지는 프로그램입니다.

테스트
1) LD_PRELOAD만 테스트

[몰라@거기 openHook]$ ls
Makefile libmy.so.1 myopen.c myopen.o test test.c test.o
[몰라@거기 openHook]$ export LD_PRELOAD=./libmy.so.1
[몰라@거기 openHook]$ ls
>>2007-11-02 18:09:06 uid = 511 getcwd= /home/사용자명/Test/dlopen/openHook open '/proc/filesystems' file
>>2007-11-02 18:09:06 uid = 511 getcwd= /home/사용자명/Test/dlopen/openHook open '/proc/self/attr/current' file

Makefile libmy.so.1 myopen.c myopen.o open.o test test.c test.o
[몰라@거기 openHook]$

2) 예제도 테스트
[몰라@거기 openHook]$ ./test
>>2007-11-02 18:12:30 uid = 511 getcwd= /home/사용자명/Test/dlopen/openHook open 'test.c' file
>>2007-11-02 18:12:30 uid = 511 getcwd= /home/사용자명/Test/dlopen/openHook open 'test.c' file
[몰라@거기 openHook]$ ls
Makefile libmy.so.1 myopen.c myopen.o test test.c test.o

첫번째 테스트에서 ls가 open한 정보를 보여줍니다.

[몰라@거기 openHook]$ ls
>>2007-11-02 18:09:06 uid = 511 getcwd= /home/사용자명/Test/dlopen/openHook open '/proc/filesystems' file
>>2007-11-02 18:09:06 uid = 511 getcwd= /home/사용자명/Test/dlopen/openHook open '/proc/self/attr/current' file
특이할 만한것은 ls 라는 프로그램은 '/proc/filesystems''/proc/self/attr/current'을 열고 있군요.
(저도 처음알았습니다.)

오픈한 시간은 위에 출력되고 있고, uid도 역시,...
myopen.c 의
fprintf(stderr, ">>%s uid = %d getcwd= %s open '%s' file\n", timeStr(), getuid(), get_current_dir_name(), path);
를 출력하는 부분을 판단로직 부분을 다른조건으로 이를 테면 uid가 0이면 열지말고 리턴한다던지... 하면 재미있는 상황이 벌어지겠지요.

끝으로,
$ export LD_PRELOAD=
하여 LD_PRELOAD 환경변수를 클리어 해야 할 경우를 만나게 될 수 있다는 조언입니다.

작은 보탬이 되기를 기대합니다.

참... OpenHook은 그냥 제가 만든 디렉터리일뿐 이런 오픈소스는 아마도 없을것으로 보입니다.

ymir의 이미지

직접 구현하시려나 보네요... 건투를... ;;

혹시나 해서 자료를 좀 찾아 보니.. inotify 란게 있었군요...
2.6.13 kernel 부터 포함된 것 같은데.. 참고해 보세요...

http://en.wikipedia.org/wiki/Inotify

http://linux.die.net/man/7/inotify

http://www-128.ibm.com/developerworks/linux/library/l-inotify.html

http://pyinotify.sourceforge.net/

되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』

되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』

mach의 이미지

anonymous

------------------ P.S. --------------
지식은 오픈해서 검증받아야 산지식이된다고 동네 아저씨가 그러더라.

sangwoo의 이미지

----
Let's shut up and code.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.