REVERSE-COMPETITION-DSCTF-2022

REVERSE-COMPETITION-DSCTF-2022

    • catchme
    • FFunction
    • nothing
    • bad_apple
    • fantastic_cpu

catchme

安卓逆向,java层传递输入,调用native层的check方法
ida打开.so文件,没有直接找到check方法,JNI_OnLoad也看不出什么
Findcrypt查到AES的S盒,通过对S盒查找交叉引用,来到sub_B2A4函数
catchme-main
输入经过AES加密,再进行变表base64,最后与true_cipher进行比较
在AES解密前,AES_key和true_cipher都需要进行异或变换
catchme-key
catchme-cipher

from Crypto.Cipher import AES
import base64key=[0x24, 0x3C, 0x3D, 0x37, 0x36, 0x21, 0x35, 0x26, 0x3F, 0x37, 0x32, 0x2A, 0x72, 0x72, 0x72, 0x72]
for i in range(len(key)):key[i]^=0x53
print(bytes(key))
# wonderfulday!!!!enc=[0x4F, 0x1C, 0x36, 0x49, 0x09, 0x3A, 0x3F, 0x07, 0x4D, 0x3D, 0x22, 0x39, 0x00, 0x0A, 0x22, 0x25, 0x06, 0x09, 0x01, 0x20, 0x4A, 0x1B, 0x51, 0x51]
for i in range(len(enc)):enc[i]^=0x6C
print(bytes(enc))
# #pZ%eVSk!QNUlfNIjemL&w==ori_table="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
cur_table="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!@#$%^&*()+/"cipher=base64.b64decode(bytes(enc).decode().translate(str.maketrans(cur_table,ori_table)))aes=AES.new(bytes(key),AES.MODE_ECB)
print(aes.decrypt(cipher))
# flag{weu/.,iopl}

FFunction

ida打开my_plugin.dll,函数窗口第一个函数f,最后调用了memcmp函数,猜测这个f就是校验函数
在f函数的第一行代码处下断点,通过尝试,当输入的长度为30时,程序会断下来
function-f
观察此时的input,发现程序在调用f函数前,对原本的输入进行了位置变换和标准base64变换

s="flag{abcdefghijklmnopqrstuvwx}"
# 1
# f}lxawgv{uatbscrdqepfognhmiljk
# Zn1seGF3Z3Z7dWF0YnNjcmRxZXBmb2duaG1pbGpr

第32到第45行代码,是将input倒置

# 2
# rpGbp1Gaud2bmBXZxRmcjNnY0FWd7Z3Z3FGes1nZ

然后是将倒置后的input,每个字符的高四位和低四位拆分成两个字节
function-f

# 3
# ord("r")==0x72 -> 0x70 0x02
# ord("p")==0x70 -> 0x70 0x00

最后就是TEA加密,delta已知,key已知,密文(a2)已知
function-tea
于是,先解密TEA

