How to create a snort content rule - snort

I am new into using snort and I don't know how to properly create rules.
I want someone to explain me how to create a rule for detection of a specific content. For example: I want to generate an alert when I search on Google the word 'terrorism'.
I tried to create the rule with what I've seen on Youtube or Google, as examples, but none of them works and I don't know what to try anymore. For instance, I am using Snort 2.9.9
alert tcp $HOME_NET any -> $EXTERNAL_NET any (msg:"terrorism content found"; content:"terrorism"; nocase; sid:1000000;)
I don't have any errors from the local.rules file, but I got the line 'include $RULE_PATH/snort.rules' commented because of some problems with PulledPork.
I expect to have an alert in the CLI, but there is no output.

I know that this is already too late but here's the answer for future reference.
The packets are probably being sent using HTTPS connection (which is why they are encrypted).
This might be a reason why there are no alerts.
Please refer here for a detailed explanation.

rules are ready, u just replace, alert with sdrop:
find /home/www \( -type d -name .git -prune \) -o -type f -print0 | xargs -0 sed -i 's/subdomainA\.example\.com/subdomainB.example.com/g'
and you can use include in config file

O.K
Answer is here: http://manpages.ubuntu.com/manpages/xenial/man8/u2spewfoo.8.html
Download Snort source, Make logs costume, write ur code to get log stream in control
Then Build source and run
Be successful :)

It is possible to send alert messages and some packet relevant data
from snort through a unix socket, to perform additional separate
processing of alert data.
Snort has to be built with spo_unsock.c/h output plugin is built in and
-A unsock (or its equivalent through the config file) is
used. The unix socket file should be created in /dev/snort_alert. Your
‘client’ code should act as ‘server’ listening to this unix socket.
Snort will be sending you Alertpkt structures which contain alert
message, event id. Original datagram, libpcap pkthdr, and offsets to
datalink, netlayer, and transport layer headers.
Below is an example how unix sockets could be used. If you have any
comments bug reports, and feature requests, please contact
snort-devel#lists.sourceforge.net or drop me an email to fygrave at
tigerteam dot net.
-Fyodor
[for copyright notice, see snort distribution code]
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include
#include "snort.h"
int sockfd;
void
sig_term (int sig)
{
printf (“Exiting!\n”);
close (sockfd);
unlink (UNSOCK_FILE);
exit (1);
}
int
main (void)
{
struct sockaddr_un snortaddr;
struct sockaddr_un bogus;
Alertpkt alert;
Packet *p;
int recv;
socklen_t len = sizeof (struct sockaddr_un);
if ((sockfd = socket (AF_UNIX, SOCK_DGRAM, 0)) < 0)
{
perror (“socket”);
exit (1);
}
bzero (&snortaddr, sizeof (snortaddr));
snortaddr.sun_family = AF_UNIX;
strcpy (snortaddr.sun_path, UNSOCK_FILE);
if (bind (sockfd, (struct sockaddr *) &snortaddr, sizeof (snortaddr)) < 0)
{
perror (“bind”);
exit (1);
}
signal(SIGINT, sig_term);
while ((recv = recvfrom (sockfd, (void *) &alert, sizeof (alert),
0, (struct sockaddr *) &bogus, &len)) > 0)
{
/* do validation of recv if you care */
if (!(alert.val & NOPACKET_STRUCT))
{
if ((p = calloc (1, sizeof (Packet))) == NULL)
{
perror ("calloc");
exit (1);
}
p->pkt = alert.pkt;
p->pkth = &alert.pkth;
if (alert.dlthdr)
p->eh = (EtherHdr *) (alert.pkt + alert.dlthdr);
if (alert.nethdr)
{
p->iph = (IPHdr *) (alert.pkt + alert.nethdr);
if (alert.transhdr)
{
switch (p->iph->ip_proto)
{
case IPPROTO_TCP:
p->tcph = (TCPHdr *) (alert.pkt + alert.transhdr);
break;
case IPPROTO_UDP:
p->udph = (UDPHdr *) (alert.pkt + alert.transhdr);
break;
case IPPROTO_ICMP:
p->icmph = (ICMPHdr *) (alert.pkt + alert.transhdr);
break;
default:
printf ("My, that's interesting.\n");
} /* case */
} /* thanshdr */
} /* nethdr */
if (alert.data)
p->data = alert.pkt + alert.data;
/* now do whatever you want with these packet structures */
} /* if (!NOPACKET_STRUCT) */
printf ("%s [%d]\n", alert.alertmsg, alert.event.event_id);
if (!(alert.val & NOPACKET_STRUCT))
if (p->iph && (p->tcph || p->udph || p->icmph))
{
switch (p->iph->ip_proto)
{
case IPPROTO_TCP:
printf ("TCP from: %s:%d ",
inet_ntoa (p->iph->ip_src),
ntohs (p->tcph->th_sport));
printf ("to: %s:%d\n", inet_ntoa (p->iph->ip_dst),
ntohs (p->tcph->th_dport));
break;
case IPPROTO_UDP:
printf ("UDP from: %s:%d ",
inet_ntoa (p->iph->ip_src),
ntohs (p->udph->uh_sport));
printf ("to: %s:%d\n", inet_ntoa (p->iph->ip_dst),
ntohs (p->udph->uh_dport));
break;
case IPPROTO_ICMP:
printf ("ICMP type: %d code: %d from: %s ",
p->icmph->type,
p->icmph->code, inet_ntoa (p->iph->ip_src));
printf ("to: %s\n", inet_ntoa (p->iph->ip_dst));
break;
}
}
}
perror (“recvfrom”);
close (sockfd);
unlink (UNSOCK_FILE);
return 0;
}

