일부 파일 설명자가 있는 경우 "chroot(2)" 이후 이전 루트를 복원하는 방법은 무엇입니까?

일부 파일 설명자가 있는 경우 "chroot(2)" 이후 이전 루트를 복원하는 방법은 무엇입니까?

chroot(2)열린 파일 설명자를 제공한 후 이전 루트를 어떻게 다시 가져오나요?

아래 프로그램에서는 먼저 에 대한 파일 설명자를 연 /다음 chroot(2).chdir(2)에 엽니다 /.

chdir(2)그러나 이전 루트 디렉토리로 이동 하면 fdPython은 현재 작업 디렉토리가 getcwd()존재하지 않기 때문에 인쇄할 수 없다고 불평합니다.

현재 작업 디렉터리를 이전 루트 디렉터리로 변경하고 인쇄할 수 없는 이유는 무엇입니까?

이것이 바로 "pivot_root()"와 "chroot()"가 있는 이유이며, 둘 다 원하는 작업을 수행하는 데 사용할 수 있습니다. 새 루트를 다른 곳에 마운트한 다음 chroot(또는 피벗 루트)합니다. 그런 다음 'chdir("/")'을 수행하여 cwd를 새 루트로 이동합니다. (그런 다음에만 이전 루트를 "잃습니다". 파일 설명자가 열려 있으면 실제로 다시 가져와서 찾을 수 있습니다. ).

https://yarchive.net/comp/linux/pivot_root.html

프로그램:

import os

print(f'cwd: {os.getcwd()}')

fd = os.open('/', os.R_OK, os.X_OK)

os.chroot('.')
os.chdir('/')

print(f'cwd: {os.getcwd()}')

os.chdir(fd)

print(f'cwd: {os.getcwd()}')

산출:

$ sudo python3 chdir_fd.py
cwd: /home/admin/projects/linux-pwn
cwd: /
Traceback (most recent call last):
  File "chdir_fd.py", line 14, in <module>
FileNotFoundError: [Errno 2] No such file or directory

답변1

세 가지 문제가 있습니다.

  • chdir(2)파일 설명자를 사용하고 있습니다 . 올바른 시스템 호출은 다음과 같아야 합니다.fchdir(2).

    Python은 아마도 그것을 대신 사용할 만큼 똑똑할 것입니다 fchdir().

  • 그것을 사용한 후에 는 다시 fchdir(2)수행 chroot(2)해야 현재 디렉토리가 다시 나타납니다.~에현재 "알려진 공간"뿌리나무.

  • 결과를 구별할 수 없습니다 getcwd(). 두 경우 모두 /동일하지 않더라도 결과를 얻을 수 있습니다 /. 예를 들어, inode 번호(동일한 파일 시스템이라고 가정하여 비교 결과가 유지됨) 또는 다를 수 있는 다른 항목을 표시할 수 있습니다.

여기에서는 위의 변경 사항을 기반으로 debian Bullseye/sid에서 LXC Buster 컨테이너의 루트 디렉터리로 루트를 변경했습니다. 내가 두 번 보여주는 것 /etc/debian_version:

import os

print(f'cwd: {os.getcwd()}')

fd = os.open('/', os.R_OK, os.X_OK)

os.chroot('.')
os.chdir('/')

print(f'cwd: {os.getcwd()}')

debfd=open("/etc/debian_version","r")
print(debfd.read())
debfd.close()

os.fchdir(fd)
os.chroot('.')

print(f'cwd: {os.getcwd()}')

debfd=open("/etc/debian_version","r")
print(debfd.read())
debfd.close()

결과:

root@glasswalker:/var/lib/lxc/buster-amd64/rootfs# /tmp/chrootback.py 
cwd: /var/lib/lxc/buster-amd64/rootfs
cwd: /
10.8

cwd: /
bullseye/sid

하찮은 일

"알 수 없는 공간"을 악용하여 탈출할 수 있음chroot() 아니요파일 설명자는 예약되어 있습니다. 2005년 이 페이지에서는 다음과 같이 설명합니다.

chroot() 감옥에서 나가는 방법

#include <stdlib.h>주어진 코드의 두 가지 문제(그 중 하나는 62행의 큰따옴표 철자 오류에 대해 추가하고 수정해야 함) 외에도 fprintf()오늘날의 데비안(물론 일부 *nix)에서는 여전히 잘 작동합니다.

제가 이해한 바에 따르면 "알 수 없는 공간"에 있을 때(예:서부 독일현재의 외부뿌리) 그러면 우리는 맹목적으로 실제 상황으로 돌아갈 수 있습니다.뿌리.

관련 정보