首页
社区
课程
招聘
[原创]解密bitt新年礼物。
发表于: 2011-1-20 15:26 13869

[原创]解密bitt新年礼物。

2011-1-20 15:26
13869

先给传送门:http://bbs.pediy.com/showthread.php?t=128378
将图片重命名为.exe 双击就能玩了。

很久之前就遇到过一个zenix的图片cm  跟这个差不多  当初不会弄
现在又遇到了 当然还是不弄  但是我们知道 他肯定不是PE文件  那他到底是怎么执行起来的呢
用一个工具Process Explorer查看一下 发现这个cm是ntvdm.exe创建的一个conime.exe进程
ntvdm.exe是神马?百度百科有如下介绍:
 

  for (BYTE i_1=0x20; i_1<=0x7e; i_1++)
  {
    for (BYTE i_2=0x20; i_2<=0x7e; i_2++)
    {
      for (BYTE i_3=0x20; i_3<0x7e; i_3++)
      {
        for (BYTE i_4=0x20; i_4<0x7e;i_4++)
        {
          for (BYTE i_5=0x20; i_5<0x7e; i_5++)
          {
            for (BYTE i_6=0x20; i_6<0x7e; i_6++)
            {
              for (BYTE i_7=0x20; i_7<0x7e; i_7++)
              {
                if ((BYTE)(i_1^i_2) == (BYTE)0x33 && (BYTE)(i_2^i_3) == (BYTE)0x16 && (BYTE)(i_3^i_4) == 0x08 && (BYTE)(i_4^i_5) == 0x2c && (BYTE)(i_5^i_6) == 0x01 && (BYTE)(i_6^i_7) == 0x11)
                {

                  if (i_1+ i_2 + i_3 +i_4 +i_5+i_6+i_7 == 0x26d)
                  {
                    //成功鸟~~~
                  }

                }

              }
            }

          }
        }
      }

    }
  }

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 7
支持
分享
最新回复 (18)
雪    币: 179
活跃值: (26)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
2
穷举起来还挺快的,但是根据那个帖子楼主的说法,找不到合适的密码。
应该是 i_1+ i_2 + i_3 +i_4 +i_5+i_6+i_7 == 0x28d
另外楼主说了,密码是大小写字母组合。

这样的话就可以找到楼主说的那个不和谐的密码了。
BYTE mi[8]={0};

        for(int i0=0;i0<52;i0++)
        {
                if(i0<26)
                {
                        mi[0]=i0+0x41;
                }
                else
                {
                        mi[0]=i0+0x61-26;
                }
               
                for(int i1=0;i1<52;i1++)
                {
                        if(i1<26)
                        {
                                mi[1]=i1+0x41;
                        }
                        else
                        {
                                mi[1]=i1+0x61-26;
                        }
                        if((mi[0]^mi[1])!=0x33)
                        {
                                continue;
                        }
                        for(int i2=0;i2<52;i2++)
                        {
                                if(i2<26)
                                {
                                        mi[2]=i2+0x41;
                                }
                                else
                                {
                                        mi[2]=i2+0x61-26;
                                }
                                if((mi[1]^mi[2])!=0x16)
                                {
                                        continue;
                                }
                                for(int i3=0;i3<52;i3++)
                                {
                                        if(i3<26)
                                        {
                                                mi[3]=i3+0x41;
                                        }
                                        else
                                        {
                                                mi[3]=i3+0x6-26;
                                        }
                                        if((mi[2]^mi[3])!=0x8)
                                        {
                                                continue;
                                        }
                                        for(int i4=0;i4<52;i4++)
                                        {
                                                if(i4<26)
                                                {
                                                        mi[4]=i4+0x41;
                                                }
                                                else
                                                {
                                                        mi[4]=i4+0x61-26;
                                                }
                                                if((mi[3]^mi[4])!=0x2C)
                                                {
                                                        continue;
                                                }
                                                for(int i5=0;i5<52;i5++)
                                                {
                                                        if(i5<26)
                                                        {
                                                                mi[5]=i5+0x41;
                                                        }
                                                        else
                                                        {
                                                                mi[5]=i5+0x61-26;
                                                        }
                                                        if((mi[4]^mi[5])!=0x1)
                                                        {
                                                                continue;
                                                        }
                                                        for(int i6=0;i6<52;i6++)
                                                        {
                                                                if(i6<26)
                                                                {
                                                                        mi[6]=i6+0x41;
                                                                }
                                                                else
                                                                {
                                                                        mi[6]=i6+0x61-26;
                                                                }
                                                                if((mi[5]^mi[6])!=0x11)
                                                                {
                                                                        continue;
                                                                }

                                                                if((mi[0]+mi[1]+mi[2]+mi[3]+mi[4]+mi[5]+mi[6])==0x28D)
                                                                {
                                      SetDlgItemText(IDC_EDIT1,(char*)mi);
                                                                          return ;
                                                                }
                                                        }
                                                }
                                        }
                                }
                        }
                }
        }

        SetDlgItemText(IDC_EDIT1,"没有找到");