Related

Linux TCP socket timestamping option

Quoting form this online kernel doc
SO_TIMESTAMPING
Generates timestamps on reception, transmission or both. Supports
multiple timestamp sources, including hardware. Supports generating
timestamps for stream sockets.
Linux supports TCP timestamping, and I tried to write some demo code to get any timestamp for TCP packet.
The server code as below:
//Bind
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
perror("bind failed. Error");
return 1;
}
puts("bind done");
//Listen
listen(socket_desc , 3);
//Accept and incoming connection
puts("Waiting for incoming connections...");
int c = sizeof(struct sockaddr_in);
client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c);
if (client_sock < 0)
{
perror("accept failed");
return 1;
}
// Note: I am trying to get software timestamp only here..
int oval = SOF_TIMESTAMPING_RX_SOFTWARE | SOF_TIMESTAMPING_SOFTWARE;
int olen = sizeof( oval );
if ( setsockopt( client_sock, SOL_SOCKET, SO_TIMESTAMPING, &oval, olen ) < 0 )
{ perror( "setsockopt TIMESTAMP"); exit(1); }
puts("Connection accepted");
char buf[] = "----------------------------------------";
int len = strlen( buf );
struct iovec myiov[1] = { {buf, len } };
unsigned char cbuf[ 40 ] = { 0 };
int clen = sizeof( cbuf );
struct msghdr mymsghdr = { 0 };
mymsghdr.msg_name = NULL;
mymsghdr.msg_namelen = 0;
mymsghdr.msg_iov = myiov;
mymsghdr.msg_iovlen = 1;
mymsghdr.msg_control = cbuf;
mymsghdr.msg_controllen = clen;
mymsghdr.msg_flags = 0;
int read_size = recvmsg( client_sock, &mymsghdr, 0);
if(read_size == 0)
{
puts("Client disconnected");
fflush(stdout);
}
else if(read_size == -1)
{
perror("recv failed");
}
else
{
struct msghdr *msgp = &mymsghdr;
printf("msg received: %s \n",(char*)msgp->msg_iov[0].iov_base);// This line is successfully hit.
// Additional info: print msgp->msg_controllen inside gdb is 0.
struct cmsghdr *cmsg;
for ( cmsg = CMSG_FIRSTHDR( msgp );
cmsg != NULL;
cmsg = CMSG_NXTHDR( msgp, cmsg ) )
{
printf("Time GOT!\n"); // <-- This line is not hit.
if (( cmsg->cmsg_level == SOL_SOCKET )
&&( cmsg->cmsg_type == SO_TIMESTAMPING ))
printf("TIME GOT2\n");// <-- of course , this line is not hit
}
}
Any ideas why no timestamping is available here ? Thanks
Solution
I am able to get the software timestamp along with hardware timestamp using onload with solarflare NIC.
Still no idea how to get software timestamp alone.
The link you gave, in the comments at the end, says:
I've discovered why it doesn't work. SIOCGSTAMP only works for UDP
packets or RAW sockets, but does not work for TCP. – Gio Mar 17 '16 at 9:331
it doesn't make sense to ask for timestamps for TCP, because there's
no direct correlation between arriving packets and data becoming
available. If you really want timestamps for TCP you'll have to use
RAW sockets and implement your own TCP stack (or use a userspace TCP
library). – ecatmur Jul 4 '16 at 10:39

