PHP Tricks
Last updated
Last updated
AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE) GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE)
웹 앱, 네트워크 및 클라우드에 대한 해커의 관점을 얻으세요.
실제 비즈니스에 영향을 미치는 치명적이고 악용 가능한 취약점을 찾아보고 보고하세요. 20개 이상의 맞춤형 도구를 사용하여 공격 표면을 매핑하고, 권한 상승을 허용하는 보안 문제를 찾아내며, 자동화된 익스플로잇을 사용하여 필수 증거를 수집하여 귀하의 노력을 설득력 있는 보고서로 전환하세요.
이것은 phpMyAdmin 쿠키에도 유효합니다.
쿠키:
위치:
PHP에서 ==
를 사용하면 예상치 못한 경우에 비교가 예상대로 작동하지 않습니다. 이는 "=="가 동일한 타입으로 변환된 값만 비교하기 때문이며, 비교되는 데이터의 타입이 동일한지 비교하고 싶다면 ===
를 사용해야 합니다.
PHP 비교 표: https://www.php.net/manual/en/types.comparisons.php
"string" == 0 -> True
숫자로 시작하지 않는 문자열은 숫자와 같습니다.
"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
"X" == 0 --> True
문자열의 어떤 문자도 int 0과 같습니다.
자세한 정보는 https://medium.com/swlh/php-type-juggling-vulnerabilities-3e28c4ed5c09에서 확인할 수 있습니다.
타입 조작은 기본적으로 in_array()
함수에도 영향을 미칩니다 (엄격한 비교를 하려면 세 번째 인수를 true로 설정해야 합니다):
이 함수가 모든 인증 확인(비밀번호 확인과 같은)에 사용되면, 사용자가 비교의 한 쪽을 제어할 경우, 비밀번호의 값으로 문자열 대신 빈 배열을 보낼 수 있습니다 (https://example.com/login.php/?username=admin&password[]=
) 그리고 이 확인을 우회할 수 있습니다:
strcasecmp()
와 동일한 오류가 발생합니다.
===
가 사용되고 있더라도 비교가 취약하게 만드는 오류가 있을 수 있습니다. 예를 들어, 비교가 비교하기 전에 데이터를 다른 타입의 객체로 변환하고 있는 경우:
**preg_match()
**는 사용자 입력을 검증하는 데 사용될 수 있습니다(사용자 입력에 블랙리스트의 단어/정규 표현식이 존재하는지 확인하고, 존재하지 않으면 코드는 계속 실행될 수 있습니다).
그러나 정규 표현식의 시작을 구분할 때 preg_match()
는 사용자 입력의 첫 번째 줄만 확인합니다. 따라서 어떤 방법으로든 여러 줄로 입력을 전송할 수 있다면 이 검사를 우회할 수 있습니다. 예:
이 검사를 우회하려면 새 줄이 URL 인코딩된 값(%0A
)을 전송하거나, JSON 데이터를 보낼 수 있다면 여러 줄로 전송하세요:
여기에서 예제를 찾으세요: https://ramadistra.dev/fbctf-2019-rceservice
(이 우회는 PHP 5.2.5에서 시도된 것으로 보이며, PHP 7.3.15에서는 작동하지 않았습니다)
preg_match()
에 유효한 매우 큰 입력을 보낼 수 있다면, 처리할 수 없게 되어 검사를 우회할 수 있습니다. 예를 들어, JSON을 블랙리스트에 올리고 있다면 다음과 같이 보낼 수 있습니다:
From: https://medium.com/bugbountywriteup/solving-each-and-every-fb-ctf-challenge-part-1-4bce03e2ecb0
Trick from: https://simones-organization-4.gitbook.io/hackbook-of-a-hacker/ctf-writeups/intigriti-challenges/1223 and https://mizu.re/post/pong
간단히 말해, 문제는 PHP의 preg_*
함수가 PCRE 라이브러리를 기반으로 하기 때문에 발생합니다. PCRE에서는 특정 정규 표현식이 많은 재귀 호출을 사용하여 일치되며, 이는 많은 스택 공간을 사용합니다. 허용되는 재귀 호출의 수에 제한을 설정할 수 있지만, PHP에서는 이 제한이 기본적으로 100.000으로 설정되어 있어 스택에 맞지 않습니다.
이 Stackoverflow 스레드도 이 문제에 대해 더 깊이 논의된 게시물에 링크되어 있었습니다. 우리의 작업은 이제 명확해졌습니다:
정규 표현식이 100_000회 이상의 재귀를 수행하게 만드는 입력을 보내어 SIGSEGV를 유발하고, preg_match()
함수가 false
를 반환하게 하여 애플리케이션이 우리의 입력이 악의적이지 않다고 생각하게 만든 후, 페이로드의 끝에 {system(<verybadcommand>)}
와 같은 놀라움을 던져 SSTI --> RCE --> flag :).
정규 표현식 용어로, 우리는 실제로 100k "재귀"를 수행하는 것이 아니라 "백트래킹 단계"를 세고 있으며, PHP 문서에 따르면 pcre.backtrack_limit
변수의 기본값은 1_000_000 (1M)입니다.
이를 달성하기 위해 'X'*500_001
은 100만 개의 백트래킹 단계를 생성합니다 (500k 전방 및 500k 후방):
PHP가 다른 페이지로 리디렉션하고 있지만 Location
헤더가 설정된 후에 die
또는 exit
함수가 호출되지 않으면, PHP는 계속 실행되어 데이터를 본문에 추가합니다:
확인:
File Inclusion/Path traversalregister_globals: PHP < 4.1.1.1 또는 잘못 구성된 경우, register_globals가 활성화될 수 있습니다(또는 그 동작이 모방되고 있을 수 있습니다). 이는 $_GET와 같은 전역 변수에 값이 있는 경우, 예를 들어 $_GET["param"]="1234", $param을 통해 접근할 수 있음을 의미합니다. 따라서 HTTP 매개변수를 전송하여 코드 내에서 사용되는 변수를 덮어쓸 수 있습니다.
같은 도메인의 PHPSESSION 쿠키는 같은 위치에 저장됩니다. 따라서 도메인 내에서 다른 경로에서 다른 쿠키가 사용되는 경우, 한 경로가 다른 경로 쿠키의 값을 설정하여 쿠키에 접근하게 만들 수 있습니다. 이렇게 하면 두 경로가 같은 이름의 변수를 접근할 경우, path1의 그 변수의 값이 path2에 적용되도록 만들 수 있습니다. 그러면 path2는 path1의 변수를 유효한 것으로 간주합니다(쿠키에 path2에 해당하는 이름을 부여하여).
사용자의 사용자 이름이 있는 경우, 주소 **/~<USERNAME>**를 확인하여 php 디렉토리가 활성화되어 있는지 확인합니다.
이 함수들은 일반적으로 PHP에서 비밀번호로부터 해시를 생성하고 해시와 비교하여 비밀번호가 올바른지 확인하는 데 사용됩니다.
지원되는 알고리즘은: PASSWORD_DEFAULT
및 PASSWORD_BCRYPT
(시작은 $2y$
). PASSWORD_DEFAULT는 자주 PASSWORD_BCRYPT와 동일합니다. 현재 PASSWORD_BCRYPT는 입력의 크기 제한이 72바이트입니다. 따라서 이 알고리즘으로 72바이트보다 큰 것을 해시하려고 하면 처음 72B만 사용됩니다:
이 트위터 스레드에서 1000개 이상의 GET 파라미터, 1000개 이상의 POST 파라미터 또는 20개의 파일을 전송하면 PHP가 응답에서 헤더를 설정하지 않는 것을 볼 수 있습니다.
예를 들어 CSP 헤더가 설정된 코드에서 우회를 허용합니다:
PHP 페이지가 오류를 출력하고 사용자가 제공한 일부 입력을 다시 에코하는 경우, 사용자는 PHP 서버가 헤더를 응답에 추가하려고 할 때 오류를 발생시키도록 충분히 긴 콘텐츠를 출력하게 할 수 있습니다. 다음 시나리오에서 공격자는 서버가 큰 오류를 발생시키도록 했으며, 화면에서 볼 수 있듯이 PHP가 헤더 정보를 수정하려고 할 때, 수정할 수 없었습니다 (예를 들어 CSP 헤더가 사용자에게 전송되지 않았습니다):
페이지를 확인하세요:
PHP SSRFsystem("ls"); `ls`; shell_exec("ls");
코드를 실행하려면 "replace" 인수에 최소한 하나의 일치 항목이 필요합니다. 이 preg_replace 옵션은 PHP 5.5.0부터 사용 중단되었습니다.
이 php 내의 함수는 문자열로 작성된 코드를 실행하여 true 또는 false를 반환할 수 있게 해줍니다 (그리고 이에 따라 실행을 변경할 수 있습니다). 일반적으로 사용자 변수는 문자열의 중간에 삽입됩니다. 예를 들어:
assert("strpos($_GET['page']),'..') === false")
--> 이 경우 RCE를 얻기 위해 다음과 같이 할 수 있습니다:
당신은 코드 구문을 깨고, 페이로드를 추가한 다음 다시 수정해야 합니다. "**and" 또는 "%26%26" 또는 "|"**와 같은 논리 연산을 사용할 수 있습니다. "or", "||"는 작동하지 않으니 주의하세요. 첫 번째 조건이 참이면 우리의 페이로드가 실행되지 않기 때문입니다. 같은 이유로 ";"도 작동하지 않습니다. 우리의 페이로드가 실행되지 않기 때문입니다.
다른 옵션은 문자열에 명령 실행을 추가하는 것입니다: '.highlight_file('.passwd').'
다른 옵션 (내부 코드를 가지고 있다면)은 실행을 변경하기 위해 일부 변수를 수정하는 것입니다: $file = "hola"
이 함수는 특정 함수를 사용하여 항목 배열을 정렬하는 데 사용됩니다. 이 함수를 악용하려면:
You can also use // to comment the rest of the code.
To discover the number of parenthesis that you need to close:
?order=id;}//
: we get an error message (Parse error: syntax error, unexpected ';'
). We are probably missing one or more brackets.
?order=id);}//
: we get a warning. That seems about right.
?order=id));}//
: we get an error message (Parse error: syntax error, unexpected ')' i
). We probably have too many closing brackets.
If you can upload a .htaccess, then you can configure several things and even execute code (configuring that files with extension .htaccess can be executed).
Different .htaccess shells can be found here
If you find a vulnerability that allows you to modify env variables in PHP (and another one to upload files, although with more research maybe this can be bypassed), you could abuse this behaviour to get RCE.
LD_PRELOAD
: 이 환경 변수는 다른 바이너리를 실행할 때 임의의 라이브러리를 로드할 수 있게 해줍니다 (이 경우에는 작동하지 않을 수 있습니다).
PHPRC
: PHP에 구성 파일의 위치를 지시합니다. 일반적으로 php.ini
라고 불립니다. 자신의 구성 파일을 업로드할 수 있다면, PHPRC
를 사용하여 PHP가 이를 가리키도록 하십시오. 두 번째 업로드된 파일을 지정하는 auto_prepend_file
항목을 추가하십시오. 이 두 번째 파일은 일반 PHP 코드를 포함하며, 이는 다른 코드가 실행되기 전에 PHP 런타임에 의해 실행됩니다.
우리의 쉘코드를 포함하는 PHP 파일을 업로드합니다.
1단계에서 업로드한 파일을 실행하도록 PHP 전처리기에 지시하는 auto_prepend_file
지시어를 포함하는 두 번째 파일을 업로드합니다.
2단계에서 업로드한 파일로 PHPRC
변수를 설정합니다.
이 체인을 실행하는 방법에 대한 더 많은 정보는 원본 보고서에서 확인하십시오.
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 코드로 파일을 전처리합니다:
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=="'
기술 이 보고서에서.
웹 서버는 HTTP 요청을 구문 분석하고 이를 PHP 스크립트에 전달하여 http://host/cgi.php?foo=bar
와 같은 요청을 실행합니다. 이는 php.exe cgi.php foo=bar
로 매개변수 주입을 허용합니다. 이는 본문에서 PHP 코드를 로드하기 위해 다음 매개변수를 주입할 수 있게 해줍니다:
또한, PHP의 후속 정규화로 인해 0xAD 문자를 사용하여 "-" 매개변수를 주입하는 것이 가능합니다. 이 게시물의 익스플로잇 예제를 확인하세요.
이 게시물에서 매우 적은 문자로 브레인 펑크 PHP 코드를 생성하는 훌륭한 아이디어를 찾을 수 있습니다. 또한 여러 검사를 우회할 수 있는 함수를 실행하는 흥미로운 방법도 제안됩니다:
이 함수 호출에 코드 삽입이 가능한지 확인하세요 (여기서): 여기
If yo are debugging a PHP application you can globally enable error printing in/etc/php5/apache2/php.ini
adding display_errors = On
and restart apache : sudo systemctl restart apache2
You can use the web www.unphp.net to deobfuscate php code.
PHP Wrappers ad protocols could allow you to bypass write and read protections in a system and compromise it. For more information check this page.
If you see that Xdebug is enabled in a phpconfig()
output you should try to get RCE via https://github.com/nqxcode/xdebug-exploit
페이지에서 임의 클래스의 새 객체를 생성할 수 있다면 RCE를 얻을 수 있습니다. 방법을 배우려면 다음 페이지를 확인하세요:
PHP - RCE abusing object creation: new $_GET["a"]($_GET["b"])https://securityonline.info/bypass-waf-php-webshell-without-numbers-letters/
이 글 에 따르면, 다음과 같은 방법으로 쉬운 셸 코드를 생성할 수 있습니다:
그래서, 숫자와 문자가 없는 임의의 PHP를 실행할 수 있다면 다음과 같은 요청을 보내 임의의 PHP를 실행할 수 있습니다:
더 자세한 설명은 https://ctf-wiki.org/web/php/php/#preg_match에서 확인하세요.
웹 앱, 네트워크 및 클라우드에 대한 해커의 관점을 얻으세요
실제 비즈니스에 영향을 미치는 중요한, 악용 가능한 취약점을 찾아보고 보고하세요. 20개 이상의 맞춤형 도구를 사용하여 공격 표면을 매핑하고, 권한 상승을 허용하는 보안 문제를 찾아내며, 자동화된 익스플로잇을 사용하여 필수 증거를 수집하여 귀하의 노력을 설득력 있는 보고서로 전환하세요.
AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE) GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE)