워게임 챌린지를 실행하는 동안 권한 문제가 발생했습니다. 제공된 정보가 /proc/PID/status
프로세스에 부여되어야 하는 권한과 일치하지 않습니다.
저는 user1 사용자입니다. SETUID 프로그램을 사용해야 합니다:
-r-sr-x--- 1 user2 user1 6297 Jun 20 2013 program
따라서 user2의 유효 UID로 실행되어야 합니다.
프로그램이 종료되는 것을 방지하기 위해 프로그램을 시작한 후 일시적으로 중지합니다.
~/program "test" &
PID=$!
kill -SIGSTOP $PID
echo $PID
그런 다음 나는 cat /proc/$PID/status
다음을 보았습니다.
Uid: 1003 1003 1003 1003
Gid: 1003 1003 1003 1003
ID는 다음과 같습니다
$ id user1
uid=1003(user1) gid=1003(user1) groups=1003(user1)
$ id user2
uid=1035(user2) gid=1035(user2) groups=1035(user2),1003(user1)
매뉴얼( man 5 proc
)이 주어졌을 때, /proc/$PID/status
주어져야 함Uid, Gid: Real, effective, saved set, and filesystem UIDs (GIDs).
하지만 여기서 프로세스의 유효 ID는 user1이고,user2의 유효한 ID가 있어야 합니다..
프로그램을 너무 일찍 중단했기 때문일 수도 있다고 생각하여 실제로 함수 의 코드가 gdb
실행될 때까지 연결하고 계속 실행 해 보았지만 (제공된 소스) 유효한 UID는 여전히 user2가 아닌 user1이었습니다.main
program
/proc/$PID/status
내가 뭐 놓친 거 없니?
편집: 챌린지의 소스를 제거했습니다. 게시할 권한이 없는 것 같습니다.
답변1
너무 일찍 진행하기 때문에 UID가 변경될 때까지 기다리면 프로세스가 종료됩니다 user2
.
./program "test" &
PID=$!
sleep 0.0005
kill -SIGSTOP $PID
grep ^Uid /proc/$PID/status
또 다른 시도는 지연을 추가하고 usleep()
수면 중에 후자를 보내는 것입니다. SIGSTOP
그런 다음 프로그램은 user2
유효한 uid로 실행됩니다. gdb
또는 를 추가하지 않고도 확인할 수 있습니다 strace
. 프로세스가 UID를 변경하는 데 시간이 걸리는 Linux 커널 내부의 문제일 가능성이 높습니다.
execve()
맨페이지의 터미널에서 프로세스를 실행할 때 시스템 호출이 호출됩니다.
filename [...]이 가리키는 프로그램 파일에 set-user-ID 비트가 설정되어 있고 호출 프로세스가 추적되지 않으면 호출 프로세스의 유효 사용자 ID가 프로그램 소유자의 사용자 ID로 변경됩니다. 프로그램 파일.
프로세스에 연결하면 위 매뉴얼 페이지에 설명된 대로 프로세스를 수행하기 때문에 gdb
uid가 표시되지 않습니다 . 또는 프로세스에 연결하고 루트 권한을 얻을 수 있습니다.user2
ptrace
sudo
SIGSEGV
그러나 이 프로그램은 를 사용하지 않는 한 분할 오류( )를 발생시키지 않습니다 kill -SIGSEGV $PID
.만약에귀하의 프로그램에는 SIGSEGV
루틴 launch_debugger()
이라는 루틴이 있습니다. 이는 인수 없이 바이너리 gdb
만 인수로 호출하여 현재 실행 중인 프로세스를 대체합니다. program
따라서 디버거에는 권한이 있으므로 user2
거기에서 원하는 작업을 수행하고 user2
권한을 가질 수 있습니다.
예를 들어 내부적으로 다음을 수행할 수 있습니다 gdb
.
(gdb) file bash
Reading symbols from /bin/bash...(no debugging symbols found)...done.
(gdb) run
Starting program: /bin/bash
user2@host:~$ id
uid=1035(user2) gid=1003(user1) groups=1035(user2),1003(user1)
이제 setuid 비트가 있고 소유자가 루트인 동일한 바이너리를 고려하십시오.
답변2
setuid
파일 비트( )를 지원하는 파일 시스템에서 프로그램이 실행되고 있습니까 mount -o nosuid
?
getuid()
이것을 디버깅하는 경우 프로그램이 비트가 적용되는지 geteuid()
확인하기 시작할 때의 출력을 인쇄합니다 .setuid