rem*_*inn 11 c printf overflow fortify-source
{
char buf[8];
sprintf(buf,"AAAA%3s","XXXXXXXX");
printf("%s\n",buf);
}
Run Code Online (Sandbox Code Playgroud)
会发生什么?
缓冲区有8个字符空间,只剩下3个空闲字符,但"XXXXXXXX"长度为8个字符.
我在Windows 7上使用Visual Studion 2008进行测试.结果,程序打印出来:AAAXXXXXXX,发生了运行时错误.
den*_*ane 12
考虑一下你的,更重要的是,类似的案例会发生什么事情是很有意义的.正如其他海报所指出的那样,它会调用UB.这可能是真的.然而,世界并不仅仅因为有人没有明确接下来应该发生什么而停止.而接下来的实际情况可能是一个主要的安全漏洞.
如果您的字符串XXX...
来自不受控制的源,则非常接近于生成缓冲区溢出漏洞.
(1)您的堆栈通常向后"增长",即地址越小,堆栈填充的越多.
(2)字符串期望存储属于该字符串的字符,以便在字符n 之后存储字符n + 1 .
(3)当你调用一个函数时,返回地址,即函数返回后要执行的指令的地址,被推送到堆栈(通常是其中之一).
现在考虑函数的堆栈帧.
|----------------|
| buf [size 8] |
|----------------|
| (func args) |
|----------------|
| (other stuff) |
|----------------|
| return address |
|----------------|
Run Code Online (Sandbox Code Playgroud)
通过找出buf
堆栈与返回地址之间的确切偏移是什么,恶意用户可以操作输入到您的应用程序,其方式是该XXX...
字符串包含攻击者在不受控制的sprintf
函数将覆盖的位置选择的地址堆栈上的返回地址.(注意:snprintf
如果您可以使用,请更好地使用).从而攻击者发起了缓冲区溢出攻击.他可能会使用类似NOP雪橇技术的东西让你的应用程序为他启动一个shell.如果您编写的是在特权用户帐户下运行的应用程序,那么您只需向攻击者提供一个入门级别的系统,即ACE 洞,如果你愿意的话.
您遇到的运行时错误可能是由于覆盖了返回地址.由于你基本上填充了gargabe,CPU跳转到的地址可能包含字节序列,解释为程序文本,导致无效的内存访问(或者地址本身已经坏了).
应该注意的是,一些编译器可以帮助解决这些类型的错误.例如,海湾合作委员会有-fstack-protector
.我不熟悉这些功能有多好.
您的格式字符串中有错误/拼写错误.而不"AAAA%3s"
应该是"AAAA%.3s"
.场[最小]宽度和场精度非常不同.前者设置字段将扩展填充的最小字节数.后者(对于字符串)设置将输出的最大字节数; 字符串的其他字节既不会被检查也不会被复制到输出中.