boost asio SO_REUSEPORT

I'm working on a multi-processes socket server with the boost library.
Each process run a io_service.
I want to this processes all accept on the same port.
I know SO_REUSEPORT (after linux kernel 3.9) will help.
like this python script
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
s.bind(('0.0.0.0', 9091))
s.listen(1)
while True:
conn, addr = s.accept()
print "new connection"
while True:
data = conn.recv(100)
print "got data", data
if not data or data == 'exit':
break
conn.close()
But I don't know how to use this option in boost asio io_service ?
For people reading this in 2019: Asio now includes a workaround in boost/asio/detail/impl/socket_ops.ipp:
#if defined(__MACH__) && defined(__APPLE__) \
|| defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
// To implement portable behaviour for SO_REUSEADDR with UDP sockets we
// need to also set SO_REUSEPORT on BSD-based platforms.
if ((state & datagram_oriented)
&& level == SOL_SOCKET && optname == SO_REUSEADDR)
{
call_setsockopt(&msghdr::msg_namelen, s,
SOL_SOCKET, SO_REUSEPORT, optval, optlen);
}
#endif
So, socket_->set_option(udp::socket::reuse_address(true)); will set the SO_REUSEPORT option automatically if needed.
Following on from how boost/asio/socket_base.hpp defines reuse_address, I did it like this:
typedef boost::asio::detail::socket_option::boolean<SOL_SOCKET, SO_REUSEPORT> reuse_port;
socket_.set_option(reuse_port(true));
Answer by my own.
#include <iostream>
#include <string>
#include <array>
#include <boost/asio.hpp>
#include <arpa/inet.h>
using boost::asio::ip::tcp;
int main()
{
boost::asio::io_service io;
tcp::acceptor acceptor(io);
acceptor.open(tcp::v4());
int one = 1;
setsockopt(acceptor.native_handle(), SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &one, sizeof(one));
acceptor.bind(tcp::endpoint(tcp::v4(), 9091));
acceptor.listen();
std::cout << "start" << std::endl;
for(;;)
{
tcp::socket socket(io);
acceptor.accept(socket);
std::cout << "new connections" << std::endl;
for(;;)
{
std::array<char, 4> buf;
boost::system::error_code error;
boost::asio::read(socket, boost::asio::buffer(buf), error);
if(error)
{
std::cout << "read error: " << error << std::endl;
break;
}
std::cout << "read: " << std::string(buf.data()) << std::endl;
}
}
}
The HTTP server example shows one way: http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/example/cpp11/http/server/server.cpp
// Open the acceptor with the option to reuse the address (i.e. SO_REUSEADDR).
boost::asio::ip::tcp::resolver resolver(io_service_);
boost::asio::ip::tcp::endpoint endpoint = *resolver.resolve({address, port});
acceptor_.open(endpoint.protocol());
acceptor_.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
acceptor_.bind(endpoint);
acceptor_.listen();
IIRC there's also an acceptor constructor that takes a boolean argument to set the reuse flag.

how to catch the socket programming's send and receive request in fiddler

