Home

Mongoose Web Server Spec @ 2010-03-10 20:19:33
Filed under: Code  Fedora  Linux  Python  Tech 
I happened to take a look at this and see there wasn't a package for it. It's one of those items that I don't have time to keep up with but I think would be a nice package to have in Fedora. If anyone wants to pick up with this and run with it be my guest!

The package includes a subpackage for devel (a single header file) and a subpackage for the Python bindings. There is also a patch to get the Python code to find the shared object.

Have fun!

Patch: mongoose-site-location.patch
--- bindings/python/mongoose.py	2010-03-10 20:07:53.735407453 -0500
+++ bindings/python/mongoose.py	2010-03-10 20:09:08.935760549 -0500
@@ -110,7 +110,8 @@
 
 	def __init__(self, **kwargs):
 		dll_extension = os.name == 'nt' and 'dll' or 'so'
-		self.dll = ctypes.CDLL('_mongoose.%s' % dll_extension)
+		from distutils.sysconfig import get_python_lib
+		self.dll = ctypes.CDLL(get_python_lib(1) + '/_mongoose.%s' % dll_extension)
 		start = self.dll.mg_start
 		self.ctx = ctypes.c_voidp(self.dll.mg_start()).value
 		self.version = ctypes.c_char_p(self.dll.mg_version()).value
Spec:
# sitearch for others (remove the unneeded one)
%{!?python_sitearch: %global python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(1))")}


Name:           mongoose
Version:        2.8
Release:        1%{?dist}
Summary:        Simple and easy to use web server

Group:          System Environment/Daemons
License:        MIT
URL:            http://code.google.com/p/mongoose/
Source0:        http://mongoose.googlecode.com/files/%{name}-%{version}.tgz
Patch0:         mongoose-site-location.patch
BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)


%description
Mongoose is an easy to use web server. It can be embedded into
existing application to provide a web interface to it.


%package python
Summary:       Python bindings for the mongoose web server
Requires:      mongoose


%description python
Mongoose is an easy to use web server. It can be embedded into
existing application to provide a web interface to it. This
package includes the bindings for the Python programming language.


%package devel
Summary:       Development files for the mongoose web server
BuildArch:     noarch


%description devel
Mongoose is an easy to use web server. It can be embedded into
existing application to provide a web interface to it. This
package includes the development files.


%prep
%setup -qn %{name}
%patch0


%build
make %{?_smp_mflags} linux


%install
rm -rf $RPM_BUILD_ROOT
# Install the base
mkdir -p $RPM_BUILD_ROOT/%{_bindir}
mkdir -p $RPM_BUILD_ROOT/%{_mandir}/man1/
cp %{name} $RPM_BUILD_ROOT/%{_bindir}
cp %{name}.1 $RPM_BUILD_ROOT/%{_mandir}/man1/

# Install the python bindings
mkdir -p $RPM_BUILD_ROOT/%{python_sitearch}
cp bindings/python/mongoose.py _%{name}.so $RPM_BUILD_ROOT/%{python_sitearch}

# Install the development files
mkdir -p $RPM_BUILD_ROOT/%{_includedir}/%{name}/
cp %{name}.h $RPM_BUILD_ROOT/%{_includedir}/%{name}/


%clean
rm -rf $RPM_BUILD_ROOT


%files
%defattr(-,root,root,-)
%{_bindir}/%{name}
%{_mandir}/man1/%{name}.1.gz


%files python
%defattr(-,root,root,-)
%{python_sitearch}/_%{name}.so
%{python_sitearch}/%{name}.py*


%files devel
%defattr(-,root,root,-)
%{_includedir}/%{name}/


%changelog
* Wed Mar 10 2010 Steve 'Ashcrow' Milner <me@stevemilner.org> 2.8-1
- Initial spec

 digg it   seed it   del.icio.us   ma.gnolia
Comments: 0 Tags:          


Nmap Script To Look For Arugizer @ 2010-03-08 16:50:50
Filed under: Code  Security  Tech 
After seeing this fun that is Energizer exploiting their user's systems I decided to try writing an Nmap script to detect an infection. I wasn't able to test it as I don't have an infected system. If you have access to an infected system give it a shot and let me know (I'm ashcrow on Twitter and Identi.ca). Patches welcome of course! I had to use binary data files as I couldn't quickly find a good way to move from hex to binary data.

Note: A matchline has already been committed to nmap. See this post by Skill Security for information on how to update.

