DASCTF 2023 0X401七月暑期挑战赛RE题解

比赛期间没有什么时间,赛后做的题。

TCP

这题最难,耗时最久,好像做出来的人不多。
在这里插入图片描述
程序开始有个初始化随机数的过程,数据写入qword_5060开始的48个字节。
在这里插入图片描述
这里是主函数,连接到服务器以后,先接收32个字节(4个QWORD)的公钥,然后再用公钥将qword_5060处的随机数据加密发送给服务端。然后开始接收服务端的数据并执行相应的命令。
先看下sub_2090函数,这里摸索了很久才弄明白是RSA加密的函数:
powmod函数里使用了__modti3函数,开始不知道是干啥的,研究了好一会,才发现是取模的函数。
在这里插入图片描述
下面的解密函数就很简单,超过16个字节的用TEA解密,16个以下的用异或,分别使用qword_5060处的前32个字节和后16个字节做密钥。
在这里插入图片描述
取出抓包流量中的数据流,对数据流尝试解密后得到如下的分组:
在这里插入图片描述
其中命令部分有3个参数,参数1是命令代码值,参数2是命令参数,参数3是数据长度。
命令代码1是显示字符串,命令代码2是将解密的数据存入100*命令参数的地址,比如0201就表示将数据写入100地偏移地址。
命令代码5是执行,0508就是表示从800地址开始执行,主要PASSWORD的判断逻辑就在这部分数据里。
因此,我先把0x243个字节的数据解密,再将解密后的代码写入内存,然后用IDA反编译,得到如下程序:
在这里插入图片描述
在这里插入图片描述
可以看出来这段代码分别使用了400,500,600和700偏移处的数据,判断出结果以后,再把100或者200处的字符串数据复制到300中,然后调用命令代码4的输出功能将300处的结果显示出来。
这样就可以解密得到flag,代码片段如下:

