首页
社区
课程
招聘
[原创]神秘系统分析
2014-3-16 23:29 11255

[原创]神秘系统分析

2014-3-16 23:29
11255
我想坛里的大神们很多参加了上周的BCTF,不知为何exploit全是liunx下的,当时看到只有玩泥巴le,希望有大神指导。玩不来liunx的只有认真的将神秘系统进行了一番分析。

附件里有解密后的idb分析记录,与分析报告。

sm.zip

(一)accesscode获取:

神秘的系统,打开发现1FEH 55AA 这是MBR(系统引导)首先分析这部分数据,主要功能就是将数据拷贝到0x8000处然后会利用输入的accesscode 去解密200H~A00H处。

解密算法根据输入的4个(0~9)循环依次解密


第一个肯定是一个call或者jmp,根据opcode可以推导

后面就是一个E8跳偏移,头执行哪个E8 *** BCTF,然后就可以推断出1337  

然后解密:
include "stdio.h"
#include <windows.h>
#define SIZE_CODE 0x800
int main()
{
 BOOL BRet = FALSE;
 DWORD dwsize = 0;
char buf[SIZE_CODE] = {0};
 HANDLE hFile = NULL;
 hFile = CreateFile("bctfos.3bbbcae1ea13b566477c99941a5eee63",GENERIC_WRITE|GENERIC_READ,
  FILE_SHARE_READ | FILE_SHARE_WRITE,
  NULL,
  OPEN_EXISTING,
  0,
  NULL
  );
 if (hFile == INVALID_HANDLE_VALUE)
 {
  MessageBox(NULL, NULL, "error", MB_OK);
  return -1;
 }
 SetFilePointer(hFile, 0x200, NULL, FILE_BEGIN);
 BRet = ReadFile(hFile, buf, 0x800, &dwsize, NULL);
 if (!BRet)
 {
  printf("sdas");
  return -1;
 }
 for (int i = 0; i*4 < 0x800; i++)
 {
  buf[i*4] = buf[i*4] ^ 0x31;
 }
 for (i = 0; 1+i*4 < 0x800; i++)
 {
  buf[1+i*4] = buf[i*4+1] ^ 0x33;
 }
 for (i = 0; 2+i*4 < 0x800; i++)
 {
  buf[2+i*4] = buf[2+i*4] ^0x33;
 }
 for (i = 0; 3+i*4 < 0x800; i++)
 {
  buf[3+i*4] = buf[3+i*4] ^ 0x37;
 }
 CloseHandle(hFile);
 hFile = CreateFile("1.txt", GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ,NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
 if (hFile == INVALID_HANDLE_VALUE)
 {
  MessageBox(NULL, "1.txt", "error", MB_OK);
  return -1;
 }
 SetFilePointer(hFile, NULL, NULL, FILE_BEGIN);
 BRet = WriteFile(hFile, buf, 0x800, &dwsize, NULL);
 if (!BRet)
 {
  return -1;
 }
 CloseHandle(hFile);
 return 0;
}


将得到的数据进行静态分析

(二)文件存储结构分析

配置boches 调试系统

用boches加载镜像,通过前面计算accesscode:1337输入,会得到一个命令行界面:


测试发现wr命令可执行,并可写入数据,,rd命令没有权限,


经过多次调试跟踪,在0x008a5c下断

结合IDA静态分析.....

首先是解析用户的数据


当按下回车(temp-8-5= 0)  会在偏移8A4处验证输入指令是否有效


跟进call sub_86c

之后会计算输入文件名size,并且size<16H


进入call sub_176发现怎么是调用int 13H完成处理屏幕及显示器,设置光标,应该是int 10H,后面跟踪发现调用int 10H完成写扇区,说明int 13h 与 int 10h功能进行了交换:


Int 10 与int 13的交换肯定是在启动系统输入accesscode之前就完成了,因为右面屏幕打印,光标定位都是通过int 13H中断完成的,于是在刚进入系统0a处下断,进入10地址函数



底层知识太差,这应该就是int 10 与 13做交换吧,,,,,紧接着对int 10H的调用


乍一看这不应该是int13H 调用模式么,

先看下es:bx  地址:0xD00


执行完int 10H后


这里完成了读操作,也就确定了上面的交换是将int 10与int 13的ISR做了交换

6A6处的函数等待输入,输入按键是esc  表示输入结束


接下来分析wr的整个过程

(1)调用0x68d处的函数生成一个随机的key序列(2个字节):


(2)读取用户输入的文件内容,同时用生成的key进行加密,加密算法为:

Messge[i] = Message[i] ^ key[i%2] ^ i



此次输入:1 2 3
计算后:b5 ed b5


(3)调用0x6d4处的函数生成一个文件,生成规则是:
1)随机生成一个磁头,磁道,扇区,扇区内偏移值


