****实验Lab3
赞赏码 & 联系方式 & 个人闲话
****前言
Lab3
1、阅读:https://blog.csdn.net/cnhk1225/article/details/53568996然后回答问题:What does this code do?
代码注释:
MSIL代码的注释如下(Java代码大同小异,功能也相同,此处就不加以注释):
Optimizing csc .NET compiler from MSVS 2015 (/o switch), ildasm output:
.method public hidebysig static bool f(char a) cil managed
{
// Code size 26 (0x1a) //代码大小 26 (0x1a)
.maxstack 8 //计算堆栈能存8个值
IL_0000: ldarg.0 //将this指针压入栈
IL_0001: ldc.i4.s 97 //97放到计算堆栈上
IL_0003: blt.s IL_000c //如果第一个值小于第二个值则将控制转移到目标指令
IL_0005: ldarg.0 //将this指针压入栈
IL_0006: ldc.i4.s 122 //122放到计算堆栈上
IL_0008: bgt.s IL_000c //如果第一个值大于第二个值则将控制转移到目标指令
IL_000a: ldc.i4.1 //把1放到计算堆栈上
IL_000b: ret //return 1
IL_000c: ldarg.0 //将this指针压入栈
IL_000d: ldc.i4.s 65 //65放到计算堆栈上
IL_000f: blt.s IL_0018 //如果第一个值小于第二个值则将控制转移到目标指令
IL_0011: ldarg.0 //将this指针压入栈
IL_0012: ldc.i4.s 90 //90放到计算堆栈上
IL_0014: bgt.s IL_0018 //如果第一个值大于第二个值则将控制转移到目标指令
IL_0016: ldc.i4.1 //把1放到计算堆栈上
IL_0017: ret //return 1
IL_0018: ldc.i4.0 //把0放到计算堆栈上
IL_0019: ret //return 0
} // end of method some_class::f
小结与讨论:
代码段的含义是:判断一个字符是否为字母。如果是字母(大小写形式不论)则返回1;其他字符则返回0。
2、2017bath这张图片有一些文字片段可能简单加密了,是某人说的,此人的姓名是什么?
(hint:hex editor)
Step1:通过十六进制编辑器打开2017bath.jpg
可以找到Rail-Fence的字符串,表明可能使用了栅栏密码进行加密。
Step2:将jpg后缀改为zip,解压缩后得到txt文本
文本内容如下:
CrudreasrsheheanaulhfouCmhlaopiaeifltouermrtdpiyeCntpmafhnpbgmbaoagspeuteuwtecwokpetwutileolctnreoicottievhetepriogoseIretodaiithgottfeorhersnueualtebtfamtnseetehrnieipooilrshashyhsrmttmanariaictntgutdeeonmotaudeowuselctnfeoghrtsbaCrgarhtbprthcirarQktodbeatees
Step3:**栅栏密码
加密方式是栅栏密码,栅栏数是不确定的,所以进行暴力**。
代码如下:
#include<stdio.h>
#include<string>
int main() {
char cipher[] = "CrudreasrsheheanaulhfouCmhlaopiaeifltouermrtdpiyeCntpmafhnpbgmbaoagspeuteuwtecwokpetwutileolctnreoicottievhetepriogoseIretodaiithgottfeorhersnueualtebtfamtnseetehrnieipooilrshashyhsrmttmanariaictntgutdeeonmotaudeowuselctnfeoghrtsbaCrgarhtbprthcirarQktodbeatees";
int len = strlen(cipher);
int i;
char temp[50][50];
int j, k;
int row, line;
int part;
int num;
for (i = 2; i < 11; i++) {
printf("每组字数%d\n", i);
row = i;
line = ceil(len / double(i));
part = len % i;
num = 0;
for (j = 0; j < part; j++) {
for (k = 0; k < line; k++) {
temp[j][k] = cipher[num];
num++;
}
}
for (; j < row; j++) {
for (k=0; k < line-1; k++) {
if (num > len)
break;
temp[j][k] = cipher[num];
num++;
}
}
num = 0;
for (k = 0; k < line; k++) {
for (j = 0; j < row; j++) {
if (num > len)
break;
printf("%c", temp[j][k]);
num++;
}
}
printf("\n\n");
}
}
运行结果如下:
当每字符数为9时,解密的结果最符合逻辑。所以明文为:CppisahorriblelanguageItsmademorehorriblebythefactthatalotofsubstandardprogrammersuseittothepointwhereitsmuchmucheasiertogeneratetotalanduttercrapwithitQuitefranklyevenifthechoiceofCweretodonothingbutkeeptheCppprogrammersoutthatinitselfwouldbeahugereasontouseC
Step4:确定问题答案
断一波句:
Cpp is a horrible language Its made more horrible by the fact that a lot of substandard programmers use it to the point where its much much easier to generate total and utter crap with it Quite frankly even if the choice of C were to do nothing but keep the Cpp programmers out that in itself would be a huge reason to use C
这是Linux之父Linus Torvalds说的,故问题的答案为:Linus Torvalds。
3、运行CrackMe1.exe,提示 "嗯,对了" 代表成功。首先修改exe使得出现成功提示,其次不修改exe输入正确的密码达到成功的目的。(hint:https://blog.csdn.net/Nagi_Way/article/details/68961121)
Ⅰ:修改exe使得出现成功提示
Step1:分析***** Me按钮源代码
思路:分析代码可知,只要把==改为!=就ok了~
Step2:通过IDA查看CrackMe1.exe文件
找到了判断语句,就是这个brtrue.s。查阅资料可知,brtrue.S表示如果value为true、非空或非零,则将控制转移到目标指令(短格式)。而brfalse.S则恰恰相反,如果value为 false、空引用或零,则将控制转移到目标指令。所以,我们只要把此处改为brfalse.s就可以了。
Step3:通过十六进制编辑器修改
通过ida找出两条判断语句的十六进制表示分别是2D 0F、2C 0B。因为0F、0B实际上是跳转地址,所以只需将2D改为2C(即将brtrue.S改为brfalse.s)。
Step4:验证修改结果
随便输如一个字符串,就可以看到成功的显示:
Ⅱ:输入正确的密码出现成功提示
Step1:分析***** Me按钮源代码
用.NET Reflector软件解析CrackMe1.exe,在button1_Click函数中里能看到:
打开Encode加密函数,可以发现是3DES加密:
Step2:3DES在线解密
我们找到一个在线解密3DES网站(http://tool.chacuo.net/crypt3des)可以进行解密。加密模式选择CBC,填充选择pkcs5padding, **为wctf{wol,偏移量为dy_*****},输出使用base64加密。
确定算法参数后,便可成功解密。这里的参数选择其实也是枚举试出来的。
Step3:验证解密结果
在CrackMe1.exe中输入wctf{dotnet_crackme1},即可出现成功提示:
4、(选做)修改CrackMe1.exe使得:只有输入你的学号才能出现成功提示。并且把“大家好...net”这段话全部换成自己自定义的英文。
Step1:修改CrackMe1.exe验证密码出现成功提示
通过十六进制编辑器将密码判断处的字符串修改为E41614018,3DES加密结果为“Kisgmrp27z0I0OANbRfC2A==”。
验证修改后的密码E41614018:
Step2:修改字符串为自定义
字符串“大家好!我是”修改为“AAAAAA”:
字符串“@无所不能的魂大人”修改为“BBBBBBBBB”:
微博链接“http://weibo.com/woldy”修改为学校官网链接“http://www.ahu.edu.cn”:
字符串“编点练习题太TMD难了。。欢迎投稿哦!投稿地址aaa@qq.com”修改为“E41614018 E41614003 E41614007 Hello,World”:
Step3:查看修改后的最终效果
点击BBBBBBBBB处的链接,打开学校官网网页:
5、运行login.exe,提示 "You Get It!" 代表成功。
Step1:分析login.exe验证登陆密码的源码
用.NET Reflector这个软件解析login.exe,找出与出现成功提示相关的源码:
分析代码可以知道:当输入的字符长度为9,所有字符的ASCII码算术运算加后是0x1d8,逻辑运算与后是0x42的时候,系统就会输出"You Get It!"。
Step2:确定login.exe的登陆密码
满足条件的字符串有很多,老师的提示是上一届同学的学号,那么就可以确定“E415140”这7位,所以只要暴力**后两位即可。
代码如下:
#include<stdio.h>
#include<string>
int main()
{
char c[] = "0123456789Ee";
int len = strlen(c);
char a[9];
int i1, i2, i3, i4, i5, i6, i7, i8, i9;
int num = 0, num2 = 0;
int j;
int flag = 0;
for (i1 = 0; i1 < 1; i1++)
{
//if (flag == 1)
//break;
//a[0] = c[i1];
a[0] = 'E';
for (i2 = 0; i2 < 1; i2++)
{
//if (flag == 1)
//break;
//a[1] = c[i2];
a[1] = '4';
for (i3 = 0; i3 < 1; i3++)
{
//if (flag == 1)
//break;
//a[2] = c[i3];
a[2] = '1';
for (i4 = 0; i4 < 1; i4++)
{
//if (flag == 1)
//break;
//a[3] = c[i4];
a[3] = '5';
for (i5 = 0; i5 < 1; i5++)
{
//if (flag == 1)
//break;
//a[4] = c[i5];
a[4] = '1';
for (i6 = 0; i6 < 1; i6++)
{
//if (flag == 1)
//break;
//a[5] = c[i6];
a[5] = '4';
for (i7 = 0; i7 < 1; i7++)
{
//if (flag == 1)
//break;
//a[6] = c[i7];
a[6] = '0';
for (i8 = 0; i8 < len; i8++)
{
//if (flag == 1)
//break;
a[7] = c[i8];
for (i9 = 0; i9 < len; i9++)
{
//if (flag == 1)
//break;
a[8] = c[i9];
for (j = 0; j < 9; j++)
{
num = num + (int)a[j];
num2 ^= (int)a[j];
}
if (num == 472 && num2 == 66)
{
for (j = 0; j < 9; j++)
printf("%c", a[j]);
flag = 1;
printf("\n");
}
num = 0;
num2 = 0;
}
}
}
}
}
}
}
}
}
}
运行结果如下:
Step3:验证login.exe的登陆密码
将这两个学号任意一个输入到login.exe,即可成功:
Step4:确定程序员信息
百度这两个学号,毫无疑问这两个人的个人信息已经被泄露了,很容易即可找到:
殷东硕、邵雨琪就是我们想找的设计这个程序的两个人。
ps:
这道题是15级两位学长学姐出的,原因记得好像是保研后闲着没事干。。。不清楚睿敏和飞哥有没有继承这个传统啊 : )
上一篇: ****实验Lab0
下一篇: 今日头条爬虫实战----爬取图片
推荐阅读