里面穷举出来的不和谐的密码只有一个。我怕跨省,还是不说了。
2011-1-20 15:47
0
雪    币: 458
活跃值: (421)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
3
补充:找到解密方法了
根据我们的条件
m1^m2=0x33  
m2^m3=0x16   =》 m1 ^ m3 = 0x33 ^0x16 = 0x25
m3^m4=0x8     =》 m1 ^ m4 = 0x25 ^ 0x08 = 0x2d
m4^m5=0x2C   =》 m1 ^ m5 = 0x2d ^ 0x2c = 0x01
m5^m6=0x1     =》 m1 ^ m6 = 0x01 ^ 0x01 = 0x00 =》m1 == m6
m6^m7=0x11   =》 m1 ^ m7 = 0x11

m1+m2+m3+m4+m5+m6+m7=0x26D

现在假设 m1 = x  列一个方程 穷举如下
        for (BYTE x = 0x00; x<0xff; x++)
        {
                DWORD dwxx = x + (0x33^x) + (0x25^x) + (0x2d ^ x) + (0x01 ^ x) + x + (x^0x11);
                if (dwxx == 0x26d)
                {
                        //搞定
                }
        }

调试一下就知道   答案是什么了  
关于答案   我很认同  
记得有一天  我下载一份什么源码  我找到官方网站竟然打不开  我真伤了  我们亲爱的祖国。
2011-1-20 16:00
0
雪    币: 458
活跃值: (421)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
4
[QUOTE=SJQIANG;917614]穷举起来还挺快的,但是根据那个帖子楼主的说法,找不到合适的密码。
应该是 i_1+ i_2 + i_3 +i_4 +i_5+i_6+i_7 == 0x28d
另外楼主说了,密码是大小写字母组合。

这样的话就可以找到楼主说的那个不和谐的密码了。
BYTE mi[8]={0};

        fo...[/QUOTE]

这样穷举只是无奈之举   最好的穷举是  数学分析一下  最多255次就完成鸟~~。。。
2011-1-20 16:06
0
雪    币: 179
活跃值: (26)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
5
数学不好,只能暴力了
2011-1-20 16:07
0
雪    币: 181
活跃值: (27)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
我只想知道礼品是什么~
2011-1-20 17:40
0
雪    币: 111
活跃值: (35)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
厉害,看到了
2011-1-20 18:36
0
雪    币: 435
活跃值: (1282)
能力值: ( LV13,RANK:388 )
在线值:
发帖
回帖
粉丝
8
呵呵这么快
我说错了,ida只能反汇编,不能动态调试
但是因为算法很简单
所以可以用ida反汇编,然后静态分析一下
debug的反汇编结果是有问题的
2011-1-21 08:37
0
雪    币: 435
活跃值: (1282)
能力值: ( LV13,RANK:388 )
在线值:
发帖
回帖
粉丝
9
org 81C9h
;平衡栈
	pusha
;切换显示模式
	mov ax,0x13
	int 10h
	mov ax,cs
	mov es,ax
	mov ds,ax
;显示欢迎信息
	mov ax,900h
	mov dx,hello
	int 21h
	xor ax,ax
	int 16h
	mov ax,13h
	int 10h
	mov ax,900h
	mov dx,pwd
	int 21h
;输入password
	mov ah,0x0a
	mov dx,hello
	int 21h
;判断字符串长度
	mov bx,hello
	inc bx
	mov al,[bx]
	cmp al,7
	jnz exit
;判断字符串内容
	inc bx
	mov al,[bx]
	inc bx
	mov cl,[bx]
	xor al,cl
	cmp al,0x33
	jnz exit
	mov al,[bx]
	inc bx
	mov cl,[bx]
	xor al,cl
	cmp al,0x16
	jnz exit
	mov al,[bx]
	inc bx
	mov cl,[bx]
	xor al,cl
	cmp al,0x08
	jnz exit
	mov al,[bx]
	inc bx
	mov cl,[bx]
	xor al,cl
	cmp al,0x2c
	jnz exit
	mov al,[bx]
	inc bx
	mov cl,[bx]
	xor al,cl
	cmp al,1
	jnz exit
	mov al,[bx]
	inc bx
	mov cl,[bx]
	xor al,cl
	cmp al,0x11
	jnz exit
;校验字符串各字节和
	xor ax,ax
	xor cx,cx
	mov al,[bx]
	add cx,ax
	dec bx
	mov al,[bx]
	add cx,ax
	dec bx
	mov al,[bx]
	add cx,ax
	dec bx
	mov al,[bx]
	add cx,ax
	dec bx
	mov al,[bx]
	add cx,ax
	dec bx
	mov al,[bx]
	add cx,ax
	dec bx
	mov al,[bx]
	add cx,ax
	cmp cx,0x26d
	jnz exit
