답변:
디렉토리를 작성하는 사용자에게 상위 디렉토리에 쓸 수있는 충분한 권한이 있으면 부여 할 수 없습니다.
대신 inotify
Linux 커널이 제공하는 시스템 호출 제품군을 활용하여 디렉토리가 작성되거나 선택적으로 -ed 인 경우 지정된 디렉토리에서 mv
디렉토리 의 작성 (및 선택적으로 -ing) 을 감시 할 수 있습니다.shop
mv
rm
이 경우 필요한 사용자 공간 프로그램은 inotifywait
(와 함께 제공되며 inotify-tools
필요한 경우 먼저 설치하십시오).
디렉토리 shop
가 디렉토리에 있다고 가정하면 작성 /foo/bar
모니터링을 /foo/bar/shop
작성하고 작성 하는 rm
경우 즉시 모니터링을 설정하십시오 .
inotifywait -qme create /foo/bar | \
awk '/,ISDIR shop$/ { system("rm -r -- /foo/bar/shop") }'
inotifywait -qme create /foo/bar
시계 /foo/bar
어떤을 위해, 즉 시계를 생성 할 수있는 파일 / 디렉토리에 대한 디렉토리를 create
이벤트
만든 경우, awk '/,ISDIR shop$/ { system("rm -r -- /foo/bar/shop") }'
검사 파일이 디렉토리를 될 일 경우 이름입니다 shop
( /,ISDIR shop$/
,) 만약 그렇다면 rm
(디렉토리 system("rm -r -- /foo/bar/shop")
)
디렉토리 /foo/bar
에서 제거 shop
하려면 디렉토리에 대한 쓰기 권한이있는 사용자로 명령을 실행해야합니다 .
mv
-ing 조작도 모니터하려면 moved_to
이벤트 감시도 추가하십시오 .
inotifywait -qme create,moved_to /foo/bar | \
awk '/,ISDIR shop$/ { system("rm -r -- /foo/bar/shop") }'
디렉토리가 아닌 파일을 찾고 있다면 shop
:
inotifywait -qme create /foo/bar | \
awk '$NF == "shop" { system("rm -- /foo/bar/shop") }'
inotifywait -qme create,moved_to /foo/bar | \
awk '$NF == "shop" { system("rm -- /foo/bar/shop") }'
inotifywait
이 작업을 수행 하는 데 사용 하는 경우 트리거가 프로세스를 잡을 수도 있습니다.ps -ef
특정 이름 의 폴더 를 만들 수 없다는 문제에 따라 문자 그대로 대답 합니다 .
touch shop
동일한 이름의 파일이 존재하면 디렉토리를 만들 수 없습니다
mkdir: cannot create directory ‘shop’: File exists
chattr +i shop
불변으로 사용하십시오. 불변의 플래그가 제거 될 때까지는 이름을 바꾸거나 삭제할 수 없습니다.
rename(2)
name은 inode의 일부가 아니기 때문에 여전히 작동 할 것으로 예상 했지만 그렇지 않습니다. 빠른 인터넷 검색은 이유를 밝히지 않습니다. 힌트가 있습니까?
rename
.
mkdir
syscall을 하이재킹하는 것은 LD_PRELOAD
어떻습니까?
$ ls
test.c
$ cat test.c
#define _GNU_SOURCE
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dlfcn.h>
typedef int (*orig_mkdir_func_type)(const char *path, mode_t mode);
int mkdir(const char *path, mode_t mode) {
if(!strcmp(path, "shop")) return 1;
orig_mkdir_func_type orig_func;
orig_func = (orig_mkdir_func_type)dlsym(RTLD_NEXT, "mkdir");
return orig_func(path, mode);
}
$ gcc -shared -fPIC test.c -o test.so
$ LD_PRELOAD='./test.so' mkdir test
$ LD_PRELOAD='./test.so' mkdir shop
mkdir: cannot create directory ‘shop’: No such file or directory
$ ls
test test.c test.so
이 핸들러 내에서 대신이 디렉토리를 작성하려는 프로세스의 PID를 로그 할 수 있습니다.
$ cat test.c
#define _GNU_SOURCE
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dlfcn.h>
typedef int (*orig_mkdir_func_type)(const char *path, mode_t mode);
int mkdir(const char *path, mode_t mode) {
if(!strcmp(path, "shop")) {
FILE* fp = fopen("/tmp/log.txt", "w");
fprintf(fp, "PID of evil script: %d\n", (int)getpid());
fclose(fp);
}
orig_mkdir_func_type orig_func;
orig_func = (orig_mkdir_func_type)dlsym(RTLD_NEXT, "mkdir");
return orig_func(path, mode);
}
$ gcc -shared -fPIC test.c -o test.so
$ LD_PRELOAD='./test.so' mkdir shop
$ cat /tmp/log.txt
PID of evil script: 8706
이것을 사용하려면 ~/.bashrc
루트 (또는 앱을 실행하는 사람)에게 이것을 배치해야합니다.
export LD_PRELOAD=/path/to/test.so
LD_PRELOAD
이와 같은 해킹은 기본적으로 항상 잘못이며, 수행중인 작업을 알지 못하면 대체하는 함수의 비동기 신호 안전과 같은 속성을 차단하여로드하는 프로그램을 심하게 손상 시킬 수 있습니다 .
fopen
해야한다 "a"
대신 "w"
이 이전 로그를 보존 할 수 있도록,
(Miati의 답변에 대해 언급했지만 내 오래된 계정을 기억할 수 없으며이 새로운 계정에 대한 명성이 충분하지 않습니다 ...)
파일을 작성한 다음 파일 속성을 변경하여 작성을 차단할 수 있습니다.
$ sudo touch shop
$ sudo chattr +i shop
그런 다음 사용자가 루트가 되더라도 해당 파일로 작업을 시도하면 차단됩니다.
$ rm shop
rm: remove write-protected regular empty file ‘shop’? y
rm: cannot remove ‘shop’: Operation not permitted
$ sudo rm shop
rm: cannot remove ‘shop’: Operation not permitted
존재하지 않는 디렉토리 내부에 존재하지 않는 위치를 가리키는 심볼릭 링크를 만듭니다. 여기에는 몇 가지 재미있는 의미가 있습니다.
$ ln -s non-existent/foobar foo
$ ls -ln
total 0
lrwxrwxrwx 1 1000 1000 19 Okt 4 17:17 foo -> non-existent/foobar
$ mkdir foo
mkdir: cannot create directory ‘foo’: File exists
$ cat foo
cat: foo: No such file or directory
$ echo foo > foo
zsh: no such file or directory: foo
EEXIST
(파일이 존재 함).ENOENT
(파일 또는 디렉토리가 없음).ENOENT
. lstat는 물론 심볼릭 링크에 대한 정보를 반환합니다.여기에 제안 된 다른 솔루션 중 일부에 비해 두 가지 장점이 있습니다. (a) 디렉토리 생성을 추적하는 서비스가 필요하지 않으며 (b) 이름이 대부분의 명령에 존재하지 않는 것 같습니다.
당신은 그것을 쏴야 할 것이지만, 나는 당신이 가진 다시 쓰기 규칙이 lstat 나 다른 비 참조 명령을 사용하지 않아서 실패한다고 생각합니다.