i have the code for creating a socket in c++.the code is running fine.the code is:
#include <winsock2.h>
#include <WS2tcpip.h>
#include <windows.h>
#include <iostream>
#pragma comment(lib,"ws2_32.lib") using namespace std;
int main (){
// Initialize Dependencies to the Windows Socket.
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) {
cout << "WSAStartup failed.\n";
system("pause");
return -1;
}
// We first prepare some "hints" for the "getaddrinfo" function
// to tell it, that we are looking for a IPv4 TCP Connection.
struct addrinfo hints;
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET; // We are targeting IPv4
hints.ai_protocol = IPPROTO_TCP; // We are targeting TCP
hints.ai_socktype = SOCK_STREAM; // We are targeting TCP so its SOCK_STREAM
// Aquiring of the IPv4 address of a host using the newer
// "getaddrinfo" function which outdated "gethostbyname".
// It will search for IPv4 addresses using the TCP-Protocol.
struct addrinfo* targetAdressInfo = NULL;
DWORD getAddrRes = getaddrinfo("www.google.com", NULL, &hints, &targetAdressInfo);
if (getAddrRes != 0 || targetAdressInfo == NULL)
{
cout << "Could not resolve the Host Name" << endl;
system("pause");
WSACleanup();
return -1;
}
// Create the Socket Address Informations, using IPv4
// We dont have to take care of sin_zero, it is only used to extend the length of SOCKADDR_IN to the size of SOCKADDR
SOCKADDR_IN sockAddr;
sockAddr.sin_addr = ((struct sockaddr_in*) targetAdressInfo->ai_addr)->sin_addr; // The IPv4 Address from the Address Resolution Result
sockAddr.sin_family = AF_INET; // IPv4
sockAddr.sin_port = htons(80); // HTTP Port: 80
// We have to free the Address-Information from getaddrinfo again
freeaddrinfo(targetAdressInfo);
// Creation of a socket for the communication with the Web Server,
// using IPv4 and the TCP-Protocol
SOCKET webSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (webSocket == INVALID_SOCKET)
{
cout << "Creation of the Socket Failed" << endl;
system("pause");
WSACleanup();
return -1;
}
// Establishing a connection to the web Socket
cout << "Connecting...\n";
if(connect(webSocket, (SOCKADDR*)&sockAddr, sizeof(sockAddr)) != 0)
{
cout << "Could not connect";
system("pause");
closesocket(webSocket);
WSACleanup();
return -1;
}
cout << "Connected.\n";
// Sending a HTTP-GET-Request to the Web Server
const char* httpRequest = "GET / HTTP/1.1\r\nHost: www.google.com\r\nConnection: close\r\n\r\n";
int sentBytes = send(webSocket, httpRequest, strlen(httpRequest),0);
if (sentBytes < strlen(httpRequest) || sentBytes == SOCKET_ERROR)
{
cout << "Could not send the request to the Server" << endl;
system("pause");
closesocket(webSocket);
WSACleanup();
return -1;
}
// Receiving and Displaying an answer from the Web Server
char buffer[10000];
ZeroMemory(buffer, sizeof(buffer));
int dataLen;
while ((dataLen = recv(webSocket, buffer, sizeof(buffer), 0) > 0))
{
int i = 0;
while (buffer[i] >= 32 || buffer[i] == '\n' || buffer[i] == '\r') {
cout << buffer[i];
i += 1;
}
}
// Cleaning up Windows Socket Dependencies
closesocket(webSocket);
WSACleanup();
system("pause");
return 0; }
I want to capture the request and response in fiddler while sending and receiving the request but fiddler is not catching it.
thanks in advance
Fiddler inserts itself into the stack as an HTTP proxy server. It relies on the web browsers to recognize that there is a proxy configured on the PC and to send through that. Your code does not detect for a proxy to send through - so Fiddler won't be able to monitor your traffic.
You have several options.
Since you are own Windows, just switch from using direct sockets to using the WinInet HTTP API. It will do automatic proxy detection for you without you having to think about it. It will do the proxy authentication as well if its required.
OR. Use Wireshark or NetMon to analyze your traffic instead of Fiddler.
I'd recommend #1 since that means your code will work in the presence of a real proxy server (commonly found on enterprise networks) and Fiddler will just work with it.
I suppose there is a third option where you auto-detect the browser proxy settings, then create a socket to the proxy, speak the HTTP PROXY protocol, etc... but that's not the best practice.

Why is Windows 7 firewall preventing PASV FTP connections?

I was trying to get CFtpServer's first example program running on a Windows 7 Pro, x64 system. After much beating around the bush and not believing what I was seeing, I got the problem down to the following simple program:
#include <iostream>
using namespace std;
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#define die(code) { cerr << "die at " << __FILE__ << " " << __LINE__ << " "; exit(code); }
int main(int argc, char **argv)
{
short port = 21;
if (argc == 2) {
port = atoi(argv[1]);
}
WSADATA WSAData;
if ( WSAStartup( MAKEWORD(2, 2), &WSAData) != 0)
die(1);
SOCKET ls = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//!!! proto 0 in ftpdmin!
if (ls == INVALID_SOCKET) die(1);
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = htons( port );
if (bind( ls, (struct sockaddr *) &sin, sizeof( struct sockaddr_in ) )
== SOCKET_ERROR) die(2);
if (listen( ls, 1 ) == SOCKET_ERROR ) //!!! backlog 1 in ftpdmin!
die(3);
// wait for connect, transmit till error
SOCKET ts;
for( ;; ) {
ts = accept( ls, NULL, NULL );
if (ts == INVALID_SOCKET) die(5);
// now write some things to that socket.
int i=0;
for(;;) {
char buf[256];
sprintf(buf, "%d Testing...\r\n",i+224);
if (send(ts, buf, strlen(buf), 0) < 0) {
DWORD err = WSAGetLastError();
cerr << "send failed with " << err << endl;
break;
}
Sleep(1000);
i = (i+1)%10;
}
Sleep(1000);
closesocket(ts);
}
}
This program opens the specified socket, listens on it for connections. When it gets a connection, it proceeds to write strings that bear a passing resemblance to the string an FTP server might use to respond to the PASV command. It will keep transmitting strings, once a second, until something goes wrong.
On my system, connecting to this 'server' using the nc.exe command, I see a few strings, then the socket will close (the error printed by the 'server' is 10053).
If I disabled the Windows firewall, I see strings as long as I care to leave the nc command running.
I've seen two different variations, and I don't know what causes the difference: Sometimes it would stop when it transmitted the string '227 ', later it started dying on '229 '. It's giving every appearance of being sensitive to the text being sent.
After 3 days of beating my head on this one, I have an answer: Window KB2754804. It's a bug, known to MS since somewhere in 2011. There is a Hotfix in the referenced Knowledge base article, but it doesn't seem to work for my tests, so I had to take the alternative route of disabling the Stateful FTP firewall.
I finally got to the KB article, from this SO entry.

