最新要闻
- 环球滚动:女子开特斯拉被查酒驾 罚2000元记12分:本人称吃醉蟹 交警回应
- 销售开特斯拉撞了顾客的特斯拉 拒赔5万元:直言刹车了停不住
- 史上口碑最好的小米旗舰!小米13京东好评率接近100%
- 全球快资讯:基于海拉克斯打造 丰田推出首款纯电皮卡原型车 网友:丑到我眼睛了
- 天天快资讯丨卡神离开Meta 批老东家效率低下:GPU利用率5%简直是侮辱
- 全球热点评!小米MIX Fold 2新配色下周首销:5.4mm厚度已是行业极限 8999元
- 今热点:同价位无敌手!小米万兆路由器更新
- AMD、NVIDIA齐发新品 显卡厂商的好日子来了:加速去库存
- 世界快报:男子1199元买长江存储2TB SSD吐槽是翻新 手指划痕:网友看完笑死
- 世界快消息!用户真实评价小米13:太惊艳了 这就是小米13带给我的感觉
- 精彩看点:北欧品质 口感清爽:OATLY燕麦奶4.1元/斤新低(商超29.8元)
- 【天天新视野】男子称买到过期3月沐浴露获赔5元:看不起谁呢
- 全球热资讯!BBA的禁脔 垂涎者不止蔚来
- 环球热点评!冬天空调取暖不热 可能是这些问题
- 环球观速讯丨小米13成了!线下门店卖断货 供不应求
- 世界速看:挑战行业多项不可能 一加11即将发布:最强性能旗舰
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
焦点关注:[PingCTF2022] guess what - S1gMa
前言
本题来自PingCTF2022 - guess what,早上12点被树木喊起来对超极长的代码审计和写 \(exp\) ,俩人直接干到下午 \(6\) 点,对着一个不存在的错误 \(debug\) 了 \(4\) 个小时,然后世一血就没了(悲),于是决定记录下来>_<
题面
本题是到交互题,题面给了 \(6\) 个脚本:\(main.py\)、\(common.py\)、\(part1.py\)、\(part2.py\)、\(part3.py\)、\(pow.py\).
代码按照顺序给出:
(资料图片)
from src.common import *from src.pow import NcPowserfrom src.part1 import part1_, part1from src.part2 import part2_, part2from src.part3 import part3_, part3def main(): part1_() input("Press enter to continue...") for i in range(2, 18): part1(i) part2_() input("Press enter to continue...") for i in range(2, 6): part2(6) part3_() input("Press enter to continue...") part3()if __name__ == "__main__": if (SHOULD_USE_POW): nc = NcPowser() if nc.pow(): main() else: print("Wrong answer") exit(0) else: main()
from time import timeimport itertoolsimport randomfrom Crypto.Util.number import bytes_to_longfrom progress.bar import ChargingBarfrom time import *import osSHOULD_USE_POW = TrueSHOULD_USE_ANNOYING_ANIMATIONS = Trueintro_dictionary = "AB"mid_dictionary = "ABCD"def brrr_the_strings(strings): print("PRINTING...") for i in range(len(strings)): print(strings[i]) print("DONE PRINTING")
from src.common import *def part1_(): print("Hi, this is my game :)") print("I will give you some sTrInGs, and you will have to tell me, which one is missing, seems easy, right? :D") print("Let"s try it out!")def part1(l): if (SHOULD_USE_ANNOYING_ANIMATIONS): for i in ChargingBar("Loading sTrInGs", max=16, check_tty=False).iter(range(16)): sleep(0.1) strings = ["".join(x) for x in itertools.product(intro_dictionary, repeat=l)] indexToRemove = bytes_to_long(os.urandom(32)) % len(strings) removedString = strings[indexToRemove] strings.remove(removedString) random.shuffle(strings) brrr_the_strings(strings) print("Which one is missing?") guess = input("> ") if guess == removedString: print("Correct!") else: print("Wrong!!!!! Cmon, you can do it!") exit(0)
from src.common import *def part2_(): print("You are doing great! Now, let"s try something harder!") print("I will give you AGAIN some StRiNgS, and you will have to tell me, which one is missing, seems still doable, right? :D") print("But I need you to hurry this time, so you will have to guess the missing string in 5 seconds.") print("Let"s try it out!")def part2(l): if (SHOULD_USE_ANNOYING_ANIMATIONS): for i in ChargingBar("Loading StRiNgS", max=32, check_tty=False).iter(range(32)): sleep(0.1) strings = ["".join(x) for x in itertools.product(mid_dictionary, repeat=l)] indexToRemove = bytes_to_long(os.urandom(32)) % len(strings) removedString = strings[indexToRemove] strings.remove(removedString) random.shuffle(strings) brrr_the_strings(strings) print("Which one is missing?") guess = input("> ") if guess == removedString: print("Correct!") else: print("Wrong!!!!! Cmon, you can do it!") exit(0)
from src.common import *from flag import flagassert(len(flag) == 2**(2**2))def part3_(): print("Ok. This is kinda spooky. This time I will show you that I know everything, and you will have to prove me wrong in order to get the flag.")def part3(): real_flag = flag[5:][:-1] if (SHOULD_USE_ANNOYING_ANIMATIONS): for i in ChargingBar("Loading flags", max=64, check_tty=False).iter(range(64)): sleep(0.1) flags = ["".join(x) for x in itertools.permutations(real_flag)] flags.remove(real_flag) random.shuffle(flags) brrr_the_strings(flags) print("If you are so smart, then you should be able to give the flag in 15 seconds!") start = time() guess = input("> ") end = time() if guess == flag and end - start <= 15: print("Correct! Here is your flag: " + flag) else: print("Well, at least I can rest. GL") exit(0)
import hashlibimport secretsclass NcPowser:def __init__(self, difficulty=20, prefix_length=17):self.difficulty = difficultyself.prefix_length = prefix_lengthdef get_challenge(self):prefix = secrets.token_hex(self.prefix_length)rest = secrets.token_hex(self.difficulty - self.prefix_length)return prefix, restdef pow(self):prefix, rest = self.get_challenge()print(f"sha256(\"{prefix} + {"?"*(len(rest))}\") == \"{hashlib.sha256((prefix + rest).encode()).hexdigest()}\"")answer = input("> ")if hashlib.sha256((prefix + answer).encode()).hexdigest() == hashlib.sha256((prefix + rest).encode()).hexdigest():return Trueelse:return Falsedef solve_pow(self, prefix, result, unknown_count):from itertools import productpossibilities = product("0123456789abcdef", repeat=unknown_count)for ans in possibilities:answer = "".join(ans)if hashlib.sha256((prefix + answer).encode()).hexdigest() == result:return answerif __name__ == "__main__":print("Solving PoW...")nc = NcPowser()# sha256("dd32ded3ce6a9c864b5b2a0c364003b409 + ??????") == "e46f470c74eff9629dd828c0bfada1ff87bbeede19cdcd3fbcac8684a07b1384"prefix = "dd32ded3ce6a9c864b5b2a0c364003b409"result = "e46f470c74eff9629dd828c0bfada1ff87bbeede19cdcd3fbcac8684a07b1384"unknown_count = 6solution = nc.solve_pow(prefix, result, unknown_count)print(f"Solution: {solution}")exit(0)
审计代码:
main.py
def main(): part1_() input("Press enter to continue...") for i in range(2, 18): part1(i) part2_() input("Press enter to continue...") for i in range(2, 6): part2(6) part3_() input("Press enter to continue...") part3()
显然是按照顺序进行闯关,不过这里要注意循环中读进去的参数(对后面很重要)。
common.py
intro_dictionary = "AB"mid_dictionary = "ABCD"
这里给出的是后面两个 \(part\) 用来生成字符串的字典。
pow.py
sha256("dd32ded3ce6a9c864b5b2a0c364003b409 + ??????") =="e46f470c74eff9629dd828c0bfada1ff87bbeede19cdcd3fbcac8684a07b1384"prefix = "dd32ded3ce6a9c864b5b2a0c364003b409"
这里就可以看出,第一步是sha256的爆破,6位的掩码爆破,差不多要跑十分钟(后面错一次就要跑这一次出题人坏b)
EXP
p = remote("guess_what.ctf.knping.pl",20000)str=p.recvuntil(b"> ")key=str[8:-84].decode()h=str[58:-4].decode()print(key)print(h)for i in range(16777216): tmp = key + hex(i).zfill(6)[2:8] if hashlib.sha256(tmp.encode("utf-8")).hexdigest() == h: print(tmp) breakprint(tmp[-6:])p.sendline(tmp[-6:])p.recvuntil(b"Press enter to continue...")p.sendline()
part1.py
strings = ["".join(x) for x in itertools.product(intro_dictionary, repeat=l)]
这里是字符串的生成规则,\(itertools.product\) 指的是对字典里的字符串进行排列组合取数,取数规则就是 \(repert\)。
removedString = strings[indexToRemove]strings.remove(removedString)random.shuffle(strings)
然后将其获取到的字符串数组打乱,随机删去一个数,然后猜删了什么。
EXP
EXP在分析完题目后就非常好写了,只需要讲排列组合列出来对生成的字符串进行比对然后 \(sendline\) 即可。
for l in range(2,18): p.recvuntil(b"PRINTING...\n") keyword=p.recvuntil(b"DONE PRINTING\n",drop=True) keyword=keyword[:-1].decode() keywordlist=keyword.split("\n") #print(keyword) #print(keywordlist) for e in itertools.product("AB", repeat=len(keywordlist[0])): s = "".join(e) if s not in keywordlist: p.sendline(s)p.recvuntil(b"Press enter to continue...")p.sendline()
对输出字符串进行切割利用 split("\n")进行转为数组(群里大佬教的,长见识了),然后根据题意利用循坏改变 \(repert\) 的值一层一层爆破即可
part2.py
strings = ["".join(x) for x in itertools.product(mid_dictionary, repeat=l)]
思路和 \(part1\) 同理,惟独改变的是字典
EXP
for l in range(2,6): p.recvuntil(b"PRINTING...\n") keyword=p.recvuntil(b"DONE PRINTING\n",drop=True) keyword=keyword[:-1].decode() keywordlist=keyword.split("\n") #print(keyword) #print(keywordlist) for e in itertools.product("ABCD", repeat=len(keywordlist[0])): s = "".join(e) if s not in keywordlist: p.sendline(s)p.recvuntil(b"Press enter to continue...")p.sendline()
part3.py
assert(len(flag) == 2**(2**2))real_flag = flag[5:][:-1]flags = ["".join(x) for x in itertools.permutations(real_flag)]flags.remove(real_flag)random.shuffle(flags)brrr_the_strings(flags)if guess == flag and end- start <= 15:
以上是关键代码,意思分别是告诉 \(flag\) 为 \(16\) 位字符串,同时在交互时只保留中心 \(flag\),然后对其进行全排列、乱序、删数,然后必须在15秒内猜到。
EXP
看到全排列就知道有 \(10^{10}\) 个可能性,而且 \(15s\) 的限制,不得不对代码进行优化,因此考虑现生成完整的全排列数列,然后利用 \(sort()\) 同时对两个数组进行排序,然后一一比对遇到不一样的既找到答案,如果不这样干的话将会最多比对 \(C_{10^{10}}^{2}\) 次,时间必然会超时。
p.recvuntil(b"PRINTING...\n")keyword=p.recvuntil(b"DONE PRINTING\n",drop=True)keyword=keyword[:-1].decode()keywordlist=keyword.split("\n")flags = ["".join(x) for x in itertools.permutations("i8a9eF2d4n")]keywordlist.sort()flags.sort()p.recvuntil(b"> \n")for i in range(0,10**10): if keywordlist[i] != flags[i]: p.sendline("ping{"+flags[i]+"}") breakp.interactive()
完整EXP
import itertoolsfrom pwn import *import hashlibcontext.log_level="debug"p = remote("guess_what.ctf.knping.pl",20000)str=p.recvuntil(b"> ")key=str[8:-84].decode()h=str[58:-4].decode()print(key)print(h)for i in range(16777216): tmp = key + hex(i).zfill(6)[2:8] if hashlib.sha256(tmp.encode("utf-8")).hexdigest() == h: print(tmp) breakprint(tmp[-6:])p.sendline(tmp[-6:])p.recvuntil(b"Press enter to continue...")p.sendline()#part1for l in range(2,18): p.recvuntil(b"PRINTING...\n") keyword=p.recvuntil(b"DONE PRINTING\n",drop=True) keyword=keyword[:-1].decode() keywordlist=keyword.split("\n") #print(keyword) #print(keywordlist) for e in itertools.product("AB", repeat=len(keywordlist[0])): s = "".join(e) if s not in keywordlist: p.sendline(s)p.recvuntil(b"Press enter to continue...")p.sendline()#part2for l in range(2,6): p.recvuntil(b"PRINTING...\n") keyword=p.recvuntil(b"DONE PRINTING\n",drop=True) keyword=keyword[:-1].decode() keywordlist=keyword.split("\n") #print(keyword) #print(keywordlist) for e in itertools.product("ABCD", repeat=len(keywordlist[0])): s = "".join(e) if s not in keywordlist: p.sendline(s)p.recvuntil(b"Press enter to continue...")p.sendline()#getflagp.recvuntil(b"PRINTING...\n")keyword=p.recvuntil(b"DONE PRINTING\n",drop=True)keyword=keyword[:-1].decode()keywordlist=keyword.split("\n")flags = ["".join(x) for x in itertools.permutations("i8a9eF2d4n")]keywordlist.sort()flags.sort()p.recvuntil(b"> \n")for i in range(0,10**10): if keywordlist[i] != flags[i]: p.sendline("ping{"+flags[i]+"}") breakp.interactive()
结语
以上便是本题的所有内容了,总体来说不是很难,主要考验代码审计能力和优化能力,是挺有意思的一道题~
感谢大家阅读,求求点点关注哦~
会不断更新各个比赛的wp、题目分享、出题笔记、学习笔记等。
碎碎念
阳了真的真的真的真的好难受呜呜呜呜呜呜。。。。。。咩。。。。。。。。。
-
智慧树视频课件课程下载工具,如何在电脑端下载智慧树视频课件PDF,PPT到本地
一 安装智慧树下载器1 获取学无止下载器https: www xuewuzhi cn zhihuishu_downloader2 下载安...
来源: 焦点关注:[PingCTF2022] guess what - S1gMa
环球滚动:女子开特斯拉被查酒驾 罚2000元记12分:本人称吃醉蟹 交警回应
销售开特斯拉撞了顾客的特斯拉 拒赔5万元:直言刹车了停不住
智慧树视频课件课程下载工具,如何在电脑端下载智慧树视频课件PDF,PPT到本地
史上口碑最好的小米旗舰!小米13京东好评率接近100%
VUE组件
【世界时快讯】安全多方计算:(2)隐私信息检索方案汇总分析
全球快资讯:基于海拉克斯打造 丰田推出首款纯电皮卡原型车 网友:丑到我眼睛了
天天快资讯丨卡神离开Meta 批老东家效率低下:GPU利用率5%简直是侮辱
全球热点评!小米MIX Fold 2新配色下周首销:5.4mm厚度已是行业极限 8999元
今热点:同价位无敌手!小米万兆路由器更新
全球观热点:第八天 循环的花里胡哨的用法
重学c#系列——linq(4) [三十]
【速看料】400行的象棋程序
AMD、NVIDIA齐发新品 显卡厂商的好日子来了:加速去库存
世界快报:男子1199元买长江存储2TB SSD吐槽是翻新 手指划痕:网友看完笑死
世界快消息!用户真实评价小米13:太惊艳了 这就是小米13带给我的感觉
精彩看点:北欧品质 口感清爽:OATLY燕麦奶4.1元/斤新低(商超29.8元)
【天天新视野】男子称买到过期3月沐浴露获赔5元:看不起谁呢
焦点信息:java基础面试题
【报资讯】Docker的资源控制管理
全球热资讯!BBA的禁脔 垂涎者不止蔚来
当前通讯!Docker网络模式
环球热点评!冬天空调取暖不热 可能是这些问题
环球观速讯丨小米13成了!线下门店卖断货 供不应求
热点!web项目的开发---第二天
世界今头条!SpringCloud-Ribbon学习笔记
世界速看:挑战行业多项不可能 一加11即将发布:最强性能旗舰
世界动态:python语法笔记
令人气愤!女子曝无良汽修店为赚钱高速路上撒钉子专扎车胎
天天视讯!刘作虎:OPPO一加正式开启双品牌战略 100亿投资扶植一加
环球观速讯丨义乌开始生产阿根廷夺冠球衣 还是三颗星 阿根廷辟谣:假的 侵权
世界快播:“顶级大众” 宾利Batur公布工艺细节:210克黄金3D打印
老人手指被卡:消防员用开塞露救了差点被剪的蓝宝石戒指
全球快资讯:一文了解 Dubbo 的代码架构
今日报丨关于整数二分的详解
滚动:预编译#error的使用
全球要闻:YoloV7 标签匹配机 loss 计算详解
安全多方计算(1):不经意传输协议
每日快讯!元旦假期首日火车票今开抢!迎出行小高峰:五大热门目的地出炉
观天下!Find N2系列发布背后:OPPO再次展示对产品精益求精态度
天天要闻:全国冻哭预警地图来了:周末20余省份或被冻哭 冷到破纪录
热议:售价超300万!乔布斯亲手编号Apple-1电脑落锤成交:46年后 开机画面眼前一亮
世界最大独立圆柱体水族馆爆裂:1500多条鱼全军覆没
世界杯决战前夕 法国又有两大主力倒下!5人感染神秘流感
【环球热闻】被加价千元:AMD喊话正加大RX 7900系生产!NV 4080笑而不语
世界简讯:VUE数据双向绑定
第一百一十四篇: JS数组Array(三)数组常用方法
世界上最大的鱼缸今日突然破裂:100万升水泄露 1500条鱼死亡
放假3天不调休!2023年元旦假期首日火车票开售 除夕票这一天就能买
天天报道:学谁不好学特斯拉!几十万的宝马车 容不下一个收音机
观天下!骗子诈骗1250万 买彩票中1450万:已退还给39名聋哑人
全球热讯:XSX性能比PS5强 但为何游戏性能总是输?
天天速看:Python函数/动态参数/关键字参数
天天热点!女子发烧敷20分钟面膜揭下变3D立体面具 医生提醒:影响退热 当心面瘫
方便面消费第一大国是我们:超6成人每周吃三次
世界速读:注解在Android中的使用场景
热推荐:锂金属电池爱长枝晶?韩国科学家找到破解之法
【当前独家】确认了!《阿凡达2:水之道》没有片尾彩蛋
天天观速讯丨1152分区+4K 144Hz 联合创新32寸miniLED显示器首发5399元
终于修好了!Win11新补丁解决22H2大文件复制缓慢Bug
首款第二代骁龙8游戏旗舰!红魔8 Pro来了
今日最新!王思聪投资百万成立新公司 经营范围包括动漫游戏开发
全球最资讯丨全自动门锁比半自动更人性化!但半自动更受青睐 真相终于揭开
世界简讯:Hessian2序列化支持这一点,让重构dubbo接口更容易了
【热闻】-真正的国产亲民MPV 新款传祺M6 PRO上市:11.98万起
看点-旗下新作首月收入超4.8亿!腾讯成为《妮姬》开发商Shift Up第二大股东
女子高烧39.8度喊妈 妈妈以为鸭子叫没搭理 网友:怎么又变异了
观察-《三体》动画明天开播第3集 官方公布史强、古筝行动档案
【天天聚看点】微信小程序报错“getLocation:fail the api need to be declared in the requiredPriva
【全球快播报】记录--三分钟打造自己专属的uni-app工具箱
视点!小米万兆路由器用上企业级处理器!卢伟冰:降维打击
【天天报资讯】LCD面板价格连连下跌!LG P7 LCD工厂停产
环球关注:中国高速看山东!山东高速施工用上北斗卫星:精度达到毫米级
世界要闻:三大板卡品牌之一的微星缺席RX 7900首发 原因揭晓:直接非公版
世界快消息!女生手捏温度计度数直线飙到38度!腋下一测39.5度
天天日报丨项目经理的核心价值:以目标为导向做正确的事
环球热点评!Vue3项目-生成Cron表达式组件
世界今亮点!MIUI 14终于再次成为最好用的操作系统
ChatGPT已经牛到取代谷歌了?测试结果来了
男子每天点赞上万次被处罚 当庭演示一分钟才点赞91个
【当前独家】“智轨列车”亮相咸阳:可识别虚拟轨道 载客达300人
全球新动态:研究揭示马桶不盖盖后果多严重:致病菌满屋乱飞
全球滚动:Java 反射概念的引入
天天热议:小米13太火爆了 博主准点抢购结果秒没:最后等了20分钟捡漏 成功上车
【天天速看料】“火流星”掉落 专家判断陨石来自46亿年前:比地球上所有石头都古老
当前速看:《阿凡达2》成2022进口片首日票房冠军!时隔69天单日再破亿 豆瓣8.4分
价格能顶半套正版Win11 老牌压缩软件WinZip 27发布 你会买吗?
快播:44岁的泰国长公主因心脏问题失去知觉:紧急送医
渗透实录-01
要闻:Nacos 2.2 正式发布,这次更新太炸了!
世界关注:Kerberos身份验证在ChunJun中的落地实践
IM通讯协议专题学习(五):Protobuf到底比JSON快几倍?全方位实测!
【聚看点】多数据源事务处理-涉及分布式事务
怎么硬盘安装ubuntu?硬盘ubuntu安装教程
佳能5d系列哪个最好?佳能5DX相机参数
诺基亚6200上市价格是多少?诺基亚6200手机参数
烤箱如何预热?烤箱预热的方法有哪些?
短讯!IDEA没有新建jsp文件按钮
VS2022生成控制台引用程序,.net应用导出成exe文件,发部成独立文件的详细图解