2)将文件名用0xcc异或加密


3)将以上信息,连同之前的生成的key和文件大小,保存在磁盘的1磁头,0磁道,1扇区处


使用x /20x 0xa000查看写入的文件头


上图中:int flag=01(表示占用),int filesize = 03 int key = de84 filename = bfb5af

经过分析可得知这是文件头存储的结构:
Int flag
Int filesize
Int key
Byte head
Byte cylinder
Byte sector_offset
Byte sector
Chat filename[22]


保存在磁盘的1磁头,0磁道,1扇区处(这里说明了,此系统存储文件时,将头部信息在1磁头,0磁道,1扇区);


(4)调用0x6f1处的函数将内容写入文件,写入的流程是:


1)定位到创建文件时随机生成的由磁头,磁道,扇区,扇区内偏移值组成的位置

将数据随机生成的磁头,磁道,扇区,扇区内偏移值组成的位置,写入es:bx(0xB000)


2)将26字节的文件内容保存在此处  (因为此次调试时输入文件为数据123只有三个)

将加密后的文件写入到 经sector_offset定位的地址+6偏移处


进入call sub_92


3)生成下一个随机的磁头,磁道,扇区,扇区内偏移并保存在此处


4)将下一段26字节的文件内容保存在步骤3)生成的位置,不断循环,直到所有内容都保存在磁盘上。

  5)将最后一个文件块的磁头,磁道,扇区,扇区内偏移的值均设置为0xff,表示文件结束。



由于测试时只输入   123

根据 加密算法: Message[i] = Message[i]^key[i%2]^i

密文:b5 ed b5



观察此时,在wr命令后在扇区上(0xa000起始地址)写入的信息


继续跟踪到偏移6d4处的call

功能:

1.定位到创建文件时随机生成的由磁头,磁道,扇区,扇区内偏移值组成的位置

2.将26字节的文件内容保存在此处

3生成下一个随机的磁头,磁道,扇区,扇区内偏移并保存在此处

4.将下一段26字节的文件内容保存在步骤3)生成的位置,不断循环,直到所有内容都保存在磁盘上。

5.将最后一个文件块的磁头,磁道,扇区,扇区内偏移的值均设置为0xff,表示文件结束。





保存加密的文本:


文件块的存储的结构为:

Int flag
Byte head
Byte cylinder
Byte sector_offset
Byte sector
Char message[26]


知道文件的创建和存储方式后,就可以还原系统中的文件了,还原步骤:

(1)        从1磁头0磁道1扇区找到文件头的信息。

也就要将CHS(柱面号,磁头号,扇区号)转化成LBA(线性地址)


计算公式如下:

    LBA = ( C – CS ) * PH * PS + ( H – HS ) * PS + ( S – SS )

可是不知道PS(没磁道有多少个扇区),PH(表示每柱面多少磁道)

想想系统在随机创建的磁头,柱面,扇区,扇区内偏移时,随机的值如果超过了最大值 写入磁盘的时候就会出错 所以我生成的随机值 必须保证其在一定的范围之内

在仔细去看看创建的磁头,柱面,扇区,扇区内偏移处的代码吧


上图push 4000001 相当于push 40h;push 0001h,进入call sub_1b2


还要注意扇区是从1开始计数的 磁头是从0开始计数的

上图可以明确 PS(扇区数)=3F

建立随机磁头时,push 20000h 同理可以明确 PH(最大磁头数)=02H

在计算随机扇内偏移时 push 100000H  所以将每个sector分割成10H个,者每个块大小为20H

C/H/S=0/1/1(1磁头0磁道1扇区) = 3F       3F*200 = 7E00


文件名异或0xcc后,发现文件名为key

(2)        得到加密的key=5252H,以及第一个文件块存储的磁头=1,磁道=1,扇区=3A,扇区内偏移=05,定位到第一块文件,取出文件内容

根据第一个文件块处所保存的下一块文件的磁头,磁道,扇区,扇区内偏移,找到

(3)        下一块文件,以此类推,直到下一块文件的磁头,磁道,扇区,扇区内偏移均为0xff


根据:[( C – CS ) * PH * PS + ( H – HS ) * PS + ( S – SS )] *200H +扇内偏移*20 = 1ECA0


