问题描述
{
char buf[8];
sprintf(buf,"AAAA%3s","XXXXXXXX");
printf("%s\n",buf);
}
会发生什么?
缓冲区有8个字符的空间,只剩下3个空闲字符,但是,"XXXXXXXX"的长度为8个字符.
The buffer have 8 characters space and only 3 free characters left, however, "XXXXXXXX" is 8 characters long.
我在Windows 7上使用Visual Studion 2008进行了测试,结果程序打印为:AAAXXXXXXX,并且发生了运行时错误.
I take a test with Visual Studion 2008 on Windows 7. As a result, the program printed:AAAXXXXXXX, and a run-time error happened.
推荐答案
考虑案例中发生的情况(更重要的是,类似情况)非常有意义.正如其他张贴者所指出的,它调用UB.可能是真的.但是,世界并不是仅仅因为有人没有定义接下来应该发生什么而停止.接下来发生的物理可能是主要安全漏洞.
It makes a lot of sense to consider what happens in your and, more importantly, similar, cases. As other posters have noted, it invokes UB. That's probably true. However, the world does not stop simply because someone did not define what exactly should happen next. And what physically happens next, may well be a major security hole.
如果您的字符串XXX...
来自不受控制的来源,那么您将非常接近产生缓冲区溢出漏洞.
If your string XXX...
comes from uncontrolled sources, you are very close to generating a buffer overflow vulnerability.
(1)您的堆栈通常向后增长",即地址越小,堆栈填充越多.
(1) Your stack typically "grows" backwards, i.e. the smaller the addresses, the more the stack is filled.
(2)字符串期望存储属于该字符串的字符,以便将字符n + 1存储在 字符n之后.
(2) Strings expect the characters belonging to that string to be stored so that character n+1 is stored after character n.
(3)调用函数时,返回地址(即函数返回后要执行的指令的地址)被压入堆栈(通常是其他操作).
(3) When you call a function, the return address, i.e. the address of the instruction that is to be executed after the function returns, is pushed to the stack (among other things, typically).
现在考虑函数的堆栈框架.
Now consider a stack frame of your function.
|----------------|
| buf [size 8] |
|----------------|
| (func args) |
|----------------|
| (other stuff) |
|----------------|
| return address |
|----------------|
通过找出buf
与堆栈上的返回地址之间的确切偏移量,恶意用户可能以XXX...
字符串包含攻击者选择的地址的方式操纵对应用程序的输入不受控制的sprintf
函数将覆盖堆栈上的返回地址的位置. (注意:如果您可以使用snprintf
,请更好地使用它).因此,攻击者发起了缓冲区溢出攻击.他可能会使用 NOP雪橇技术之类的方法来使您的应用程序启动外壳.如果您正在编写以特权用户帐户运行的应用程序,那么您只需向攻击者提供客户系统的第一级条目,即 ACE 孔,如果可以的话.
By finding out what exactly the offset between buf
and the return address on the stack is, a malicious user may manipulate input to your application in a way that the XXX...
string contains an address of the attacker's choosing at just the point where the uncontrolled sprintf
function will overwrite the return address on the stack. (NB: Better use snprintf
if it's available to you). Thereby the attacker mounted a buffer overflow attack. He might use something like the NOP sled technique to have your application start a shell for him. If you were writing an application that ran under a privileged user account, you'd just have provided an attacker with a first-grade entry to your costumer's system, an ACE hole, if you will.
您遇到的运行时错误很可能是由于返回地址被覆盖.由于基本上是用gargabe填充的,因此CPU跳转到的地址可能确实包含字节序列,这些字节序列被解释为程序文本,从而导致无效的内存访问(或者该地址本身已经坏了).
The run-time error you experience may well be due to an overwritten return address. Since you filled it with, basically, gargabe, the address the CPU jumped to did probably contain byte sequences that, interpreted as program text, cause an invalid memory access (or the address itself was already bad).
应注意,某些编译器可以帮助解决此类错误.例如,GCC具有-fstack-protector
.我不熟悉这些功能的优势.
It should be noted that some compilers can help against these kinds of errors. GCC, for example, has the -fstack-protector
. I'm not familiar with how good those features are.
这篇关于sprintf函数的缓冲区溢出?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!