#include <stdio.h>
#include <stdint.h>//加密函数
void encrypt(unsigned int num_rounds, uint32_t* v, uint32_t* k) {uint32_t v0 = v[0], v1 = v[1], sum = 0, i;uint32_t delta = 0x79B99E37;uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3];for (i = 0; i < num_rounds; i++) {sum += delta;v0 -= ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);v1 -= ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);}v[0] = v0; v[1] = v1;
}//解密函数
void decrypt(unsigned int num_rounds, uint32_t* v, uint32_t* k) {uint32_t v0 = v[0], v1 = v[1], i;uint32_t delta = 0x79B99E37,sum = delta*num_rounds;uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3];for (i = 0; i<num_rounds; i++) {v1 += ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);v0 += ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);sum -= delta;}v[0] = v0; v[1] = v1;
}//打印数据 hex_or_chr: 1-hex 0-chr
void dump_data(uint32_t * v,int n,bool hex_or_chr)
{if(hex_or_chr){for(int i=0;i<n;i++){printf("0x%x,",v[i]);}}else{for (int i = 0; i < n; i++){for (int j = 0; j < sizeof(uint32_t)/sizeof(uint8_t); j++){printf("0x%02x,", (v[i] >> (j * 8)) & 0xFF);}}}printf("\n");return;
}int main()
{// v为要加解密的数据uint32_t v[] = { 0x5c15754c,0xd1d781e7,0x501bf173,0xcb4db222,0x215d61f5,0x3fca9ee7,0x7c76b5c7,0xc7dd8cb9,0x990d23fa,0xbab1ad3,0x8e12c932,0xd307baf2,0xe52dd123,0xfbb68f2c,0xbdd853e3,0x892e1e4e,0x39dd66fa,0x87feec65,0x307c5e60,0x340c6c00 };// k为加解密密钥,4个32位无符号整数,密钥长度为128位uint32_t k[4] = { 0x0BABEC0FE,0x0DEADBEEF,0x0FACEB00C,0x0DEADC0DE };// num_rounds,建议取值为32unsigned int r = 32;int n = sizeof(v) / sizeof(uint32_t);/*printf("加密前明文数据:");dump_data(v,n,1);for(int i=0;i<n/2;i++){encrypt(r,&v[i*2], k);}printf("加密后密文数据:");dump_data(v,n,1);*/for(int i=0;i<n/2;i++){decrypt(r,&v[i*2], k);}printf("解密后明文数据:");dump_data(v,n,1);printf("解密后明文字符:");dump_data(v,n,0);return 0;
}
// 解密后明文数据:0x6400130,0x4600440,0x2500740,0x8500330,0xa400c60,0x3600e60,0x9300c60,0x4600130,0x2400330,0xd400450,0x2500770,0x2600850,0x6500f60,0x8500030,0xe400730,0xa500030,0x5400860,0x9400750,0x1300370,0xa500e60,
// 解密后明文字符:0x30,0x01,0x40,0x06,0x40,0x04,0x60,0x04,0x40,0x07,0x50,0x02,0x30,0x03,0x50,0x08,0x60,0x0c,0x40,0x0a,0x60,0x0e,0x60,0x03,0x60,0x0c,0x30,0x09,0x30,0x01,0x60,0x04,0x30,0x03,0x40,0x02,0x50,0x04,0x40,0x0d,0x70,0x07,0x50,0x02,0x50,0x08,0x60,0x02,0x60,0x0f,0x50,0x06,0x30,0x00,0x50,0x08,0x30,0x07,0x40,0x0e,0x30,0x00,0x50,0x0a,0x60,0x08,0x40,0x05,0x50,0x07,0x40,0x09,0x70,0x03,0x30,0x01,0x60,0x0e,0x50,0x0a,

再按照3、2、1的顺序将解TEA得到的明文转换成flag即可

import base64
s="flag{abcdefghijklmnopqrstuvwx}"
# 1
# f}lxawgv{uatbscrdqepfognhmiljk
# Zn1seGF3Z3Z7dWF0YnNjcmRxZXBmb2duaG1pbGpr# 2
# rpGbp1Gaud2bmBXZxRmcjNnY0FWd7Z3Z3FGes1nZ# 3
# ord("r")==0x72 -> 0x70 0x02
# ord("p")==0x70 -> 0x70 0x00# 4
# TEAtea_plain=[0x30,0x01,0x40,0x06,0x40,0x04,0x60,0x04,0x40,0x07,0x50,0x02,0x30,0x03,0x50,0x08,0x60,0x0c,0x40,0x0a,0x60,0x0e,0x60,0x03,0x60,0x0c,0x30,0x09,0x30,0x01,0x60,0x04,0x30,0x03,0x40,0x02,0x50,0x04,0x40,0x0d,0x70,0x07,0x50,0x02,0x50,0x08,0x60,0x02,0x60,0x0f,0x50,0x06,0x30,0x00,0x50,0x08,0x30,0x07,0x40,0x0e,0x30,0x00,0x50,0x0a,0x60,0x08,0x40,0x05,0x50,0x07,0x40,0x09,0x70,0x03,0x30,0x01,0x60,0x0e,0x50,0x0a]
cipher=""
for i in range(0,len(tea_plain),2):cipher+=chr(tea_plain[i]+tea_plain[i+1])
cipher=cipher[::-1]
cipher=base64.b64decode(cipher)flag=""
for i in range(0,len(cipher),2):flag+=chr(cipher[i])
for i in range(len(cipher)-1,0,-2):flag+=chr(cipher[i])
print(flag)
# flag{Emp0wer_F1utter_w1th_C!!}

