1、下载

PE文件,控制台程序

2、main函数

大致分析,请看下面的注释

int __cdecl main(int argc, const char **argv, const char **envp)
{unsigned int str_length; // eaxunsigned int myflag_length; // eaxvoid *v5; // raxvoid *v7; // raxint i; // [rsp+24h] [rbp-D4h]void *memory; // [rsp+28h] [rbp-D0h]char myflag[32]; // [rsp+30h] [rbp-C8h] BYREFchar Str[128]; // [rsp+50h] [rbp-A8h] BYREFstrcpy(Str, "12345678abcdefghijklmnopqrspxyz");memset(&Str[32], 0, 0x60ui64);memset(myflag, 0, 0x17ui64);sub_1400054D0("%s", myflag);                  // 输入字符串memory = malloc(0x408ui64);                   // v9应该是一个内存地址,是申请下来的地址str_length = strlen(Str);sub_140001120(memory, Str, str_length);       // 关键myflag_length = strlen(myflag);sub_140001240(memory, myflag, myflag_length); // 关键for ( i = 0; i < 22; ++i ){if ( ((unsigned __int8)myflag[i] ^ 0x22) != main_break[i] )// 加密之后的myflag[i]^0x22=main_break[i]{v5 = (void *)sub_1400015A0(&off_14013B020, "error");// 输出错误_CallMemberFunction0(v5, sub_140001F10);return 0;}}v7 = (void *)sub_1400015A0(&off_14013B020, "nice job");// 正确_CallMemberFunction0(v7, sub_140001F10);return 0;
}

sub_140001120函数和sub_140001240函数看起来很重要

提取main_break[]数组

unsigned char main_break[] =
{0x9E, 0xE7, 0x30, 0x5F, 0xA7, 0x01, 0xA6, 0x53, 0x59, 0x1B, 0x0A, 0x20, 0xF1, 0x73, 0xD1, 0x0E, 0xAB, 0x09, 0x84, 0x0E, 0x8D, 0x2B, 0x00, 0x00
};

3、sub_140001120函数

__int64 __fastcall sub_140001120(_DWORD *a1, __int64 key, int key_length)
{__int64 result; // raxint i; // [rsp+0h] [rbp-28h]int j; // [rsp+0h] [rbp-28h]int v6; // [rsp+4h] [rbp-24h]int v7; // [rsp+8h] [rbp-20h]int tmp; // [rsp+Ch] [rbp-1Ch]_DWORD *s_box; // [rsp+10h] [rbp-18h]*a1 = 0;a1[1] = 0;s_box = a1 + 2;             //给s_box放在堆空间里面for ( i = 0; i < 256; ++i )s_box[i] = i;                               // 给 v9数组初始化 0~255v6 = 0;result = 0i64;LOBYTE(v7) = 0;for ( j = 0; j < 256; ++j ){                                         // 下面这一段是RC4加密,v8是临时变量,进行交换tmp = s_box[j];v7 = (key[v6] + tmp + v7);            // Key[v6]+tmp+v7s_box[j] = s_box[v7];s_box[v7] = tmp;if ( ++v6 >= key_length )                   // v6下标在规定范围内255循环v6 = 0;                                   // 重置为0result = (unsigned int)(j + 1);}return result;                                // 返回一个result
}

可以得出结论,sub_140001120是re4_init函数

Str="12345678abcdefghijklmnopqrspxyz" 是key

4、sub_140001240函数

那么这个函数就是RC4加密函数了,稍微分析了一下,发现写的代码很妙啊

_DWORD *__fastcall sub_140001240(_DWORD *memory, __int64 myflag, int myflag_length)
{_DWORD *result; // raxint i; // [rsp+0h] [rbp-28h]int tmp1; // [rsp+4h] [rbp-24h]int tmp2; // [rsp+8h] [rbp-20h]int v7; // [rsp+Ch] [rbp-1Ch]int v8; // [rsp+10h] [rbp-18h]_DWORD *s_box; // [rsp+18h] [rbp-10h]tmp1 = *memory;tmp2 = memory[1];s_box = memory + 2;for ( i = 0; i < myflag_length; ++i ){                                             // 这段RC4写的很妙啊tmp1 = (unsigned __int8)(tmp1 + 1);v7 = s_box[tmp1];tmp2 = (unsigned __int8)(v7 + tmp2);v8 = s_box[tmp2];s_box[tmp1] = v8;                           // 交换s_box盒s_box[tmp2] = v7;*(_BYTE *)(myflag + i) ^= LOBYTE(s_box[(unsigned __int8)(v8 + v7)]);// myflag[i] ^=s_box[v8+v7]}*memory = tmp1;result = memory;memory[1] = tmp2;return result;
}