;password正确信息
	mov ax,0x13
	int 10h
	mov ax,900h
	mov dx,correct
	int 21h
	xor ax,ax
	int 16h
;用password第一个字节来解密代码
	mov bx,hello
	add bx,2
	mov al,[bx]
	mov bx,letsgo
	xor cx,cx
repxor:
	mov dl,[bx]
	xor dl,al
	mov [bx],dl
	inc cx
	inc bx
	cmp cx,0x1014
	jnz repxor
	jmp letsgo
;password错误并退出
exit:
	mov ax,0x13
	int 10h
	mov ax,900h
	mov dx,incorrect
	int 21h
	xor ax,ax
	int 16h
	int 20h
hello: db 0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0d,"      Hello,wellcom to asm world!","$"
pwd: db 0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0d,"       Enter Password:","$"
incorrect: db 0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0d,"          Incorrect Password!","$"
correct: db 0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0d,"     Correct Password,Let's go!","$"
;将3ddemo copy到100h,相当于一个小的loader
letsgo:
	mov ax,cs
	mov ds,ax
	mov es,ax
	mov si,offset    ;源偏移量
	mov di,0x100     ;目标位置 段地址ds 偏移地址
	mov ch,0x10      ;cx字节数 
	rep movsw
	push 100h
	retn
offset: db 0

这个就是源码了,其实ida反汇编出来的貌似比这个还清晰一点,还带中断说明的。。。
不停的int 10h是因为不知道怎么清屏,询问了一下,得知最简单的方法就是重设属性
其实我是第一次写16位程序,基本上是看着中断说明来的,所以程序没敢太复杂
2011-1-21 08:47
0
雪    币: 458
活跃值: (421)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
10
debug 不完善  pusha  和 一些条件跳转都没反汇编出来  但是调试 很给力。
通过调试 就能知道  他是跳转指令了。。。
2011-1-21 09:18
0
雪    币: 435
活跃值: (1282)
能力值: ( LV13,RANK:388 )
在线值:
发帖
回帖
粉丝
11
后面的3ddemo看到没 给力吧
2011-1-21 09:29
0
雪    币: 458
活跃值: (421)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
12
给力啊    好像是某一年什么编程大赛的冠军作品    你给异或加密了一下。  然后就跑起来了
2011-1-21 10:41
0
雪    币: 2687
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
经常访问不了Google是不是也和这个GFW有关?
2011-1-21 13:55
0
雪    币: 435
活跃值: (1282)
能力值: ( LV13,RANK:388 )
在线值:
发帖
回帖
粉丝
14
yes
搜索和谐词之后,会封锁ip大概3分钟,在此期间不能使用google提供的任何服务
另外,google的很多服务,比如YouTube、docs、wave、在线相册等是永久封闭的
2011-1-21 14:03
0
雪    币: 435
活跃值: (1282)
能力值: ( LV13,RANK:388 )
在线值:
发帖
回帖
粉丝
15
其实穷举的话没必要做255次计算
52次计算足够
只需穷举密码第一位,因为只能大小写字母所以只有52个可能
枚举出第一位之后 通过逐字节xor可以推出一个密码 xor是可逆的嘛
然后校验这个密码字节和是不是0x26d就行了
如果是就没问题了
BYTE pwd[8];
for(i='A';i<='z';i++)
{
 pwd[0]=i;
 pwd[1]=pwd[0]^0x33;
 pwd[2]=pwd[1]^0x16;
 pwd[3]=pwd[2]^8;
 pwd[4]=pwd[3]^0x2c;
 pwd[5]=pwd[4]^1;
 pwd[6]=pwd[5]^0x11;
 if(pwd[0]+pwd[1]+pwd[2]+pwd[3]+pwd[4]+pwd[5]+pwd[6]==0x26d)
 break;
}
2011-1-21 14:28
0
雪    币: 458
活跃值: (421)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
16
[QUOTE=bitt;917938]其实穷举的话没必要做255次计算
52次计算足够
只需穷举密码第一位,因为只能大小写字母所以只有52个可能
枚举出第一位之后 通过逐字节xor可以推出一个密码 xor是可逆的嘛
然后校验这个密码字节和是不是0x26d就行了
如果是就没问题了
BYTE pwd[8];
for(i='A...[/QUOTE]


我当时  认为答案可能是汉字。。。。如果是汉字一般来说最好255次穷举了。
2011-1-22 10:23
0
雪    币: 370
活跃值: (15)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
17
搜索和谐词 lock ip三分钟
哇塞 这不就是变相警告吗
2011-1-22 18:24
0
雪    币: 90
活跃值: (91)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
潜力贴留名.Opera插图补丁.字数补丁..
2011-1-23 11:58
0
雪    币: 95
活跃值: (15)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
19
学习了,谢谢lz
2011-2-4 15:04
0
游客
登录 | 注册 方可回帖
返回
//