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:      


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:        


Mercurial Is Teh Awesome @ 2009-12-28 11:28:58
Filed under: Code  Personal  Tech 
I'm really digging it. Just for the heck of it, here is my global config.
[ui]
username = Steve 'Ashcrow' Milner <stevem@EXAMPLE.COMt>
editor = vim

[extensions]
hgext.gpg=
hgext.graphlog =
color =
mq =
bookmarks =
pager =
inotify =
rebase =
localbranch = ~/.hg-ext/localbranch.py
hgext.convert =

[pager]
pager = less -R

[diff]
git = True

[alias]
blame = annotate -uln

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


Static Analysis in Nmap Makefile @ 2009-10-31 14:18:12
Filed under: Code  Security 
I noticed there wasn't a makefile target for static analysis so I made one ... I doubt it will get applied, but might as well give it a shot ...

Index: Makefile.in
===================================================================
--- Makefile.in (revision 15953)
+++ Makefile.in (working copy)
@@ -77,6 +77,11 @@
 endif
 endif

+# The tool to use for analysis
+ANALYZE=$(shell which rats)
+# Command to run if the analyzer is available
+ANALYSIS_CMD=$(ANALYZE) -w 2 .
+
 export SRCS = main.cc nmap.cc targets.cc tcpip.cc nmap_error.cc 
utils.cc idle_scan.cc osscan.cc osscan2.cc output.cc payload.cc 
scan_engine.cc timing.cc charpool.cc services.cc protocols.cc nmap_rpc.cc 
portlist.cc NmapOps.cc TargetGroup.cc Target.cc FingerPrintResults.cc 
service_scan.cc NmapOutputTable.cc MACLookup.cc nmap_tty.cc nmap_dns.cc 
traceroute.cc portreasons.cc $(NSE_SRC) @COMPAT_SRCS@

 export HDRS = charpool.h FingerPrintResults.h global_structures.h 
idle_scan.h MACLookup.h nmap_amigaos.h nmap_dns.h nmap_error.h 
nmap.h NmapOps.h NmapOutputTable.h nmap_rpc.h nmap_tty.h 
nmap_winconfig.h osscan.h osscan2.h output.h payload.h portlist.h protocols.h 
scan_engine.h service_scan.h services.h TargetGroup.h Target.h targets.h 
tcpip.h timing.h utils.h traceroute.h portreasons.h $(NSE_HDRS)
@@ -291,6 +296,13 @@
 uninstall-ncat:
    @cd $(NCATDIR) && $(MAKE) uninstall

+analyze:
+ifneq ($(ANALYZE),)
+   @$(ANALYSIS_CMD)
+else
+   @echo "the static analysis tool is not available"
+endif
+
 ${srcdir}/configure: configure.ac
    cd ${srcdir} && autoconf

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


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