nothing

出题人,richar师傅的wp:ISC-Nothing出题思路及WriteUp
FallW1nd师傅的wp:nothing

bad_apple

附件是1个.elf文件和1张电路图,电路图里是树莓派连接ST7789
根据字符串"frame: %d\n"的交叉引用,来到sub_100003A4函数,猜测是画图函数
frame_data是每一帧填充的像素,总共2192帧,每帧的大小为宽240*高180
apple-main
dump出byte_100068CC数据

data=get_bytes(0x100068CC,1343128)
with open("D:\\CTFFiles\\ZMatches\\202208\\20220801-360DSCTF-Final\\bad_apple\\data","wb") as f:f.write(data)

直接复制ida反编译出来的伪代码,把每帧的frame_data输出到文件里

#include<stdio.h>
#include"defs.h"int32 frame_id=0;int32 dword_20000FC8=0;char byte_100068CC[1343128];int __fastcall sub_1000035C(int *a1)
{int v1; // r1_BYTE *i; // r3int v3; // r4int v4; // r6char *v5; // r7while ( 1 ){v1 = a1[2];if ( v1 )break;v4 = *a1;v5 = (char *)&byte_100068CC + *a1;v3 = 0;for ( i = (_BYTE *)v5; ; ++i ){v3 |= (*i & 0x7F) << v1;if ( (char)*i >= 0 )break;LOBYTE(v1) = v1 + 7;}a1[2] = v3;*a1 = v4 + i + 1 - (_BYTE *)v5;*((_WORD *)a1 + 2) = ~*((_WORD *)a1 + 2);}a1[2] = v1 - 1;return *((unsigned __int16 *)a1 + 2);
}void sub_100003A4(FILE *fp)
{int i; // r4_WORD frame_data[43204]; // [sp+0h] [bp-15188h] BYREFprintf("frame: %d\n", frame_id);for ( i = 0; i <= 43199; ++i )frame_data[i] = sub_1000035C(&dword_20000FC8);for(int y=0;y<180;y++){for(int x=0;x<240;x++){if(frame_data[y*240+x])fwrite("*",1,1,fp);elsefwrite("0",1,1,fp);}fwrite("\n",1,1,fp);}frame_id++;return;
}int main()
{FILE *fp = NULL;fp = fopen("D:\\CTFFiles\\ZMatches\\202208\\20220801-360DSCTF-Final\\bad_apple\\data", "rb");fseek(fp, 0, SEEK_SET);fread(byte_100068CC, 1, 1343128, (FILE*)fp);fclose(fp);fp = fopen("D:\\CTFFiles\\ZMatches\\202208\\20220801-360DSCTF-Final\\bad_apple\\flag", "wb");for(int i = 0; i < 2192; i++) {sub_100003A4(fp);}fclose(fp);return 0;
}

在最后的地方看到flag
apple-flag

fantastic_cpu

verilog写的vm,flag的4个int,4选2,选4组做加法,和data比较
通过运行.v,发现data是已知的8个int的第0、2、4、6个
cpu-data
用claripy求解即可得到flag

import claripyflag=[claripy.BVS(f"flag_{i}",64) for i in range(4)]data=[0x90771cb9,0xe3520b8,0x65dfd405,0x74c00bcc,0x64b1ca23,0x74942df9,0xb7385ab6,0xec36f96c]cons=[[0,1],[1,3],[2,3],[0,3]]s=claripy.Solver()
for i in range(len(cons)):s.add(flag[cons[i][0]]+flag[cons[i][1]]==data[i*2])for i in s.batch_eval(flag,1):for c in i:print(hex(c)[2:].zfill(8),end="")
# 70e7d1b51f8f4b041e61412246508901

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

01-单一职责原则(SPR)

1. 背景 类T负责两个不同的职责&#xff1a;职责P1&#xff0c;职责P2。当由于职责P1需求发生改变而需要修改类T时&#xff0c;有可能会导致原本运行正常的职责P2功能发生故障。 2. 定义 不要存在多于一个导致类变更的原因。通俗的说&#xff0c;即一个类只负责一项职责。 3.…

Python3 已经安装相关库,Pycharm 仍然报错 ModuleNotFoundError: No module named 'xxxxxx' 的解决办法