Files:
Script: http://www.stevemilner.org/images/arugizer.nse
Binary Send Data: http://www.stevemilner.org/images/arugizer_ping.data
Binary Response Data: http://www.stevemilner.org/images/arugizer_yes.data


The data files need to be placed in /usr/share/nmap/nselib/data/ or wherever your nselib's data is placed.

description = [[
Checks systems for Arugizer, the energizer bunny trojan.
]]

---
-- @usage
-- nmap --script arugizer.nse <target>
-- @output
-- Host script results:
-- |_ arugizer: Infected


author = "Steve Milner"
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
categories = {"default", "safe", "discovery"}

require("nmap")

-- File that holds the following as found by ron@skullsecurity.net
-- Hex: \xC2\xE5\xE5\xE5\x9E\xA0\xD7\xA4\xA6\xD0\xD5\xDD\xDC\xC8\xD6\xDD\xD7\xD5\xC8\xD1\xD6\x83\x80\xC8\xDD\xA4\xD1\xA1\xC8\xA4\xD2\xD5\xD7\xDD\xA3\xA4\xA1\xDD\xA6\xD7\xDD\x98\xE5
-- ASCII: {E2AC5089-3820-43fe-8A4D-A7028FAD8C28}
f = assert(io.open(nmap.fetchfile('nselib/data/arugizer_ping.data'), "rb"))
ping = f:read("*all")
f:close()

-- File that holds the following as found by ron@skullsecurity.net
-- Hex: \xbc\xa0\xb6
-- ASCII: YES
f = assert(io.open(nmap.fetchfile('nselib/data/arugizer_yes.data'), "rb"))
yes = f:read("*all")
f:close()


--- Rule to decide if the action should take place.
-- We only trigger if the port is 7777
-- @param host The host table from nmap.
-- @param port The port info from nmap.
portrule = function(host, port)
    if port.state == "open" and
       port.protocol == "tcp" and
       port.number == 7777 then
        return true
    end
    return false
end


--- Takes action if the host rule is triggered.
-- Checks if port 7777 responds to known string
-- @param host The host table from nmap.
-- @param port The port info from nmap.
action = function(host, port)
    local socket = nmap.new_socket()
    socket:set_timeout(1000)
    socket:connect(host.ip, 7777)

    socket:send(ping)
    local status, response = socket:receive()
    socket:close()

    if (string.sub(response, 0, 3) == yes) then
        return "Infected"
    end
    return "Seems OK ..."
end

 digg it   seed it   del.icio.us   ma.gnolia
Comments: 0 Tags:      


Real Time Collab Test With EtherPad @ 2010-02-17 13:37:35
Filed under: Comedy  Tech 

It went great!


 digg it   seed it   del.icio.us   ma.gnolia
Comments: 0 Tags:    


I Don't Know Why I Wrote This @ 2010-02-14 20:45:01
Filed under: Code  Personal  Python  Tech 
More or less a dictionary store on the network with very simple authentication. I don't know what got into me ... I had no intention of writing this ... hopefully it will be of use to someone. It is a little messy, but it works on Python2.6.

# WHY DID I WRITE THIS?!

import os
import yaml

from multiprocessing import Process
from multiprocessing.managers import BaseManager


class WriteableDict(dict):
    """
    A dictionary which can write to disk.
    """

    def __init__(self, fs_loc, *args, **kwargs):
        """
        Create the instance.

        :Parameters:
           - `fs_loc`: location on disk to write to
           - `args`: all other non-keyword arguments
           - `kwargs`: all other keyword arguments
        """
        dict.__init__(self, *args, **kwargs)
        self.__fs_loc = fs_loc
        self.__saving = None

    def __save_to_disk(self):
        """
        Save to disk.
        """
        # If we are trying to save while anothe save is happening
        # kill the previous save as it's already out of date
        try:
            if self.__saving.is_alive():
                self.__saving.terminate()
            self.__saving.join()
        except:
            pass

        def save(write, data):
            with open(write, 'w') as fs_file:
                fs_file.write(yaml.dump(data.copy()))
            self.__saving = False

        self.__saving = Process(target=save, args=(self.__fs_loc, self))
        self.__saving.daemon = True
        self.__saving.start()

    def update(self, *args, **kwargs):
        """
        Write enabled update.

        :Parameters:
           - `args`: all other non-keyword arguments
           - `kwargs`: all other keyword arguments
        """
        dict.update(self, *args, **kwargs)
        self.__save_to_disk()

    def pop(self, *args, **kwargs):
        """
        Write enabled pop.

        :Parameters:
           - `args`: all other non-keyword arguments
           - `kwargs`: all other keyword arguments
        """
        dict.pop(self, *args, **kwargs)
        self.__save_to_disk()

    def popitem(self, *args, **kwargs):
        """
        Write enabled popitem.

        :Parameters:
           - `args`: all other non-keyword arguments
           - `kwargs`: all other keyword arguments
        """
        dict.popitem(self, *args, **kwargs)
        self.__save_to_disk()

    def clear(self, *args, **kwargs):
        """
        Write enabled clear.

        :Parameters:
           - `args`: all other non-keyword arguments
           - `kwargs`: all other keyword arguments
        """
        dict.clear(self, *args, **kwargs)
        self.__save_to_disk()