上图可知  磁头=0,柱面=05,扇内偏移=06 扇区=11计算的下一存储地址:50CC0


上图可知  磁头=01,柱面=09,扇内偏移=07 扇区=27计算的下一存储地址:9A6E0


上图可知  磁头=0,柱面=0D,扇内偏移=08 扇区=3D计算的下一存储地址:D4500


上图可知  磁头=01,柱面=02,扇内偏移=09 扇区=14计算的下一存储地址:29D20


上图可知  磁头=01,柱面=09,扇内偏移=0b 扇区=30计算的下一存储地址:9B960


(4)        将文件内容拼接起来,用(2)中得到的key解密,即可得到flag:


#include "stdio.h"
#include <windows.h>
#define SIZE_CODE 256
int main()
{
	char buf[SIZE_CODE] = {0};
	DWORD dwsize = 0;
	HANDLE hFile = CreateFile("Decode_.txt", GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL,
		OPEN_EXISTING, 0, NULL);
	
	char key[] = "\x52\x52";
	if (hFile == INVALID_HANDLE_VALUE)
	{
		return -1;
	}
	BOOL bRet = ReadFile(hFile, buf, SIZE_CODE, &dwsize, NULL);
	for (int i = 0; i < dwsize; i++)
	{
		buf[i] = buf[i]^key[i%2]^i;
	}
	printf("buf:  %s\n", buf);
	CloseHandle(hFile);
	system("pause");
	return 0;
}



注:本帖由看雪论坛志愿者PEstone 重新将DOC整理排版,若和原文有出入,以原作者附件为准

[培训]内核驱动高级班,冲击BAT一流互联网大厂工 作,每周日13:00-18:00直播授课

上传的附件:
收藏
点赞1
打赏
分享
最新回复 (18)
雪    币: 341
活跃值: (85)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
JoySauce 1 2014-3-17 09:01
2
0
so difficult
雪    币: 30
活跃值: (56)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
逆转录酶 2 2014-3-17 10:48
3
0
居然看成神经系统分析......
雪    币: 35
活跃值: (139)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
JoyFei 2 2014-3-17 11:18
4
0
,,,,囧
雪    币: 2
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
suixinpiao 2014-3-17 11:22
5
0
不明觉厉。。
雪    币: 2879
活跃值: (1086)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
yjd 2014-3-17 12:40
6
0
linux 而不是liunx
雪    币: 496
活跃值: (281)
能力值: ( LV13,RANK:400 )
在线值:
发帖
回帖
粉丝
tishion 9 2014-3-17 12:49
7
0
把内容展开 贴出来,不要只发一个zip
雪    币: 341
活跃值: (85)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
JoySauce 1 2014-3-17 19:10
8
0
为什么呢,申哥
雪    币: 35
活跃值: (139)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
JoyFei 2 2014-3-17 19:23
9
0
申哥,图太多了。
雪    币: 202
活跃值: (114)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
vcnewer 2014-3-17 20:11
10
0
这都能发现
雪    币: 3295
活跃值: (1078)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
CRoot 2014-3-22 18:02
11
0
当时这个系统卡了半天 --- 得好好学习下--多谢!

不过求下 boches 教程 我看过那个从实模式到保护模式 李忠 的书 但是没看懂---怎么用的boches---
雪    币: 250
活跃值: (251)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
OnlyEnd 2014-3-23 16:12
12
0
我也觉得展开好些 嘿嘿
雪    币: 6253
活跃值: (2599)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
liter 2014-3-23 17:00
13
0
没听明白,大神啊。。。
雪    币: 266
活跃值: (204)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
lsmjj 2014-3-23 21:17
14
0
兄弟bochs吧
雪    币: 35
活跃值: (139)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
JoyFei 2 2014-3-24 10:50
15
0
google了一篇文章 http://www.cnblogs.com/chengxuyuancc/archive/2013/05/13/3076524.html
雪    币: 202
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
kxzb 2014-3-24 21:32
16
0
自己学着写os就能解决很多问题
雪    币: 3295
活跃值: (1078)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
CRoot 2014-3-28 22:51
17
0
多谢~ 挺好用的。
雪    币: 2354
活跃值: (2096)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
金白水清 2014-3-29 20:03
18
0
知识含量很高,收藏慢慢消化了,感谢楼主分享
雪    币: 36
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
修罗虎 2014-4-17 15:59
19
0
听不懂。。。看来还有待提高
游客
登录 | 注册 方可回帖
返回