[网鼎杯 2020 青龙组]jocker

SMC(self-Modifying Code): 自修改代码,程序在执行某段代码的过程中会对程序的代码进行修改,只有在修改后的代码才是可汇编,可执行的。在程序未对该段代码进行修改之前,在静态分析状态下,均是不可读的字节码。

查壳:32位无壳程序,直接拖ida

首先shift+f12搜索字符串,但是除了main函数中的一句请输入flag提示之外在没有什么有用的。

main函数

// positive sp value has been detected, the output may be wrong!
int __cdecl main(int argc, const char **argv, const char **envp)
{char Str[50]; // [esp+12h] [ebp-96h] BYREFchar Destination[80]; // [esp+44h] [ebp-64h] BYREFDWORD flOldProtect; // [esp+94h] [ebp-14h] BYREFsize_t v7; // [esp+98h] [ebp-10h]int i; // [esp+9Ch] [ebp-Ch]
​__main();puts("please input you flag:");if ( !VirtualProtect(encrypt, 0xC8u, 4u, &flOldProtect) )exit(1);scanf("%40s", Str);v7 = strlen(Str);if ( v7 != 24 ){puts("Wrong!");exit(0);}strcpy(Destination, Str);wrong(Str);omg(Str);for ( i = 0; i <= 186; ++i )*((_BYTE *)encrypt + i) ^= 0x41u;if ( encrypt(Destination) )finally(Destination);return 0;
}

可以看到第一个条件是flag长度要为24

然后将str先复制到Destination这里,再调用wrong函数对str进行修改。

wrong函数

char *__cdecl wrong(char *a1)
{char *result; // eaxint i; // [esp+Ch] [ebp-4h]
​for ( i = 0; i <= 23; ++i ){result = &a1[i];if ( (i & 1) != 0 )a1[i] -= i;       //i为偶数elsea1[i] ^= i;       //i为奇数}return result;
}

可以看出wrong函数的功能是把a1里每个元素按照下标的奇偶进行相应的加密处理

然后来到omg函数

omg函数

int __cdecl omg(char *a1)
{int v2[24]; // [esp+18h] [ebp-80h] BYREFint i; // [esp+78h] [ebp-20h]int v4; // [esp+7Ch] [ebp-1Ch]
​v4 = 1;qmemcpy(v2, &unk_4030C0, sizeof(v2));for ( i = 0; i <= 23; ++i ){if ( a1[i] != v2[i] )v4 = 0;}if ( v4 == 1 )return puts("hahahaha_do_you_find_me?");elsereturn puts("wrong ~~ But seems a little program");
}

查看unk_430C0部分

直接给出字符串了,破解一下吧(shift + E直接导出字符串)

key = 0x66, 0x6B, 0x63, 0x64, 0x7F, 0x61, 0x67, 0x64, 0x3B, 0x56, 0x6B, 0x61, 0x7B, 0x26, 0x3B, 0x50, 0x63,       0x5F, 0x4D, 0x5A, 0x71, 0x0C, 0x37, 0x66
flag = ''
for i in range(24):if i % 2 == 1:flag += chr(key[i] + i)else:flag += chr(key[i] ^ i)
print(flag)
#结果:
#flag{fak3_alw35_sp_me!!}

假的flag

在omg后面还有一个循环,最后的一点应该是在这里的

循环中还有一个encrypt函数,但是无法打开

红色标注的下面那里像是一段乱码一样,导致无法反汇编出来结果吧,然后尝试找出调用了encrypt函数的地址,od动调一下,看看这个函数到底在干什么

在这里发现了encrypt函数和finally函数分别被调用

既然由前面的函数得到的flag是个假的,那最后正确的flag一定是通过这两个函数处理的,下一步就是分析encrypt函数

OD打开后 在0x401833地址处下断点

然后F9运行至断点处,在应用中随意输入24位字符

然后F7步入

可以看到这里的函数是已经解密了,然后可以直接olldump脱壳,直接保存新的exe

然后再用ida打开它

encrypt函数

int __cdecl start(int a1)
{int v2[19]; // [esp+1Ch] [ebp-6Ch] BYREFint v3; // [esp+68h] [ebp-20h]int i; // [esp+6Ch] [ebp-1Ch]
​v3 = 1;qmemcpy(v2, &unk_403040, sizeof(v2));for ( i = 0; i <= 18; ++i ){if ( (char)(*(_BYTE *)(i + a1) ^ aHahahahaDoYouF[i]) != v2[i] ){puts("wrong ~");v3 = 0;exit(0);}}puts("come here");return v3;
}

aHahahahaDoYouF中的字符串是hahahaha_do_you_find_me?

unk_403040中的字符通过shift + E 可以直接导出

然后写个脚本破解一下

v2 = [14, 13, 9, 6, 19, 5, 88, 86, 62, 6, 12, 60, 31, 87, 20, 107, 87, 89, 13]
xor = 'hahahaha_do_you_find_me?'
flag = []
for i in range(0, 19):flag.append(v2[i] ^ ord(xor[i]))
for i in range(0, 19):print(chr(flag[i]), end = '')

得到结果是

flag{d07abccf8a410c

flag明显少了一部分啊,但是它最后还有一个

finally函数

int __cdecl sub_40159A(int a1)
{unsigned int v1; // eaxchar v3[9]; // [esp+13h] [ebp-15h] BYREFint v4; // [esp+1Ch] [ebp-Ch]
​strcpy(v3, "%tp&:");v1 = time(0);srand(v1);v4 = rand() % 100;v3[6] = 0;*(_WORD *)&v3[7] = 0;if ( (v3[(unsigned __int8)v3[5]] != *(_BYTE *)((unsigned __int8)v3[5] + a1)) == v4 )return puts("Really??? Did you find it?OMG!!!");elsereturn puts("I hide the last part, you will not succeed!!!");
}

这段代码具体是什么意思真的没搞明白,但是前面的加密算法是异或,所以尝试一下异或

得到的flag现在没有最后一位 },那么剩下的字符串里肯定是最后一个字符异或一个数得到}

