我最近在C完成了大学课程.所以我当然缺乏经验.
一些大学倾向于教他们的学生安全编程,或至少一些元素.还有,即使视频(摘自这里).
在C中,复制字符串,据我所知 - strcpy或string.h函数.如何在日常编程中安全地使用它?你有一些函数,它们处理分配以防止缓冲区溢出?有C的CERT安全编码标准.它提供示例和合规解决方案:
int main(int argc, char *argv[]) {
/* ... */
char prog_name[128];
strcpy(prog_name, argv[0]);
/* ... */
}
Run Code Online (Sandbox Code Playgroud)
他们的替代方案是:
int main(int argc, char *argv[]) {
/* ... */
char *prog_name = (char *)malloc(strlen(argv[0])+1);
if (prog_name != NULL) {
strcpy(prog_name, argv[0]);
}
else {
/* Couldn't get the memory - recover */
}
/* ... */
}
Run Code Online (Sandbox Code Playgroud)
从这里开始,第二个例子.
但据我所知,这更具挑战性,更多代码,更多工作.为什么没有人改变图书馆本身?或者至少为什么没有人提供安全的替代库或功能,以正确的方式处理这个?
感谢阅读,愿
我们正在计划让我们的应用程序识别Unicode,我们正在分析我们将遇到的问题.
特别是,我们的应用程序将严重依赖于字符串的长度,我们希望将其wchar_t用作基本字符类.
当处理必须以UTF-16中的2个16位单位存储的字符时出现问题,即U + 10000以上的字符.
简单的例子:
我有UTF-8字符串"蟂"(Unicode字符U + 87C2,UTF-8:E8 9F 82)
所以,我设置以下代码:
const unsigned char my_utf8_string[] = { 0xe8, 0x9f, 0x82, 0x00 };
// compute size of wchar_t buffer.
int nb_chars = ::MultiByteToWideChar(CP_UTF8, // input is UTF8
0, // no flags
reinterpret_cast<char *>(my_utf8_string), // input string (no worries about signedness)
-1, // input is zero-terminated
NULL, // no output this time
0); // need the necessary buffer size
// allocate
wchar_t *my_utf16_string = new wchar_t[nb_chars];
// convert
nb_chars …Run Code Online (Sandbox Code Playgroud) unicode wchar-t buffer-overflow visual-studio-2010 visual-c++
我正在做一些关于缓冲区溢出的研究,我想知道堆栈粉碎保护是如何工作的
我有这个代码:
int main( )
{
char Buf[16];
printf(“Digite o seu nome: ”);
gets(Buf);
printf(“%s”,Buf);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我用gcc编译它
然后我放入一堆字符来填充缓冲区
首先我放16个字符
$ ./Exemplo1
Digite o seu nome:AAAAAAAAAAAAAAAA
Ola AAAAAAAAAAAAAAAA
这是好的,因为缓冲区大小合适
接下来我尝试24个字符
$ ./Exemplo1
Digite o seu nome:AAAAAAAAAAAAAAAAAAAAAAAA
Ola AAAAAAAAAAAAAAAAAAAAAAAA
为什么它仍然有效?
这不应该导致程序终止!?
它只会在我放入25个或更多字符时终止程序
./Exemplo1
Digite o seu nome:AAAAAAAAAAAAAAAAAAAAAAAAA
Ola AAAAAAAAAAAAAAAAAAAAAAAAA
*堆栈粉碎检测*:./ .Exmplo1终止
为什么?什么是缓冲区后不是返回地址?我读到的以及我认为理解的是它应该有一个金丝雀值,但如果该值已经改变并且将24个字符写入缓冲区它应该终止程序它应该不会给我一个堆栈粉碎检测甚至如果返回地址没有改变但金丝雀值没有改变.
谢谢.
好吧,所以我在教我的女朋友一些c ++,她写了一个我觉得不行的程序,但确实如此.它访问数组中的另一个元素然后存在(例如,访问数组大小为5的数组[5]).这是缓冲区溢出的实例吗?我对它的想法是它在数组之后直接写入/访问内存,这是正确的吗?基本上我的问题是..为什么这样做?
#include <iostream>
using namespace std;
int main()
{
int size;
cout << "Please enter a size for the array." << endl;
cin >> size;
cout << endl;
cout << "There are " << size << " elements in this array." << endl;
cout << endl;
cout << endl;
cout << endl;
int array[size];
for (int counter = 1; counter <= size; counter++)
{
cout << "Please enter a value for element " << counter << "." << endl; …Run Code Online (Sandbox Code Playgroud) 我决定在一些旧代码上运行一个静态分析工具,我找到了一些我正在使用sprintf的地方.该工具建议使用vsnprintf或snprintf替换调用,因为sprintf不会对缓冲区溢出执行任何类型的边界检查.
我可以轻松地在调用上进行查找和替换,以便它使用snprintf或vsnprintf,但我想确保没有其他任何事情需要完成才能使功能安全
在某些情况下,使用的字符串源自用户输入,在某些情况下,它们不会.
有人对如何做到这一点有任何建议吗?
我正在完成一项学校任务,我完全被难过了.教授和助教没有任何帮助,因为他们为任何学生提供的每一个答案都是"继续寻找,答案就在那里"的一些变化.我正在尝试使用以下代码创建一个shell:
#include <stdio.h>
#include <stdlib.h>
const char code[] =
"\x31\xc0"
"\x50"
"\x68""//sh"
"\x68""/bin"
"\x89\xe3"
"\x50"
"\x53"
"\x89\xe1"
"\x99"
"\xb0\x0b"
"\xcd\x80"
;
int main(int argc, char **argv)
{
printf("running...\n");
char buf[sizeof(code)];
strcpy(buf, code);
((void(*)( ))buf)( );
}
Run Code Online (Sandbox Code Playgroud)
我试图code[]用在网上找到的其他一些例子(包括这个网站)取代,以及教授提供的另一个例子.这些都没有用.我使用gdb进行反汇编并试图构建自己的code[],并且失败了.对于它的价值,我可以说,在普通用户中,我的应用程序会((void(*)( ))buf)( );在线路上发生段错误,只是在同一行的root用户中退出(没有段错误通知).
我不知道在哪里采取这个任务,我不能处理任何后来的缓冲区溢出任务,直到我能理解这个简单的第一步.任何帮助将大大赞赏.
编辑:我忘了提到,我已经在OSX 10.8.2上和通过VirtualBox在Ubuntu VM上尝试过这个.我假设它不适用于OSX,但我很绝望.ha对于Ubuntu,我们被要求做:
sudo #sysctl -w kernel.randomize_va_space = 0
sudo apt-get install zsh cd/bin sudo rm sh sudo ln -s/bin/zsh/bin/sh
这些命令应禁用地址空间随机化,安装zsh并将其链接到/ bin/sh.我在VM中完成了所有这些任务,没有任何错误
我正在关注"粉碎堆栈以获得乐趣和利润" http://insecure.org/stf/smashstack.html.
我想知道为什么我的代码工作,虽然我写它来产生分段错误.
#include <stdio.h>
#include <string.h>
void function(char *str){
char buffer[16];
strcpy(buffer, str);
}
int main(void)
{
char large_string[256];
int i;
for(i = 0; i < 255; i++)
large_string[i];
function(large_string);
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我正在学习缓冲区溢出漏洞利用.我写了这样一个易受攻击的程序:
#include <stdio.h>
#include <string.h>
main(int argc, char *argv[])
{
char buffer[80];
strcpy(buffer, argv[1]);
return 1;
}
Run Code Online (Sandbox Code Playgroud)
很简单的程序.想法是覆盖用于返回libc函数的返回地址start_main.一切都很顺利,我使用GDB来验证返回地址是否被指向shellcode内存中的正确地址覆盖.
但是,当我想要获得一个shell时,会出现:
Program received signal SIGSEGV, Segmentation fault. 0xbffff178 in ?? ()
0xbffff178是返回覆盖的返回地址,它确实指向shellcode我很确定.有帮助吗?
我试着理解缓冲区溢出.这是我的代码:
#include <stdio.h>
int main()
{
char buf[5] = { 0 };
char x = 'u';
printf("Please enter your name: ");
gets(buf);
printf("Hello %s!", buf);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
该buf数组的大小为5,并使用0es初始化.所以(使用null终止)我有四个字符的空间.如果我输入五个字符(例如堆栈),我会覆盖空终止字符并printf打印"Hello stacku!" 因为后续的变量x.但事实并非如此.它只是打印"堆栈".有人可以解释一下原因吗?
我有这个结构:
struct Books {
char title[50];
char author[50];
};
Run Code Online (Sandbox Code Playgroud)
让我说我知道如果我传递arg1给程序,在代码的某些部分,它会在方向上添加一些字符$title+52,因此author值被覆盖(缓冲区溢出).
现在我将ASLR添加到我的二进制文件中.通过这种方式,一些方向是随机的,所以我认为我之前描述的缓冲区溢出是不可能的.
这是真的?或者即使我添加ASLR,结构成员的方向也在一起,缓冲区溢出是可能的吗?