以 requests 库为例&#xff0c;打开 cmd&#xff0c;运行命令 pip install requests&#xff0c;即可安装 requests 库&#xff0c;由于我已经安装过&#xff0c;所以会提示 Requirement already satisfied 此时&#xff0c;我们使用 Pycharm 运行以下代码&#xff1a; impo…

Sharepoint学习笔记—Site Definition系列-- 3、创建ListDefinition

创建一个List Definition有多条途径&#xff0c;这里由于我们要基于前面的用户自定义Content Type来创建一个List Defintion&#xff0c;所以我们就需要使用到List Definition From Content Type模板。 这里先大致描述如何创建List Definition&#xff0c;然后重点介绍一下Li…

Sharepoint学习笔记—error处理-- The user does not exist or is not unique.

看到网上不少人遇到过这种类似的错误&#xff0c;而产生这种错误的原因也有多种&#xff0c;我产生此错误的背景是在试图通过ECMAscript对象模型把一个User添加到某个指定的Group中时遇到的。 问题1.当我试图把一个User添加到Sharepoint的某个指定的Group&#xff0c;…

Knockout学习笔记之二($root,$parent及$data的区别)

以下是我从Google上找到的一个例子&#xff0c;非常生动形象&#xff0c;我修改了部分代码&#xff0c;具体内容如下&#xff1a; 对于$root 与$parent的区别&#xff1a; $root refers to the view model applied to the DOM with ko.applyBindings;译&#xff1a;$root 是指…

GitHub 学生认证,申请 GitHub 学生包

GitHub 面对学生推出了学生认证服务&#xff0c;通过认证后就可以得到学生包&#xff0c;学生包大概有十几项优惠&#xff0c;包括 DATADOG Pro 帐户、免费两年的10台服务器&#xff0c;Icons8 3个月的带图标&#xff0c;照片&#xff0c;插图和音乐订阅服务、JETBRAINS 专业桌…

Python3 使用 pymysql 连接 MySQL 建表时出现 Warning3719 UTF8 警告

在学习 Python3 爬虫关系型数据库储存时&#xff0c;利用 pymysql 连接 MySQL 建表&#xff0c;测试用的代码如下&#xff0c;第一句 SQL 用于获取当前 MySQL 的版本信息&#xff0c;第二句 SQL 执行创建 spiders 数据库的操作&#xff0c;如果程序代码正确&#xff0c;将会输出…

完美解决 bash: hexo: command not found

背景介绍&#xff1a;有好几天没动过 Hexo 博客了&#xff0c;今天准备更新的时候输入 hexo s&#xff0c;报错 bash: hexo: command not found&#xff0c;这是啥情况&#xff1f;以前都好好的&#xff0c;想了一下&#xff0c;大概是这几天折腾各种 Python 库的原因&#xff…

Sharepoin学习笔记 —架构系列--02 Sharepoint的处理(Process)与执行模型(Trust Model) 1

Sharepoint210有四种执行模型: 1、完全信任执行模型(Full Trust) 2、Bin/CAS 执行模型 &#xff08;1与2都属于场解决方案&#xff09; 3、沙盒执行模型(Sand Box) 4、 混合执行方法&#xff08;Hybrid Approach&#xff09; Sharepoint最简单的处理模型就是一个完整的Asp.net应…

Python3 爬虫学习笔记 C10【数据储存系列 — MySQL】

Python3 爬虫学习笔记第十章 —— 【数据储存系列 — MySQL】文章目录【10.1】MySQL 基本操作语句数据库操作表操作表的结构表的数据【10.2】Python 连接 MySQL【10.3】创建表【10.4】插入数据【10.5】更新数据【10.6】删除数据【10.7】查询数据【10.8】实战训练 — 爬取CSDN博…

Sharepoin学习笔记—架构系列--03 Sharepoint的处理(Process)与执行模型(Trust Model) 2

上文我们了解了一个外部Http Request进入IIS 工作进程(W3WP)的处理与执行信任模型&#xff0c;这个阶段是Sharepoint的四种执行模型都必须经过的处理阶段&#xff0c;其中Sharepoint场解决方案与任何 ASP.NET 应用程序一样就是在 IIS 工作进程(w3wp)中运行的&#xff0c;所以上…

