Posts tagged C

Pipe your log through a socket

The idea behind this hack is to log a syslog event, send to a fifo extension pipe, and through the use of socket client, send it to a server listening on a specific port.

I decided to write my “log notification” server in C#, actually it was destined for a Windows machine, so I though “why not” :)

So here it goes, in C#


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading;

namespace ServerCli
{
class Program
{
static void Main(string[] args)
{
Thread myThread = new Thread(new ThreadStart(socketInit));
myThread.Start();
}

static void socketInit()
{
IPAddress ip = IPAddress.Parse("192.168.2.107");
TcpListener ListInit = new TcpListener(ip, 8085);
ListInit.Start();
Console.WriteLine("local End point is  :"  ListInit.LocalEndpoint);
while (Thread.CurrentThread.IsAlive)
{
try
{
Socket s = myList.AcceptSocket();
byte[] b = new byte[200];
int k = s.Receive(b);
String data = "";
for (int i = 0; i < k; i++)
data += Convert.ToChar(b[i]);
Console.WriteLine(data);
s.Close();
}
catch (Exception e)
{
Console.WriteLine("Error..... " + e.StackTrace);
}
}
ListInit.Stop();
}
}
}

Ok so, this could really be improved, but you get the picture… :p

Now we need to edit syslog.conf to set our event log to pipe to our fifo extension (which we still need to create)

So… mkfifo /var/log/mySecureLog

vi /etc/syslog.conf

and add

youreventLog. |/var/log/mySecureLog

In my case, i used authpriv.warning … so that I get a notification whenever a fail login takes place on the server.

Save your file, restart syslog and now, we need to write our client, which will “cat” the fifo extension and send it to our socket connection.

I used perl here…


#!/usr/bin/perl -w
use strict;
use IO::Socket;

my $uname = `uname -n`;

open(LOGFILE, "cat /var/log/mySecureLog |") || die "oups: $!";
while (my $line =

<LOGFILE>)
{
my $conn = IO::Socket::INET->new(
Proto    => "tcp",
PeerAddr => "192.168.2.107",
PeerPort => "8085",
) or die "cannot connect";

$conn->send($line);
}

Yes I know! pretty basic script, but you still get the picture ;-)

and that’s it… so what? lanch the server, launch the perl script (client)… try an ssh connection to the server with a false username/password and look :)

Any further mods are welcome! feel free to post back with your own tweaks! As I said earlier! this is just to give the idea for further possibilities.

Wrap your shell commands

One of the most annoying matter I have met when administrating a server was following and fixing messes other users (who happen to have root password) would do on the server.

Random users with root passwords often know two things… “sh” and “history -c”… and of course “I didn’t do it”.

Now, while it is important to keep logs of activities on the server, it is even better to be able to pull up logs of every single commands entered plus their arguments.

Here is a little C wrapper once can use to wrap /bin/sh so that every commands gets logged.

Now, we first need to backup our current sh executable…  so

mv /bin/sh /bin/shb


#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#define LOG_FILE     "/var/log/sh.log"
#define LOG_FLAGS    O_CREAT|O_APPEND|O_WRONLY
#define LOG_MODE     S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH
#define WRAPPER "/bin/shb"

int main (int argc, char **const argv)
{
FILE *        logfile         = fopen (LOG_FILE, "a");
const char *  program         = argv[0];
argv[0] = WRAPPER;
if (logfile)
{
struct passwd *pw         = getpwuid (geteuid ());
int            i          = 0;
fprintf (logfile, "(%s)", pw->pw_name);

for (i = 0; i < argc; ++i)
fprintf (logfile, " '%s'", argv[i]);

fprintf (logfile, "\n");
fclose (logfile);
chmod (LOG_FILE, LOG_MODE);
}

execv (argv[0], argv);

exit (EXIT_FAILURE);

}

Now, compile your code into an sh executable.

Move your newly compiled sh into /bin/

And voila :) … whenever someone executes /bin/sh… a log will be generated in /var/log/sh.log