首页 > 其他分享 >X`NUCA 2022 unravelmfc

X`NUCA 2022 unravelmfc

时间:2023-09-18 23:01:23浏览次数:31  
标签:sub esp int unravelmfc char ebp 2022 v4 NUCA

这应该是第八周第三道题,我记录一下我的做题过程,虽然有很多疑问 首先查壳 ![Image description](https://bbs.xdsec.org/assets/files/2023-04-10/1681115143-134913-image.png) Unknown EXE,不知道是个啥写的,010看一下吧,没发现有python这样的字符存在,那就ida打开 然后shift+f12先找字符串 有一个个`i_will_not_be_found`,一看就是出题人放的,果断双击后x交叉引用 ``` int sub_599C80() {   int v0; // eax   int v1; // eax   int v2; // eax   int v3; // eax   unsigned int i; // [esp+118h] [ebp-54h]   size_t v6; // [esp+124h] [ebp-48h]   char *Str; // [esp+130h] [ebp-3Ch]   char v8[32]; // [esp+13Ch] [ebp-30h] BYREF   int v9; // [esp+168h] [ebp-4h]
  v0 = sub_579EA4("i_will_not_be_found");   v1 = sub_5736A8(v0);   sub_5761A0(v1);   v9 = 0;   if ( !NtCurrentPeb()->BeingDebugged )   {     v2 = sub_579EA4("you_can_not_find_me");     v3 = sub_5736A8(v2);     sub_56DE0B(v3);   }   Str = (char *)sub_577203(v8);   v6 = j__strlen(Str);   for ( i = 0; i < 0x292; ++i )     byte_875188[i] ^= Str[i % v6];//SMC   v9 = -1;   sub_571628(v8);   return 0; } ``` 好像是个SMC?先不管,交叉引用byte_875188看看谁调用了它![Image description](https://bbs.xdsec.org/assets/files/2023-04-10/1681115868-707561-image.png) 果然有,第二个双击跟进 ``` bool __cdecl sub_599540(char *a1, unsigned int a2) {   size_t v2; // eax   char v4; // [esp+Fh] [ebp-141h]   char Buf1[68]; // [esp+D4h] [ebp-7Ch] BYREF   unsigned int i; // [esp+118h] [ebp-38h]   int v7[8]; // [esp+124h] [ebp-2Ch] BYREF   __int16 v8; // [esp+144h] [ebp-Ch]   char v9; // [esp+146h] [ebp-Ah]
  memset(v7, 0, sizeof(v7));   v8 = 0;   v9 = 0;   for ( i = 0; i < a2; ++i )   {     v4 = *a1++;     *((_BYTE *)v7 + i) = v4;   }   sub_57971F(v7, a2);   ((void (__fastcall *)(char *, int *, unsigned int))byte_875188)(Buf1, v7, a2);   v2 = j__strlen(Str);   return j__memcmp(Buf1, Str, v2) == 0; } ``` emmmm,return了一个比较函数的返回值,看样子是Buf1只要和Str相等返回值就为1了,emm,看看返回值有啥用,sub_599540交叉引用一下,来到这里 ``` void __thiscall sub_5A1080(CWnd *this) {   void *v1; // esp   int v2; // eax   int v3; // eax   const WCHAR *v4; // eax   LPCWSTR lpText; // [esp+18h] [ebp-18Ch]   char *lpCaption; // [esp+1Ch] [ebp-188h]   const WCHAR *lpCaptiona; // [esp+1Ch] [ebp-188h]   CHAR v8[4]; // [esp+20h] [ebp-184h] BYREF   _RTC_ALLOCA_NODE *PAllocaInfoList; // [esp+12Ch] [ebp-78h]   unsigned int v10; // [esp+138h] [ebp-6Ch]   char *Str; // [esp+144h] [ebp-60h]   int v12; // [esp+150h] [ebp-54h]   wchar_t *String; // [esp+15Ch] [ebp-48h]   UINT CodePage; // [esp+168h] [ebp-3Ch]   int v15; // [esp+174h] [ebp-30h]   char v16[12]; // [esp+180h] [ebp-24h] BYREF   CWnd *v17; // [esp+18Ch] [ebp-18h]   int v18; // [esp+1A0h] [ebp-4h]
  v17 = this;   PAllocaInfoList = 0;   if ( NtCurrentPeb()->BeingDebugged )     sub_56F206();   sub_57BDA8(4u);   sub_573856(v16);   v18 = 0;   CWnd::GetDlgItem(v17, 1000);   CWnd::GetWindowTextW(v16);   v15 = 0;   CodePage = sub_573608();   v12 = 0;   String = (wchar_t *)sub_5773F2(v16);   if ( String )   {     v15 = j__wcslen(String) + 1;     if ( v15 <= 0x3FFFFFFF )     {       v1 = alloca(2 * v15 + 36);       lpText = (LPCWSTR)sub_5717A9(v8, String, 2 * v15, CodePage);     }     else     {       lpText = 0;     }     lpCaption = (char *)lpText;   }   else   {     lpCaption = 0;   }   Str = lpCaption;   v10 = j__strlen(lpCaption) >> 1;   if ( sub_57378E(lpCaption, v10) && (unsigned __int8)sub_56D4B0(&Str[v10], v10) )   {     v2 = sub_5768A8(&unk_87989C);     lpCaptiona = (const WCHAR *)sub_57007A(v2);     v3 = sub_57086D(aFlag);     v4 = (const WCHAR *)sub_5782F2(v3);     sub_579328(v4, lpCaptiona, 0);   }   v18 = -1;   sub_57A8E5(v16); } ``` 我们刚刚的返回值就在最后那个if里,返回值为1才会执行里面的操作,if里的第三行好像就显示falg正确(aflag里存的是flag正确),那现在我们要做的就是,分析sub_57378E()和sub_56D4B0()这两个函数就行 (看样子是把字符串分成两部分了,v10>>1 先分析第一部分: ``` bool __cdecl sub_599540(char *a1, unsigned int a2) {   size_t v2; // eax   char v4; // [esp+Fh] [ebp-141h]   char Buf1[68]; // [esp+D4h] [ebp-7Ch] BYREF   unsigned int i; // [esp+118h] [ebp-38h]   int v7[8]; // [esp+124h] [ebp-2Ch] BYREF   __int16 v8; // [esp+144h] [ebp-Ch]   char v9; // [esp+146h] [ebp-Ah]
  memset(v7, 0, sizeof(v7));   v8 = 0;   v9 = 0;   for ( i = 0; i < a2; ++i )   {     v4 = *a1++;     *((_BYTE *)v7 + i) = v4;   }   RC4((int)v7, a2);   ((void (__fastcall *)(char *, int *, unsigned int))byte_875188)(Buf1, v7, a2);   v2 = j__strlen(Str);   return j__memcmp(Buf1, Str, v2) == 0; } ``` 经分析对密钥是有一个类似RC4操作的,密钥是`sorry_you_are_wrong`,然后先把这个SMC解了吧( ``` int sub_599C80() {   int v0; // eax   int v1; // eax   int v2; // eax   int v3; // eax   unsigned int i; // [esp+118h] [ebp-54h]   size_t v6; // [esp+124h] [ebp-48h]   char *Str; // [esp+130h] [ebp-3Ch]   char v8[32]; // [esp+13Ch] [ebp-30h] BYREF   int v9; // [esp+168h] [ebp-4h]
  v0 = sub_579EA4("i_will_not_be_found");   v1 = sub_5736A8(v0);   sub_5761A0(v1);   v9 = 0;   if ( !NtCurrentPeb()->BeingDebugged )   {     v2 = sub_579EA4("you_can_not_find_me");     v3 = sub_5736A8(v2);     sub_56DE0B(v3);   }   Str = (char *)sub_577203(v8);   v6 = j__strlen(Str);   for ( i = 0; i < 0x292; ++i )     byte_875188[i] ^= Str[i % v6];   v9 = -1;   sub_571628(v8);   return 0; } ``` ``` from ida_bytes import * addr =0x875188 key="you_can_not_find_me" for i in range(0x292):     patch_byte(addr+i,get_byte(addr+i)^ord(key[i%len(key)])) ``` 奇怪,解出来是这样的 ``` void __usercall sub_875231(int a1@<edx>, _BYTE *a2@<ecx>, int a3@<ebp>) {   unsigned int v3; // edi   char v4; // bl   char v5; // dl   int v6; // ecx   _BYTE *v7; // eax   unsigned int v8; // ebx   char v9; // cl   unsigned int v10; // esi   char v11; // dl   char v12; // dl   char v13; // cl   char v14; // dl   char v15; // cl
  v8 = *(_DWORD *)(a3 + 8);   v7 = a2;   v10 = 0;   *(_DWORD *)(a3 - 4) = a1;   v3 = v8 - 2;   *(_DWORD *)(a3 - 8) = a2;   if ( v8 != 2 )   {     do     {       v13 = *(_BYTE *)(a1 + v10);       v12 = v13 & 3;       v9 = (v13 >> 2) & 0x3F;       v11 = 16 * v12;       *v7 = v9 + 35;       v15 = *(_BYTE *)(*(_DWORD *)(a3 - 4) + v10 + 1);       v4 = v15 & 0xF;       v5 = (v15 >> 4) & 0xF | v11;       v6 = *(_DWORD *)(a3 - 4);       v7[1] = v5 + 35;       v14 = *(_BYTE *)(v6 + v10 + 2);       v10 += 3;       v7[2] = ((v14 >> 6) & 3 | (4 * v4)) + 35;       v7[3] = (v14 & 0x3F) + 35;       v7 += 4;       a1 = *(_DWORD *)(a3 - 4);     }     while ( v10 < v3 );     v8 = *(_DWORD *)(a3 + 8);   }   if ( v10 < v8 )     JUMPOUT(0x87540C);   JUMPOUT(0x875222); } ``` 怎么只对了前一部分,啊,抓狂,不会了( 分析第二个函数: ``` bool __cdecl sub_5996C0(char *a1, int a2) {   __int64 v3; // rax   int v4; // [esp+10h] [ebp-144h]   char v5; // [esp+13h] [ebp-141h]   unsigned int j; // [esp+D8h] [ebp-7Ch]   unsigned __int64 v7; // [esp+E4h] [ebp-70h]   int v8; // [esp+ECh] [ebp-68h]   int v9; // [esp+F0h] [ebp-64h]   unsigned __int64 v10; // [esp+F4h] [ebp-60h]   unsigned __int64 v11; // [esp+FCh] [ebp-58h]   int v12[4]; // [esp+10Ch] [ebp-48h] BYREF   unsigned int i; // [esp+11Ch] [ebp-38h]   int v14[8]; // [esp+128h] [ebp-2Ch] BYREF   __int16 v15; // [esp+148h] [ebp-Ch]   char v16; // [esp+14Ah] [ebp-Ah]   char *v17; // [esp+15Ch] [ebp+8h]
  v4 = *a1;   v17 = a1 + 1;   if ( v4 != 102 )     return 0;   memset(v14, 0, sizeof(v14));   v15 = 0;   v16 = 0;   for ( i = 0; i < a2 - 1; ++i )   {     v5 = *v17++;     *((_BYTE *)v14 + i) = v5;   }   for ( j = 0; j < 4; ++j )   {     sub_5751B5((int)&v14[2 * j], (int)v12);     TEA((int)v12, (int)&dword_875048[4 * j]);     *((_DWORD *)&v7 + 2 * j) = v12[0];     *((_DWORD *)&v7 + 2 * j + 1) = 0;     LODWORD(v3) = *((_DWORD *)&v7 + 2 * j);     HIDWORD(v3) = *((_DWORD *)&v7 + 2 * j + 1);     v3 <<= 32;     *((_DWORD *)&v7 + 2 * j) = v3;     *((_DWORD *)&v7 + 2 * j + 1) = HIDWORD(v3);     HIDWORD(v3) = *((_DWORD *)&v7 + 2 * j + 1);     *((_DWORD *)&v7 + 2 * j) |= v12[1];     *((_DWORD *)&v7 + 2 * j + 1) = HIDWORD(v3);   }   return v8 == 798585087       && v9 == -550095698       && v7 < v10       && v10 < v11       && v10 - v7 == 4568540450738734457i64       && v7 + v11 == 0x162F924623D2CAE0i64       && v11 - v10 == 0x7C3C71F1B295D77Fi64; } ``` 这好像是个tea加密 ``` unsigned int __fastcall sub_8754EF(unsigned int *a1, int *a2) {   unsigned int v2; // esi   int v3; // ebx   unsigned int v4; // eax   int v5; // edi   int v6; // edx   unsigned int result; // eax   int v8; // ecx   unsigned int v9; // [esp-28h] [ebp-28h]   int v11; // [esp-14h] [ebp-14h]   int v12; // [esp-10h] [ebp-10h]   int v13; // [esp-Ch] [ebp-Ch]   int v14; // [esp-8h] [ebp-8h]
  v2 = *a1;   v4 = a1[1];   v14 = *a2;   v8 = a2[1];   v12 = a2[2];   v3 = 32;   v11 = v8;   v13 = a2[3];   v5 = 0;   do   {     v5 += 607369562;     v2 += (v5 + v4) ^ (v14 + 16 * v4) ^ (v8 + (v4 >> 5));     v6 = (v5 + v2) ^ (v12 + 16 * v2) ^ (v13 + (v2 >> 5));     v8 = v11;     v9 = v6 + v4;     --v3;     v4 += v6;   }   while ( v3 );   result = v9;   *a1 = v2;   a1[1] = v9;   return result; } ``` 可以试着解出后半段的flag ``` #include<stdio.h> #include<stdint.h> int decrypto_Tea(uint32_t *a,uint32_t *key) {   uint32_t v2 =*a;   uint32_t v4 =a[1],v14=*key,v8=key[1],v12=key[2],v13=key[3];   int v3 =32;   uint32_t v5 =0x86772b40;   do{       v3--;       v4-=(v5 + v2) ^ (v12 + 16 * v2) ^ (v13 + (v2 >> 5));        v2 -= (v5 + v4) ^ (v14 + 16 * v4) ^ (v8 + (v4 >> 5));        v5 -= 0x2433B95A;   }while(v3);   *a=v2;   a[1]=v4;   } int main() {   uint32_t a[8]={0x2d46347f,0x5e79f6f4,0xDF3634AE,0x2F9970FF,0x6cacebd5,0x12c2fc6d,0xe8e95dc6,0xc558d3ec};   uint32_t key[16] ={     0xD9610D02, 0x2AADA57D, 0xA37537F1, 0xC29E3913, 0xD5942CE8, 0x608CCE66, 0x6D593422, 0x21E5D6F2,     0xED3A9235, 0x9DAD62C4, 0x3856641B, 0x71F75B9D, 0xDCDEDAE8, 0xEAD2D1A0, 0xBAC4F564, 0xDA4772AC}; for(int i=0,j=0;i<8;i+=2,j+=4) {   decrypto_Tea(&a[i],&key[j]);   printf("0x%x,",a[i]);   printf("0x%x,",a[i+1]); } printf("\n");