flag = []
v3 = [37, 116, 112, 38, 58]#既是‘%tp&:’
key = ord('}') ^ 58
for i in range(5):flag.append(chr(v3[i] ^ key))
print(''.join(flag))

最后得到

b37a}

flag

flag{d07abccf8a410cb37a}

[网鼎杯 2020 青龙组]jocker相关推荐

  1. BUUCTF Reverse/[网鼎杯 2020 青龙组]jocker

    BUUCTF Reverse/[网鼎杯 2020 青龙组]jocker 先看下文件信息,没有加壳,32位程序 运行一下,又是一道字符串比较的题目 用IDA32位打开,分析一下 // positive ...

  2. Buuctf [网鼎杯 2020 青龙组]jocker 题解

    目录 一.主函数逻辑 二.wrong函数和omg函数--假flag 1.wrong函数 2.omg函数 3.假flag 三.encrypt和finally函数--真flag 1.打开sp指针偏移显示 ...

  3. re -25 buuctf [网鼎杯 2020 青龙组]jocker

    [网鼎杯 2020 青龙组]jocker 前话:ida7.6设置栏内没有general,可以通过ctrl+shift+p打开命令面板,搜索option打开设置选项,于Disassembly设置堆栈显示 ...

  4. [网鼎杯 2020 青龙组]jocker(详解)

    首先我们查看一下信息,32位程序,无壳: 然后用IDA打开,提示// positive sp value has been detected, the output may be wrong! 出现了 ...

  5. [BUUCTF]Reverse——[网鼎杯 2020 青龙组]jocker

    网上大部分是动调,我尝试IDC解一下, 无壳,32位,放入IDApro,查看main函数 查看wrong和str函数,借出假的flag a=[0x66,0x6B,0x63,0x64,0x7F,0x61 ...

  6. 网鼎杯2020 青龙组 jocker

    来看一眼题目逻辑哈,看函数名知道_Z5wrongPc那一处是个假加密函数,先不看...然后下面很明显是一道smc了 对加密函数的前186(0xBA)位异或 0x41 这里可以用idapython对加密 ...

  7. [BUUCTF][网鼎杯 2020 青龙组]jocker 分析与记录

    无壳,IDA打开可以直接进入main函数: 第12行调用VirtualProtect函数更改了offset encrypt处的访问保护权限 BOOL VirtualProtect(LPVOID lpA ...

  8. buuctf刷题记录21 [网鼎杯 2020 青龙组]jocker

    今天挑战一下,结果最后还是看了别人的wp才写出来的 无壳,ida查看发现不能f5,原因堆栈不平衡 进行栈指针修改 修改出错的地方的栈指针偏移,快捷键alt+k,值改为0 然后就能f5了, 逻辑也不难, ...

  9. undefsafe原型链[网鼎杯 2020 青龙组]notes

    感觉是考原型链但还是有点不知道如何下手,呜呜呜呜呜呜. 从浅入深 Javascript 原型链与原型链污染 [网鼎杯 2020 青龙组]notes var express = require('exp ...

最新文章

  1. python querystring encode_百分号 json
  2. Java项目:人事管理系统(java+javaweb+jdbc)
  3. 2021年中国工业互联网安全大赛核能行业赛道writeup之隐写
  4. Spring Boot + Vue.js 实现前后端分离(附源码)
  5. R语言使用t.test函数计算两组独立数据的t检验(Independent t-test)
  6. CTF(pwn) 堆利用 之 unlink 介绍
  7. STM32 CAN波特率计算程序
  8. Kaspersky Security Center部署
  9. 千千静听界面模拟(C#)
  10. Python-day17
  11. 新版iTunes如何设置手机铃声
  12. 搜狗输入法原先能在word中输入中文,现在不行。
  13. 程序员考公指南1-59
  14. SUMOlympics
  15. 单商户商城系统功能拆解40—分销应用—分销设置
  16. 网络营销人员21条基本能力要求
  17. [XCTF-pwn] 31_ciscn-2018-Quals_house_of_grey
  18. DNS解析:腾讯云转战cloudfare解析记录
  19. vue实现九宫格效果
  20. java-对文件内容进行排序

热门文章

  1. 在线购物系统问题描述
  2. 软件测试 - 白盒测试
  3. 怎么把两个pdf合并成一个?三种合并方法任你选择
  4. 基于餐饮管理系统的软件体系结构设计读书报告
  5. 网页前端项目评审参考标准
  6. 顺丰同城公布发售结果:IPO定价位于下限,连年录得巨额亏损
  7. 中国空气泵行业市场供需与战略研究报告
  8. 七牛云如何配置免费 https 阿里云SSL证书
  9. 罗马数字的计数规则和算法实现罗马数字和十进制的相互转换
  10. Android内存优化(二)系统进程之logd的native memory优化