1 保护操作系统(5)(harib19a)
大家早上好。
在昨天的最后我们成功干掉了crack2.hrb,今天我们要尝试一下更厉害的攻击手段。所以说,从现在开始又要打开坏人模式了哟,嘿嘿嘿。
■■■■■
虽然把操作系统的段地址存入DS这一招现在已经不能用了,不过我可不会善罢甘休的。我要想个更厉害的招数,把使用“纸娃娃系统”的人推进恐怖的深渊,哈哈哈哈!
在操作系统管理的内存空间里搞破坏是行不通了,这次算你厉害,不过我还可以在定时器上动动手脚。这样一来,光标闪烁就会变得异常缓慢,任务切换的速度也会变慢,一定很不爽吧。嗯,光想想就觉得很有趣啊,嘿嘿嘿。
本次的crack3.nas
[INSTRSET "i486p"]
[BITS 32]
MOV AL,0x34
OUT 0x43,AL
MOV AL,0xff
OUT 0x40,AL
MOV AL,0xff
OUT 0x40,AL
; 上述代码的功能与下面代码相当
; io_out8(PIT_CTRL, 0x34);
; io_out8(PIT_CNT0, 0xff);
; io_out8(PIT_CNT0, 0xff);
MOV EDX,4
INT 0x40
好,完成了!赶紧“make run”,然后输入“crack3”,口中念念有词道:“可恶的‘纸娃娃系统’,吃我这招!”然后按下回车键。
可是失败了……
哎呀,有两下子嘛!可恶!
当以应用程序模式运行时,执行IN指令和OUT指令都会产生一般保护异常。当然,通过修改CPU设置,可以允许应用程序使用IN指令和OUT指令,不过这样大家会担心留下bug而遭到恶意攻击。
■■■■■
我还没输呢,这点挫折我可不会善罢甘休!既然如此,我就给你执行CLI然后再HLT,这样一来电脑就死机了。由于不再产生定时器中断,任务切换也会停止,键盘和鼠标中断也停止响应,除了按下机箱上的Reset按钮以外没有别的办法了。我真是个天才,哈哈哈哈!
本次的crack4.nas
[INSTRSET "i486p"]
[BITS 32]
CLI
fin:
HLT
JMP fin
这次一定要成功,“make run”!
又失败了……
又产生了异常,为什么啊!
当以应用程序模式运行时,执行CLI、STI和HLT这些指令都会产生异常。因为中断应该是由操作系统来管理的,应用程序不可以随便进行控制。不能执行HLT的话,应用程序就没办法省电了,不过一般情况下,这应该通过调用任务休眠API来实现,而不能由应用程序自己来执行HLT。此外,在多任务下,调用休眠API还可以让系统将CPU时间分配给其他任务。
连CLI也不让我执行吗?怎么会有这种事!这样的话不就干不成坏事了吗?难道只能缴械投降了?
哦哦,想起来了!操作系统里面不是有一个用来CLI的函数嘛,far-CALL这个函数不就行了吗?这样一来“纸娃娃系统”应该就会死机了。应该CALL哪个地址呢?只要有map文件就可以轻松找到了。
嗯嗯,map文件中有这样一行:
- 0x00000AC1 : _io_cli
我就来far-CALL这个地址吧,哈哈!
本次的crack5.nas
[INSTRSET "i486p"]
[BITS 32]
CALL 2*8:0xac1
MOV EDX,4
INT 0x40
嘿嘿,准备接招吧,“make run”!
还是失败了……
又产生异常了!到底为啥呀!能不能让我赢一次啊!可恶!
如果应用程序可以CALL任意地址的话,像这样的恶作剧就可以成功了,因此CPU规定除了设置好的地址以外,禁止应用程序CALL其他的地址。因此,“纸娃娃系统”中应用程序要调用操作系统只能采用INT 0x40的方法。
■■■■■
于是坏人只好失望地洗洗睡了(笑)。3天后……
有了!这次应该能行,我怎么早没想到这个办法呢?哈哈,这次绝对可以成功!
既然应用程序只能调用API,那么把API修改一下不就行了吗?
本次的console.c节选
int *hrb_api(int edi, int esi, int ebp, int esp, int ebx, int edx, int ecx, int eax)
{
int cs_base = *((int *) 0xfe8);
struct TASK *task = task_now();
struct CONSOLE *cons = (struct CONSOLE *) *((int *) 0x0fec);
if (edx == 1) {
cons_putchar(cons, eax & 0xff, 1);
} else if (edx == 2) {
cons_putstr0(cons, (char *) ebx + cs_base);
} else if (edx == 3) {
cons_putstr1(cons, (char *) ebx + cs_base, ecx);
} else if (edx == 4) {
return &(task->tss.esp0);
} else if (edx == 123456789) { /*这里!*/
*((char *) 0x00102600) = 0; /*这里!*/
}
return 0;
}
嘿嘿嘿,改好了,然后只要写这样一个应用程序就行了。
本次的crack6.nas
[INSTRSET "i486p"]
[BITS 32]
MOV EDX,123456789
INT 0x40
MOV EDX,4
INT 0x40
好啦!准备接招吧,“make run”!
没有异常……
没有产生异常!不过到底成功了没有呢?dir一下看看……成功了,消失了耶!这次我赢了,哈哈!
如果操作系统内部存在这种蠢到作茧自缚的API,那么再优秀的CPU也对此无能为力,操作系统只能束手就擒。即使操作系统原本没有这样的API,如果像这次一样被篡改的话,也有可能被植入后门。
要防止这种问题的发生,我们只能 “不安装不可靠的操作系统”了。如果大家都能遵守这条原则,就不会因为随意下载应用程序而弄坏电脑了——当然,如果操作系统本身就破绽百出的话就另当别论了。
这次的crack6.hrb其实只能在使用 “改版纸娃娃系统”的人身上发挥效果。如果对方不安装“改版纸娃娃系统”的话,即便运行了这个应用程序也不会发生任何问题。因此,就目前而言,这个应用程序的受害者就只有这个坏人自己而已,从这个角度来说,他“赢”得还真是空虚啊。
■■■■■
现在坏人已经走了,接下来我们继续做系统吧。