Python3 爬虫学习笔记 C11【数据储存系列 — MongoDB】

Python3 爬虫学习笔记第十一章 —— 【数据储存系列 — MongoDB】文章目录【11.1】关于 MongoDB【11.2】MongoDB 基本操作语句【11.3】连接 MongoDB【11.4】指定数据库【11.5】指定集合【11.6】插入数据【11.6】数据查询【11.7】数据计数【11.8】数据排序【11.9】数据偏移【11.…

Sharepoin学习笔记—架构系列--04 Sharepoint的四种执行模型 1

Sharepoint210有四种执行模型 1、完全信任执行模型(Full Trust) 2、Bin/CAS 执行模型 &#xff08;1与2都属于场解决方案&#xff09; 3、沙盒执行模型(Sand Box) 4、 混合执行方法 (Hybrid Approach) 下面分别来看看它们是怎么回事 一、场解决方案 场解决方案是在 Share…

Python3 爬虫学习笔记 C12【验证码对抗系列 — 图形验证码】

Python3 爬虫学习笔记第十二章 —— 【验证码对抗系列 — 图形验证码】文章目录【12.1】关于普通图形验证码【12.2】tesserocr 库识别验证码【12.3】pytesseract 库识别验证码【12.4】验证码处理【12.5】tesserocr 与 pytesserocr 相关资料【12.1】关于普通图形验证码 普通图形…

Sharepoin学习笔记—架构系列--05 Sharepoint的四种执行模型 2

上一篇我们看了场解决方案与沙盒方案两种执行模型&#xff0c;其中场解决方案包括有完全信任方式与Bin/CAS方式两种&#xff0c;这里让我们继续来看看最后一个执行模型&#xff0c;即混合模型(或混合模式)。 三、混合模式&#xff08;hybrid approaches&#xff09; 所谓混合模…

Python3 爬虫学习笔记 C13【验证码对抗系列 — 滑动验证码】

Python3 爬虫学习笔记第十三章 —— 【验证码对抗系列 — 滑动验证码】文章目录【13.1】关于滑动验证码【13.2】滑动验证码攻克思路【13.3】模拟登录 bilibili — 总体思路【13.4】主函数【13.5】初始化函数【13.6】登录函数【13.7】验证码元素查找函数【13.8】元素可见性设置函…

Sharepoin学习笔记—架构系列—06 Sharepoint服务(Services)与服务应用程序框架(Service Application Framework) 1

Sharepoint服务是Sharepoint的重要组成&#xff0c;可以说Sharepoint的许多网站功能都是基于这些服务构架起来的。这里把Sharepoint服务的相关要点总结一下。 1、什么是 SharePoint 服务&#xff1f; SharePoint 服务是一项 IT 服务&#xff0c;它是运行在后台&#xff0c;为调…

Python3 爬虫学习笔记 C14【验证码对抗系列 — 点触验证码】

Python3 爬虫学习笔记第十四章 —— 【验证码对抗系列 — 点触验证码】文章目录【14.1】关于点触验证码【14.2】点触验证码攻克思路【14.3】模拟登录 12306 — 总体思路【14.4】主函数【14.5】初始化函数【14.6】破解入口函数【14.7】账号密码输入函数【14.8】页面截图函数【14…

Sharepoin学习笔记—架构系列—07nSharepoint服务(Services)与服务应用程序框架(Service Application Framework) 2

上一篇我们以问答的方式明确了Sharepoint服务的一些概念&#xff0c;这里我们重点来看两个方面:Sharepoint服务器构架对象模型以及Sharepoint 服务应用程序的某些拓扑结构 一、Sharepoint服务器构架对象模型 转存失败重新上传取消 二、Sharepoint 服务应用程序的某些拓扑结…

Sharepoin学习笔记—架构系列--08 Sharepoint的数据模型(DataModel)、数据管理(Data Management)与查询(Query System)

Sharepoint Foundation中的首要数据结构就是列表(List), 每个List属于某种List Type&#xff0c;与此类似&#xff0c;每个列表中的列(Column)属于某种FieldType&#xff0c;而每一条列表记录(List Item)属于某种Content Type.至于外部数据(External Data)&#xff0c;即来自于…