5、解题

网上找一下RC4的解题脚本,做RC4这类题,只要找到密文 和 key,就可以做出来

flag1=[]
main_break=[0x9E, 0xE7, 0x30, 0x5F, 0xA7, 0x01, 0xA6, 0x53, 0x59, 0x1B,0x0A, 0x20, 0xF1, 0x73, 0xD1, 0x0E, 0xAB, 0x09, 0x84, 0x0E,0x8D, 0x2B, 0x00, 0x00]
for i in range(len(main_break)):flag1.append(main_break[i]^0x22)
#flag1是经过rc4加密后的值
#现在有 flag1 和 rc4 key
#输出
flag1= [188, 197, 18, 125, 133, 35, 132, 113, 123, 57, 40, 2, 211, 81, 243, 44, 137, 43, 166, 44, 175, 9, 34, 34]
#include<stdio.h>
#include<string.h>
typedef unsigned longULONG;/*初始化函数*/
void rc4_init(unsigned char*s, unsigned char*key, unsigned long Len)
{int i = 0, j = 0;char k[256] = { 0 };unsigned char tmp = 0;for (i = 0; i < 256; i++){s[i] = i;k[i] = key[i%Len];}for (i = 0; i < 256; i++){j = (j + s[i] + k[i]) % 256;tmp = s[i];s[i] = s[j]; // 交换s[i]和s[j]s[j] = tmp;}
}/*加解密*/
void rc4_crypt(unsigned char*s, unsigned char*Data, unsigned long Len)
{int i = 0, j = 0, t = 0;unsigned long k = 0;unsigned char tmp;for (k = 0; k < Len; k++){i = (i + 1) % 256;j = (j + s[i]) % 256;tmp = s[i];s[i] = s[j]; // 交换s[x]和s[y]s[j] = tmp;t = (s[i] + s[j]) % 256;Data[k] ^= s[t];}
}int main()
{unsigned char s[256] = { 0 }, s2[256] = { 0 }; // S-boxchar key[256] = { "12345678abcdefghijklmnopqrspxyz" };char pData[] = {0xbc,0xc5,0x12,0x7d,0x85,0x23,0x84,0x71,0x7b,0x39,0x28,0x2,0xd3,0x51,0xf3,0x2c,0x89,0x2b,0xa6,0x2c,0xaf,0x9,0x22,0x22};unsigned long len = strlen(pData);int i;printf("pData=%s\n", pData);printf("key=%s,length=%d\n\n", key, strlen(key));rc4_init(s, (unsigned char*)key, strlen(key)); // 已经完成了初始化printf("\n\n");for (i = 0; i < 256; i++) // 用s2[i]暂时保留经过初始化的s[i],很重要的!!!{s2[i] = s[i];}//可以看到,加解密函数都是相同的printf("已经加密,现在解密:\n\n");rc4_crypt(s2, (unsigned char*)pData, len); // 解密printf("pData=%s\n\n", pData);return 0;
}

key= 12345678abcdefghijklmnopqrspxyz

flag{nice_to_meet_you}

6、总结

收获很大,深刻理解RC4,搞到了解RC4的两套方法

第一种:脚本解密

第二种:获得RC4后的数据,输入flag,进行动态调试,直接逆出flag

攻防世界:crypt(RC4)相关推荐

  1. 【攻防世界001】Guess-the-Number

    攻防世界之前刷了几十题了,没写wp,感觉很简单没啥意思.后来参加了几次比赛,发现有点干不动,决定还是老老实实刷题好了.这是第一篇wp,这题很简单,是个jar,用jd-gui可以得到java源码. 原来 ...

  2. 攻防世界(pwn)--Mary_Morton 利用格式化字符串+栈溢出破解Canary的保护机制

    ctf(pwn) canary保护机制讲解 与 破解方法介绍 程序执行流程 有三个选项,1是利用栈溢出,2是利用格式化字符串,3是退出;可连续输入多次; IDA分析 解题思路 程序存在canary保护 ...

  3. 攻防世界(Pwn) forgot---栈溢出;(方法二)

    攻防世界(Pwn) forgot-栈溢出:(方法一) 里面对问题描述的更详细一点 返回目标函数 0x80486CC 方法二(爆破流) 因为最终返回的是 v3[0]-v3[9] 之中的一个函数, v3[ ...

  4. 攻防世界(Pwn) forgot---栈溢出;(方法一)

    攻防世界(Pwn) forgot-栈溢出:(方法二) 介绍 这道题表面看起来有点复杂,其实很简单,有两种方法可以来做这一道题; 方法一(精确打击) 文件运行流程是: 1.先输入名字 2. 输入一串字符 ...

  5. 攻防世界misc新手_[攻防世界]mobile新手练习区easy-apk

    [攻防世界]mobile新手练习区easy-apk easy-apk最佳Writeup由129师386旅独立团 • devi1提供 难度系数: 7.0 题目来源: 暂无 题目描述:无 题目场景: 暂无 ...

  6. 攻防世界 ——crypto

    目录 新手区部分题解: 1,easy_RSA 2,Normal_RSA 3, 幂数加密 4,easy_ECC 高手进阶区部分题题解 5, ENC 6,告诉你个秘密 7,Easy-one 8,说我作弊需 ...

  7. 攻防世界———MISC 高手区题解

    目录 1,base64stego 2,easycap 3,Avatar 4,What-is-this 5,签到题 6,Training-Stegano-1 7,Excaliflag 8,Get-the ...

  8. 攻防世界 web(二)

    这周接着刷攻防世界的web题( ̄︶ ̄)↗ 1.command_execution 看提示这题为命令执行漏洞(command_execution),关于命令执行漏洞,我前面有篇博客详细介绍了,大家不了解 ...

  9. misc高阶 攻防世界_攻防世界 Misc 进阶题(一)

    攻防世界 Misc 进阶题(一) 关于隐写术的思路或方法 转载: https://blog.csdn.net/a_small_rabbit/article/details/79644078     隐 ...

  10. [攻防世界 pwn]——pwn1(内涵peak小知识)

    [攻防世界 pwn]--pwn1 题目地址:https://adworld.xctf.org.cn/ 题目: peak小知识 这道题目的关键就是泄露canary,通常我们泄露canary有两种方法,遇 ...

最新文章

  1. java程序错误类型及异常处理
  2. vue开发小程序Demo
  3. java线程三种创建方式与线程池的应用
  4. 快乐学习 Ionic Framework+PhoneGap 手册1-5 {IO开关}
  5. 交换机、路由器、PIX密码恢复
  6. MySQL添加唯一约束和联合唯一约束(建表后添加)
  7. redis 条件查询
  8. empty判断0会出的问题
  9. 乙酸乙酯密度是多少 乙酸乙酯的用途
  10. 【笔记】TNT: Target-driveN Trajectory Prediction
  11. pca人脸特征降维的过程理解及matlab编程实现
  12. 订单管理_04删除订单信息流程
  13. 思科模拟器配置 DHCP中继
  14. 如何卸载Oracle数据库
  15. QVector元素增删改
  16. 一张图理解EOS是什么
  17. 关系图d3、封装js
  18. UI行业就业前景怎样 如何成为合格的UI设计师
  19. 怎么给图片加上红圈,红框,红箭头标重点等?还有添加文字
  20. Spring中的@Transactional(rollbackFor = Exception.class) try catch 异常时候 会失效

热门文章

  1. 破解组态王在wince系统工业平板电脑中的安装应用
  2. 百万级深空天体数据库获取
  3. 苹果8参数配置_苹果12与苹果12Pro相比较有哪些区别?哪个更值得购买?
  4. 【数据结构面试常见问题】
  5. H5视频之video.js 视频直播前端
  6. Python学习(类的属性、继承、覆盖等详解)
  7. ARM_UART 串行通讯基础知识及编程
  8. 国二python考试时间_计算机二级考试时间3月几号 2019全国计算机等级考试
  9. 360和广点通广告SDK注意事项
  10. 关于无线上网卡的使用记录