class DataBroker(object):

    __data = {}

    def __init__(self, data_loc, auth):
        """
        Creates an instance of the broker and loads any initial data found.

        :Parameters:
           - `data_loc`: directory on disk that houses any .data files to load
           - `auth`: auth information to use
        """
        self.__auth = auth
        self.__data_loc = data_loc
        for loc in filter(lambda s: s.endswith('.data'), os.listdir(data_loc)):
            full_path = os.path.sep.join([data_loc, loc])
            name = os.path.basename(loc).replace('.data', '')
            with open(full_path, 'r') as f_loc:
                self.__data[name] = WriteableDict(
                    full_path, yaml.load(f_loc.read()))

    def __authenticate(self, user, passwd):
        """
        Poor mans authentication.

        :Parameters:
           - `user`: username
           - `pasword`: ... password
        """
        if user in self.__auth.keys():
            if self.__auth[user][0] == passwd:
                return True
        return False

    def get_data(self, user, passwd, name):
        """
        Hands over access to the dictionary.

        :Parameters:
           - `user`: username
           - `password`: password
           - `name`: name of the dictionary to access
        """
        if self.__authenticate(user, passwd):
            if name in self.__auth[user][1]:
                if name not in self.__data.keys():
                    self.__data[name] = WriteableDict(self.__data_loc + name + ".data")
                return self.__data[name]
        raise Exception


class DataManager(BaseManager):
    """
    Data Manager.
    """

    def __init__(self, *args, **kwargs):
        """
        Creates an instance of the manager.

        :Parameters:
           - `args`: all other non-keyword arguments
           - `kwargs`: all other keyword arguments
        """
        BaseManager.__init__(self, *args, **kwargs)
        self.register('get_data',
            callable=lambda u, p, s: broker.get_data(u, p, s))


if __name__ == '__main__':
    # Auth information user: (password (dicts, that, they, can, access))
    auth = {'test': ('testing', ('something', ))}
    # Setup the broker and manager
    broker = DataBroker('/tmp/', auth)
    manager = DataManager(address=('', 50000), authkey='abracadabra')
    # and serve until a ctrl+c
    server = manager.get_server()
    try:
        server.serve_forever()
    except KeyboardInterrupt, ki:
        server.shutdown()

 digg it   seed it   del.icio.us   ma.gnolia
Comments: 0 Tags:        


Theory: Why Business People Are Crazy @ 2010-02-01 10:56:27
Filed under: Comedy  Philosophy  Tech 
I've always wondered why business people (marketing, PR, sales, etc..) make little to no sense when they talk about technology including whatever tech they think will make their life magically easy. I happened to come across a company advertising it's services as a low cost development shop to outsource to. As an engineer, I know that outsourcing works in so few cases it's not really worth looking at (unless you are trying to cut costs and get a promotion quickly ignoring the end result of the work). In any case, here is some of their marketing material. Be prepared to be confused (or inspired if you are a business person).

 What you are using our software? 
Unlike the other software you buy. For our software is the
tool, if deployed, or a professional you must learn to apply
themselves will not achieve the desired effect. When using
our software than the software you buy (the tools) you will
be advised and supported during implementation of the
software, and you will be maintaining the software during
operating software.


Is your brain fried yet? If so, put on a suit and SELL SELL SELL!

 digg it   seed it   del.icio.us   ma.gnolia
Comments: 0 Tags:      


 
A Django joint.
© 2007-2009 Steve 'Ashcrow' Milner | Studio7designs | Arbutus Photography