enc=bytes.fromhex('63424fb4921f224eb2d445183f9bc6541d1ac77072a6e616e6826cbbebe96af229e79620462869e51686d4d523f782b2e5b43a769403bf62f1b87512013f95d068dc04beb337f8741b471386a7746ebc7b9c7a9568ed9b590936cdc533f6f943e3a37966362b62092ce5a3c53a95b33d0ff1ac2c5800b67b8cc40d614b8df74d4114d4bb7104b545ac7d0b9eb606578fd63561578740ce7eeaa189baacd436ae')
enc=teadec(enc,keys)
a400=[]
for i in range(len(enc)//4):
    a400.append(struct.unpack('<I',enc[i*4:i*4+4])[0])
enc=bytes.fromhex('ecc4942bbc4e2bbec5c4adb791a7096298f6347c4a277364cea894234bdcf69811f31ce644bae10edc0de4ccc200a44fa0e2faa4d2eb3b28dcecc3a468efdbfa7de2728b27dfafd1a5df4803a7986cfa768fb1f9751ba1a7d47c9a6928978810d76dceb819738f4684637d3ddd2cc41e2a4585a366d4a46b32db59508f34bf5c654be7b5c86e24cca5d1013738c32ba9b6083e76e0f93c80fe712261841e5463')
enc=teadec(enc,keys)
a500=[]
for i in range(len(enc)//4):
    a500.append(struct.unpack('<I',enc[i*4:i*4+4])[0])
enc=bytes.fromhex('60fd338fdcecb096e26a56603082a58f5b1fb0ffb7fc8faac33589ec52ed02256aba88b2c2836433a5d146c6efe784d47da7a7ffc4256f3dce73314c0171f89e9a4f6a95f59e8460d2b65fe178daba5faf8d34d99e32a50aefbbb7ed9c9507765958870dd2e1836fe608215ca753a7125f3cb86ac32d1149cf2a144b873fc7a96914d376ed2fe88d36a609596a68d8bb76e71d1b81a8db3618271f002ff6fb58')
enc=teadec(enc,keys)
a600=[]
for i in range(len(enc)//4):
    a600.append(struct.unpack('<I',enc[i*4:i*4+4])[0])
enc=bytes.fromhex('b72d657abc1a3c2133fa45fd834d28fce3b5bdd8f111bfa61386a306aa74598ea6e5022f4aac8d9acd442c44465eb334c26d060dfc8f4f59c13f3225a5ea111f9e3e9ef4c75f40b85c43dbdd5d30970cde507cd96fa6a88970e23c1dc1cb9a1eab2f4cc16444226aff6c49dd13e030240ea32267a1699b5b8c83d05c1cc257f5028d649e2b58d96a1f59fcd42f027179e7400f2c64c3063ae1f9c496ec019eba')
enc=teadec(enc,keys)
a700=[]
for i in range(len(enc)//4):
    a700.append(struct.unpack('<I',enc[i*4:i*4+4])[0])
for i in range(40):
    x=((a600[i]<<16)+a700[i]-a500[i])^a400[i]
    print(chr(x),end='')  #DASCTF{5rOV562J5Y5pu+5amn6Zuv2B5aSa5Liq}

controlflow

代码采用ROP方式去跳转和运行
在这里插入图片描述
执行完主函数就会跳转到sub_AD1220和sub_AD11A0、sub_AD1100这样
在这里插入图片描述
调试跟踪下就清楚逻辑了,然后写出来解密代码:

a=[0x00000CCF, 0x00000CC0, 0x00000CFC, 0x00000CD8, 0x00000D23, 0x00000D11, 0x00000DC8, 0x00000D7D, 0x00000DAA, 0x00000E2B, 0x00000E7C, 0x00000E5B, 0x00000EA9, 0x00000ECA, 0x00000F5A, 0x00000F5A, 0x00000FB1, 0x0000104D, 0x00001095, 0x0000117C, 0x0000137D, 0x000012F3, 0x0000142E, 0x0000141C, 0x00001233, 0x00001287, 0x000011F4, 0x00001758, 0x00001461, 0x0000122A, 0x00001782, 0x000017F7, 0x00001911, 0x0000194D, 0x00001A10, 0x00001AEB, 0x00001B90, 0x00001CE6, 0x00001DE2, 0x00001ED2]
for i in range(10,30,2):
    a[i],a[i+1]=a[i+1],a[i]
for i in range(40):
    if a[i]%3!=0:
        raise(i,'mod3 error')
    a[i]//=3
    a[i]+=i
for i in range(20):
    a[i+10]^=i*(i+1)
for i in range(40):
    a[i]-=i*i
    a[i]^=0x401
print(bytes(a))  #DASCTF{TWpnemRuSTRkVzVsWVhOMmJqZzNOREoy}

webserver

这个程序好像是用的github上的otapp框架写的,去掉符号确实也不方便理解代码。主函数逻辑如下:
先注册了几个web接口,route包括/,/Flag,/Check
在这里插入图片描述
测试的时候只有/能返回welcome DASCTF,其他的接口均返回403禁止。
搜索flag字符串的时候找到了几个Handler,应该就是接口处理函数定义的地方
在这里插入图片描述
找到CheckHander的入口sub_40617E,真正的flag判断逻辑在这里:
在这里插入图片描述
这里sub_404955是一个字符串取反解密的函数

判断部分在下图的紫框中的代码,就是要让v16经过一系列处理以后变成0:
在这里插入图片描述
其实可以看出就是矩阵乘法,v17是从unk_61B0E0复制得到,然后写代码解密即可:

a=[0x00000017, 0x0000000D, 0x00000004, 0x00000030, 0x00000029, 0x00000029, 0x0000002A, 0x00000021, 0x0000001E, 0x00000003, 0x00000045, 0x00000001, 0x0000000D, 0x0000002D, 0x00000029, 0x00000040, 0x00000008, 0x00000050, 0x0000000F, 0x0000002A, 0x00000038, 0x00000013, 0x0000003E, 0x00000046, 0x00000017, 0x0000003F, 0x0000001E, 0x00000044, 0x00000011, 0x00000038, 0x0000005C, 0x0000000C, 0x00000010, 0x00000040, 0x0000001F, 0x00000003, 0x00000011, 0x00000047, 0x0000003A, 0x00000009, 0x00000040, 0x00000053, 0x00000047, 0x00000034, 0x00000063, 0x00000059, 0x0000004C, 0x00000044, 0x00000001, 0x00000063, 0x00000010, 0x00000010, 0x00000034, 0x0000002B, 0x00000000, 0x0000002C, 0x00000032, 0x00000020, 0x00000032, 0x0000001F, 0x00000014, 0x0000003F, 0x00000002, 0x00000063, 0x00000000, 0x00000039, 0x0000004F, 0x0000002B, 0x00000047, 0x00000013, 0x00000050, 0x0000005C, 0x0000005D, 0x0000003A, 0x00000054, 0x0000004A, 0x00000051, 0x0000002D, 0x00000037, 0x00000015, 0x00000001, 0x00000063, 0x0000001E, 0x0000001C, 0x00000038, 0x00000001, 0x0000000C, 0x0000004D, 0x0000005C, 0x00000004, 0x00000025, 0x00000043, 0x0000003C, 0x00000036, 0x00000033, 0x0000004F, 0x00000026, 0x00000057, 0x00000030, 0x00000010]
v16=[0]*40
v16[0] = 33211;
v16[1] = 36113;
v16[2] = 28786;
v16[3] = 44634;
v16[4] = 30174;
v16[5] = 39163;
v16[6] = 34923;
v16[7] = 44333;
v16[8] = 33574;
v16[9] = 23555;
v16[10] = 35015;
v16[11] = 42724;
v16[12] = 34160;
v16[13] = 49166;
v16[14] = 35770;
v16[15] = 45984;
v16[16] = 39754;
v16[17] = 51672;
v16[18] = 38323;
v16[19] = 27511;
v16[20] = 31334;
v16[21] = 34214;
v16[22] = 28014;
v16[23] = 41090;
v16[24] = 29258;
v16[25] = 37905;
v16[26] = 33777;
v16[27] = 39812;
v16[28] = 29442;
v16[29] = 22225;
v16[30] = 30853;
v16[31] = 35330;
v16[32] = 30393;
v16[33] = 41247;
v16[34] = 30439;
v16[35] = 39434;
v16[36] = 31587;
v16[37] = 46815;
v16[38] = 35205;
v16[39] = 20689;
data=[]
for i in range(10):
    d=[]
    for j in range(10):
        d.append(a[j*10+i])
    data.append(d)
import numpy as np
key=[]
for i in range(4):
    d=[]
    for j in range(10):
        d.append(v16[j+i*10])
    key.append(d)
A=np.matrix(data).I
B=np.matrix(key).T
x=np.dot(A,B)
y=x.T.round().tolist()	
print(''.join(chr(int(i)) for i in y[0]+y[1]+y[2]+y[3]))   #DASCTF{CI5ZCM5piv5aaC5L2V5pS26LS555qE5Y}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/43082.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

spring-IOC

IOC容器 简介 IoC(Inversion of Control)控制反转&#xff0c;是一种基于面向对象编程法则的设计思想&#xff0c;它设计出的程序具有松耦合、更优良的特点。 IoC容器是Spring框架中重要的核心组件之一&#xff0c;贯穿了Spring从出生到成长的整个过程&#xff0c;Spring通过I…

K8S下如何搭建eureka集群

背景 传统应用上云&#xff0c;基于传统应用需要考虑上云的方案和改造成本&#xff0c;这也是传统应用上云过程中的难点&#xff0c;本篇介绍3台eureka搭建的方案。 方案一 此方案借助了K8S中Service的一些功能。 这种方案是传统方案的简单迁移版本&#xff0c;比较易于理解…

19.主题时钟

主题时钟 html部分 <div class"btn">黑色</div><div class"clock-container"><div class"time">21</div><div class"date">21</div><div class"clock"><div class&qu…

MOS,PCB如何添加散热孔、过孔

一、什么是 PCB 散热孔&#xff1f; 散热孔是利用贯通PCB板的通道&#xff08;过孔&#xff09;使热量传导到背面来散热的手法&#xff0c;配置在发热体的正下方或尽可能靠近发热体。 散热孔是利用PCB板来提高表面贴装部件散热效果的一种方法&#xff0c;在结构上是在PCB板上…

IMU和视觉融合学习笔记

利用纯视觉信息进行位姿估计&#xff0c;对运动物体、光照干扰、场景纹理缺失等情况&#xff0c;定位效果不够鲁棒。当下&#xff0c;视觉与IMU融合(VI-SLAM&#xff09;逐渐成为常见的多传感器融合方式。视觉信息与IMU 数据进行融合&#xff0c;根据融合方式同样可分为基于滤波…

【《机器学习和深度学习:原理、算法、实战(使用Python和TensorFlow)》——以机器学习理论为基础并包含其在工业界的实践的一本书】

机器学习和深度学习已经成为从业人员在人工智能时代必备的技术&#xff0c;被广泛应用于图像识别、自然语言理解、推荐系统、语音识别等多个领域&#xff0c;并取得了丰硕的成果。目前&#xff0c;很多高校的人工智能、软件工程、计算机应用等专业均已开设了机器学习和深度学习…

「网络编程」传输层协议_ TCP协议学习_及原理深入理解(一)[万字详解]

「前言」文章内容大致是传输层协议&#xff0c;TCP协议讲解&#xff0c;续上篇UDP协议。 「归属专栏」网络编程 「主页链接」个人主页 「笔者」枫叶先生(fy) 目录 一、TCP协议介绍二、TCP协议2.1 解包与分用2.2 谈谈可靠性2.3 TCP的工作模式2.4 确认应答(ACK)机制2.5 16位序号与…

绘出「星辰大海」:华为云Astro轻应用新手指南-第二章

第2章 Astro轻应用奇遇——用鼠标「拖拽」的开发 不被编程所困&#xff0c;像玩拼图一样打造订购系统&#xff01; 今天&#xff0c;我们用鼠标拖拽的方式开发订餐应用。 读过本章&#xff0c;你可以同理开发出各异的订购小程序。 继续Astro轻应用旅行吧&#xff01; 第1站…

WebSocket笔记

1. websocket介绍 WebSocket 是基于 TCP 的一种新的网络协议。它实现了浏览器与服务器全双工通信——浏览器和服务器只需要完成一次握手&#xff0c;两者之间就可以创建持久性的连接&#xff0c; 并进行双向数据传输。 HTTP协议和WebSocket协议对比&#xff1a; HTTP是短连接W…

【JavaWeb】Tomcat底层机制和Servlet运行原理

&#x1f384;欢迎来到dandelionl_的csdn博文&#xff0c;本文主要讲解Java web中Tomcat底层机制和Servlet的运行原理的相关知识&#x1f384; &#x1f308;我是dandelionl_&#xff0c;一个正在为秋招和算法竞赛做准备的学生&#x1f308; &#x1f386;喜欢的朋友可以关注一…

iNav开源代码之Filters

iNav开源代码之Filters 1. 源由2. 滤波器应用类型2.1 一般滤波2.1.1 pt1Filter2.1.2 pt2Filter2.1.3 pt3Filter2.1.4 biquadFilter2.2 kalman滤波2.3 动态gyro带通滤波2.3.1 dynamicGyroNotchFilters2.3.2 secondaryDynamicGyroNotchFilters 2.4 rpm滤波 3. 滤波器技术类型3.1 …

C# SolidWorks 二次开发 -从零开始创建一个插件(2)

上一篇我详细讲解了如何创建一个插件&#xff0c;但是无界面无按钮&#xff0c;这种插件适合配合事件偷偷的在后台做点什么事情。今天这篇讲一下如何增加一些按钮到工具栏、菜单上去。 先告诉大家这个东西注册表在哪&#xff0c;因为solidworks在这方面做的不太好&#xff0c;…

prometheus监控mysql8.x以及主从监控告警

mysql8.x主从部署请看下面文档 docker和yum安装的都有 Docker部署mysql8.x版本互为主从_争取不加班&#xff01;的博客-CSDN博客 Mysql8.x版本主从加读写分离&#xff08;一&#xff09; mysql8.x主从_myswl8双主一从读写分离_争取不加班&#xff01;的博客-CSDN博客 安装部署…

uniapp 微信小程序 placeholder字体、颜色自定义

效果图&#xff1a; 1、template <input type"text" placeholder"搜索标题" placeholder-class"placeholder-style"></input>2、style .placeholder-style{color: #2D94FF; }

通过nexus3部署公司内部的私有npm仓库

简介&#xff1a; 登录时使用默认用户admin&#xff0c;密码不知道就需要找默认的&#xff0c;点击Sign in时会提示你路径&#xff0c;这里我是这样查的&#xff0c;在linux服务器上输入以下命令 ​编辑 前言&#xff1a; 准备工作&#xff0c;可能需要一台linux服务器&#x…

讯为RK3568开发板入门之-tftpnfs的配置

基础条件 VMware虚拟机 Ubuntu18.04 【网络配置陈桥接模式】 RK3568开发板【我是用讯为的RK3568】 网线连接路由器或者和电脑直连 配置TFTP和NFS的作用 使用tftp和nfs网络挂载可以很方便的进行软件的调试&#xff0c;挂载成功后只要把Ubuntu下编译好的文件程序放到挂载的目录…

思科路由器交换机密码破解教程

1. 路由器密码的恢复. 2600、3600等新系列路由器步骤&#xff1a; 1、启动路由器&#xff0c;60秒内按下ctrlbreak键2、rommon>confreg 0x21423、rommon>reset4、router#copy startup-config running-config5、router(config)#no enable secrect //可以删除密码也可以更…

一键批量JSON标注转PNG图片工具V1.1,支持labelme快捷矩形、圆以及轮廓标注

上次发布了一个批量将labelme标注的json文件转换为png文件工具&#xff0c;但是当时只是想着自己用的&#xff0c;功能相当简单&#xff0c;一些网友使用之后跟我反馈这玩意真”垃圾“&#xff0c;很多情况都没有进行设想&#xff0c;所以在功能上很欠缺。由于小陶这几天在外地…

如何提升环境、生态、水文、土地、土壤、农业、大气等领域的数据分析能力

专题一、空间数据获取与制图 1.1 软件安装与应用讲解 1.2 空间数据介绍 1.3海量空间数据下载 1.4 ArcGIS软件快速入门 1.5 Geodatabase地理数据库 专题二、ArcGIS专题地图制作 2.1专题地图制作规范 2.2 空间数据的准备与处理 2.3 空间数据可视化&#xff1a;地图符号与…

HTTP超本文传输协议

HTTP超本文传输协议 HTTP简介HTTP请求与响应HTTP请求请求行请求头空行请求体 HTTP响应响应行响应头空行响应体 HTTP请求方法GET和POST之间的区别HTTP为什么是无状态的cookie原理session 原理cookie 和 session 的区别cookie如何设置cookie被禁止后如何使用session HTTP简介 HT…