puts(a); return 0; } //f1cUlt_foR_THe_r0Ok1E_t0_REver5e ```

标签:sub,esp,int,unravelmfc,char,ebp,2022,v4,NUCA
From: https://www.cnblogs.com/fux1aoyun/p/17713377.html

相关文章

  • 2022年中国大学生程序设计竞赛女生专场 ACEGHIL
    2022年中国大学生程序设计竞赛女生专场目录2022年中国大学生程序设计竞赛女生专场概况A-减肥计划C-测量学E-睡觉G-排队打卡H-提瓦特之旅I-宠物对战L-彩色的树概况因为女生赛,要给女队找找题,我又试了下2022女生赛,题目很多小细节需要注意,不然会wa很多发,前\(3\)题......
  • [HUBUCTF 2022 新生赛]ezPython
    附件链接:https://wwvc.lanzouj.com/iIqq218z5x0d给了一个pyc文件利用命令将pyc转换为py文件uncompyle6ezPython.pyc>ezPython.py打开py文件#uncompyle6version3.9.0#Pythonbytecodeversionbase3.7.0(3394)#Decompiledfrom:Python3.8.2(tags/v3.8.2:7b3ab......
  • 2022年07月 python界面可视化 VS2022配置PyQt5环境
    文章目录 一、VS2022配置PyQt5环境1.安装anaconda及opencv-python1.1安装对应的anaconda包1.2安装opencv-python2.安装PyQt53.安装PyQt常用工具4.配置系统环境变量5.配置VS2022中的外部工具6.第一个VS2022下的pyqt5程序一、VS2022配置PyQt5环境本机环境:......
  • [Writeup]2022 NewstarCTF_Week5(Web部分)
    一只网络安全菜鸟--(˙<>˙)/--写博客主要是想记录一下自己的学习过程,过两年毕业了也能回头看看自己都学了些啥东西。由于本人水平有限内容难免有错误、疏漏、逻辑不清、让人看不懂等各种问题,恳请大家批评指正如果我写的东西能对你有一点点帮助,那真是再好不过了。2023Newsta......
  • M1版本MacBook使用PD配置kali2022.1虚拟机
    经过了两天的努力终于成功了,在这里把过程记录一下。主机:M1芯片MACBOOK_PRO14寸软件:paralleldesktop18.1.1镜像:kali-linux-2022.1-installer-arm64前前后后安装了好几个版本,2021.4、2022.1、2022.2、2022.4、2023.1、2023.3,都是在安装pdtools的时候卡住,然后解决不了问题从......
  • Sketchup 2015、2016、2017、2018、2019、2020、2021、2022、2023(草图大师)下载
    SketchUp是一套直接面向设计方案创作过程的设计工具,其创作过程不仅能够充分表达设计师的思想而且完全满足与客户即时交流的需要,它使得设计师可以直接在电脑上进行十分直观的构思,是三维建筑设计方案创作的优秀工具。草图大师也就是SketchUp,是一个建筑景观专业的3D建模软件,由于运行......
  • 草图大师下载-草图大师2022官网版 各个版本下载
    sketchup草图大师是一款应用于建筑领域的全新三维建模软件。sketchup草图大师的功能是非常强大的,成为全球千万设计师选择的设计工具,模型很多质量很好。sketchup草图大师是必不可少的一款建模软件,有需要的朋友们不妨下载试试看。软件地址:看置顶贴sketchup草图大师安装步骤:1、在本站......
  • origin软件下载 origin2022最新中文版下载 各个版本下载
    Origin制图功能增强数据和管理导入功能大为增强;对原有的图形类型进行了重整,使之更加合理;数据处理方面,参数设置的功能大大增强,在各个方面可以细调;数据分析和处理:回归,拟合,统计,图象处理,信号处理,光谱处理等功能都比以前强大;软件地址:看置顶贴Origin8.0软件特色1.为了获得更高效的数......
  • ACL2022 paper1 CAKE: A Scalable Commonsense-Aware Framework for Multi-View Knowl
    CAKE:用于多视域知识图谱补全的可扩展常识感知框架ACL2022Abstract  知识图谱存储大规模事实三元组,然而不可避免的是图谱仍然具有不完整性。(问题)以往的只是图谱补全模型仅仅依赖于事实域数据进行实体之间缺失关系的预测,忽略了宝贵的常识知识。以往的知识图嵌入技术存在无效负......
  • 【专题】2022年中国跨境电商行业研究报告PDF合集分享(附原数据表)
    报告链接:http://tecdat.cn/?p=32044近年来,我国的跨境电子商务发展迅速,在过去五年中,其贸易额增长率达到了16.2%,已经成为稳定对外贸易的一支重要力量。阅读原文,获取专题报告合集全文,解锁文末52份跨境电商行业相关报告。一方面,随着跨境电子商务的发展,跨境电子商务的监管政策得到了......