I/O redirection in a C program

I want to implement a simple "cat file1 > file1" command in a C program. I have tried the following, but it does not work...
main () {
pid_t pid;
FILE *ip, *op;
char *args[3];
printf("Name of the executable program\n\t");
scanf("%s", &name[0]); // I entered cat here
printf("Name of the input file\n\t");
scanf("%s", &name[1]); //file1.txt
printf("Name of the output file\n\t");
scanf("%s", &name[0]); //file2.txt
pid = fork();
if(pid == -1)
perror("fork() error");
else if(pid > 0)
waitpid(-1, NULL, 0);
else if (pid == 0) {
op = fopen(name[2], "w");
close(1);
dup(op);
execlp(name[0], name[1], NULL);
}
return 0;
}// end of main()
I thought the execlp() will run cat file1.txt and its output will be redirected to file2.txt, but it's not and I don't know why. How do I do it?
scanf("%s", &name[0]); // I entered cat here
printf("Name of the input file\n\t");
scanf("%s", &name[1]); //file1.txt
printf("Name of the output file\n\t");
scanf("%s", &name[0]); //file2.txt
Clearly not a C&P of actual code - name should be args, and the last one should be "2" instead of 0.
Also, dup works on file descriptors, not FILE*, so need to look at open rather than fopen, or whatever method gets the fd from a FILE*
The first argument to execlp() is the name to be looked up; the second and following arguments are the argv list, starting with argv[0].
int execlp(const char *file, const char *arg0, ... /*, (char *)0 */);
For shell I/O redirection, it is easier to open files with open() than to use standard I/O (<stdio.h> and FILE *); you should also close the file you opened after the dup(), though it is easier to use dup2(). You need to allocate space to read the strings into; on many systems, the original code would crash because the pointers in str don't point anywhere. You should normally aim to exit with status 0 only if everything worked; otherwise, exit with a non-zero exit status.
This leads to:
#include <fcntl.h> /* open() */
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h> /* waitpid() */
#include <unistd.h> /* execlp(), fork(), dup2() */
int main(void)
{
pid_t pid;
pid_t corpse;
int status;
char name[3][50];
printf("Name of the executable program\n\t");
if (scanf("%49s", name[0]) != 1)
return(EXIT_FAILURE);
printf("Name of the input file\n\t");
if (scanf("%49s", name[1]) != 1)
return(EXIT_FAILURE);
printf("Name of the output file\n\t");
if (scanf("%49s", name[2]) != 1)
return(EXIT_FAILURE);
pid = fork();
if (pid == -1)
{
perror("fork() error");
return(EXIT_FAILURE);
}
else if (pid > 0)
corpse = waitpid(-1, &status, 0);
else
{
int fd = open(name[2], O_WRONLY|O_CREAT|O_EXCL, 0644);
if (fd < 0)
{
fprintf(stderr, "Failed to open %s for writing\n", name[2]);
return(EXIT_FAILURE);
}
dup2(fd, 1);
close(fd);
execlp(name[0], name[0], name[1], NULL);
fprintf(stderr, "Failed to exec %s\n", name[0]);
return(EXIT_FAILURE);
}
return(corpse == pid && status == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
}
You have to either use fork() a process and reassign it's file descriptors to previously(manually) open()'ed file, or use system() call to make shell handle it for you.