DDexec / EverythingExec

Tip

AWS Hacking을 배우고 연습하세요:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking을 배우고 연습하세요: HackTricks Training GCP Red Team Expert (GRTE)
Az Hacking을 배우고 연습하세요: HackTricks Training Azure Red Team Expert (AzRTE) 평가 트랙 (ARTA/GRTA/AzRTA)과 Linux Hacking Expert (LHE)를 보려면 전체 HackTricks Training 카탈로그를 둘러보세요.

HackTricks 지원하기

Context

리눅스에서 프로그램을 실행하려면 파일로 존재해야 하며, 파일 시스템 계층을 통해 어떤 방식으로든 접근 가능해야 합니다(이는 execve()가 작동하는 방식입니다). 이 파일은 디스크에 있거나 램(tmpfs, memfd)에 있을 수 있지만, 파일 경로가 필요합니다. 이로 인해 리눅스 시스템에서 실행되는 것을 쉽게 제어할 수 있으며, 위협 및 공격자의 도구를 감지하거나 그들이 아무것도 실행하지 못하도록 방지하는 것이 용이합니다(_예: 비특권 사용자가 실행 파일을 아무 곳에나 배치하는 것을 허용하지 않음).

하지만 이 기술은 모든 것을 바꾸기 위해 존재합니다. 원하는 프로세스를 시작할 수 없다면… 이미 존재하는 프로세스를 탈취합니다.

이 기술은 읽기 전용, noexec, 파일 이름 화이트리스트, 해시 화이트리스트와 같은 일반적인 보호 기술을 우회할 수 있게 해줍니다.

Dependencies

최종 스크립트는 작동하기 위해 다음 도구에 의존하며, 공격하는 시스템에서 접근 가능해야 합니다(기본적으로 모든 곳에서 이들을 찾을 수 있습니다):

dd
bash | zsh | ash (busybox)
head
tail
cut
grep
od
readlink
wc
tr
base64

기술

프로세스의 메모리를 임의로 수정할 수 있다면, 해당 프로세스를 장악할 수 있습니다. 이는 이미 존재하는 프로세스를 가로채고 다른 프로그램으로 교체하는 데 사용될 수 있습니다. 우리는 ptrace() 시스템 호출을 사용하거나 (이는 시스템에서 시스템 호출을 실행할 수 있는 능력이나 gdb가 필요합니다) 더 흥미롭게도 /proc/$pid/mem에 쓰는 방법으로 이를 달성할 수 있습니다.

파일 /proc/$pid/mem은 프로세스의 전체 주소 공간의 1:1 매핑입니다 (_예: x86-64에서 0x0000000000000000에서 0x7ffffffffffff000까지). 이는 오프셋 x에서 이 파일을 읽거나 쓰는 것이 가상 주소 x에서 내용을 읽거나 수정하는 것과 동일하다는 것을 의미합니다.

이제 우리는 네 가지 기본 문제에 직면하게 됩니다:

  • 일반적으로 루트와 파일의 프로그램 소유자만 수정할 수 있습니다.
  • ASLR.
  • 프로그램의 주소 공간에 매핑되지 않은 주소를 읽거나 쓰려고 하면 I/O 오류가 발생합니다.

이 문제들은 완벽하지는 않지만 좋은 해결책이 있습니다:

  • 대부분의 셸 인터프리터는 자식 프로세스가 상속받을 파일 설명자를 생성할 수 있도록 허용합니다. 우리는 쓰기 권한이 있는 셸의 mem 파일을 가리키는 fd를 생성할 수 있습니다… 따라서 해당 fd를 사용하는 자식 프로세스는 셸의 메모리를 수정할 수 있습니다.
  • ASLR은 문제도 아닙니다. 우리는 셸의 maps 파일이나 procfs의 다른 파일을 확인하여 프로세스의 주소 공간에 대한 정보를 얻을 수 있습니다.
  • 따라서 우리는 파일에서 lseek()를 수행해야 합니다. 셸에서는 악명 높은 dd를 사용하지 않고는 이를 수행할 수 없습니다.

더 자세히

단계는 상대적으로 쉽고 이해하는 데 어떤 전문 지식도 필요하지 않습니다:

  • 실행할 바이너리와 로더를 파싱하여 필요한 매핑을 찾습니다. 그런 다음, 대략적으로 커널이 execve()를 호출할 때 수행하는 것과 동일한 단계를 수행하는 “셸” 코드를 작성합니다:
  • 해당 매핑을 생성합니다.
  • 바이너리를 그 안으로 읽어들입니다.
  • 권한을 설정합니다.
  • 마지막으로 프로그램의 인수로 스택을 초기화하고 로더에 필요한 보조 벡터를 배치합니다.
  • 로더로 점프하여 나머지를 수행하게 합니다 (프로그램에 필요한 라이브러리를 로드합니다).
  • 실행 중인 시스템 호출 후 프로세스가 반환할 주소를 syscall 파일에서 가져옵니다.
  • 해당 위치를 덮어씌우고, 이는 실행 가능하며, 우리의 셸코드로 대체합니다 (우리는 mem을 통해 쓰기 불가능한 페이지를 수정할 수 있습니다).
  • 실행할 프로그램을 프로세스의 stdin으로 전달합니다 (해당 “셸” 코드에 의해 read()됩니다).
  • 이 시점에서 로더는 프로그램에 필요한 라이브러리를 로드하고 그 안으로 점프하는 역할을 합니다.

도구를 확인하세요 https://github.com/arget13/DDexec

EverythingExec

dd에 대한 여러 대안이 있으며, 그 중 하나인 tail은 현재 mem 파일을 통해 lseek()하는 데 사용되는 기본 프로그램입니다 (이는 dd를 사용하는 유일한 목적이었습니다). 이러한 대안은:

tail
hexdump
cmp
xxd

변수 SEEKER를 설정하면 사용되는 seeker를 변경할 수 있습니다, 예::

SEEKER=cmp bash ddexec.sh ls -l <<< $(base64 -w0 /bin/ls)

스크립트에 구현되지 않은 다른 유효한 seeker를 찾으면 SEEKER_ARGS 변수를 설정하여 여전히 사용할 수 있습니다:

SEEKER=xxd SEEKER_ARGS='-s $offset' zsh ddexec.sh ls -l <<< $(base64 -w0 /bin/ls)

이것을 차단하세요, EDRs.

참고문헌

Tip

AWS Hacking을 배우고 연습하세요:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking을 배우고 연습하세요: HackTricks Training GCP Red Team Expert (GRTE)
Az Hacking을 배우고 연습하세요: HackTricks Training Azure Red Team Expert (AzRTE) 평가 트랙 (ARTA/GRTA/AzRTA)과 Linux Hacking Expert (LHE)를 보려면 전체 HackTricks Training 카탈로그를 둘러보세요.

HackTricks 지원하기