www.LinuxHowtos.org





LIBMIX

Section: C Library Functions (3)
Updated: Jan 2003
Index Return to Main Contents
 

NAME

libmix - Crypto, Network and Multipurpose Library  

SYNOPSIS

#include <mix/mix.h>



extern short alg;
extern short aes_binary;
int lm_keywillwork (int algorithm, u1byte *testkey);
u4byte *aes_key (const char *key);
u1byte *aes_encrypt (const u1byte *inbuf, int *length);
u1byte *aes_decrypt (const u1byte *inbuf, int length);
u1byte *aes_hash (const s1byte *inbuf);
s1byte *base64_in (const u1byte *inbuf, int length);
u1byte *base64_out (const s1byte *inbuf, int length);



char *lm_device;
int pcap_l2offset;
pcap_t *pcap_fd;
struct ether_addr *srcmacp;
char tfn2k2_command
char tfn2k2_lastsize
struct libnet_link_int *lm_fd;
void lm_libnet_init(void);
void lm_libnet_destroy(void);
void tfn2k2transmit(unsigned long from, unsigned long to, int proto, char id, char *payload, int payloadsize);
void lm_libpcap_init(void);
void lm_libpcap_destroy(void);
char *tfn2k2read(void);



int isip(char *host);
unsigned long resolve (char *host);
char *lm_ntoa(unsigned int, char *);
unsigned int lm_addr(char *);
unsigned short sum (unsigned short *buf, int nwords);
int incip (char *ipaddr);
int decip (char *ipaddr);
int rawsock (int protocol);
int psock (void);
unsigned int inet_gethostaddr (void);
unsigned int inet_local (void);
void ethsrc (struct eth *eh, char *addr);
void ethdst (struct eth *eh, char *addr);
int lm_timed_connect (int fd, const struct sockaddr *serv_addr, socklen_t addrlen, unsigned int seconds);

ssize_t lm_timed_read (int fd, unsigned char *buf, size_t count, unsigned int seconds);
void tfntransmit (unsigned long longip_src, unsigned long longip_dst, int protocol, char *data);
char * tfnread (int icmpsock, int udpsock, int tcpsock);



void * LMNEW (type, size_in_bytes);
void LMDELETE (var);
int exclude_parse (FILE *);
void exclude_list (void);
int excluded (unsigned int addr);
void exclude_free (void);
long getrandom (int low, int high);
void strchop (char *buffer);
void strlower (char *buffer);
void strnsubst (char *buffer, char c, int length);
char *strscpy (char *in, char *out, char *out2, char c);
int pattern (char *needle, char **haystack);
void log (char *filename, char *buf, ...);
void fatal (char *msg, ...);
void disguise (char *name, int argc, char **argv);
void ioterm (int infd, int outfd, int encryption);
int isactive (char *pidfile);
char * nstrdup (const char *p);
int sexec (char *path, char *newpath, char *arg0, char *arg1, char *arg2, char *arg3);
int sexecve (int argc, char **argv, char **envp, char *newpath, char *newexec);
int lm_scan_run (FILE *input, lm_callback func, int forking);

 

LICENSE

LibMix is distributed under the GNU General Public License. You may use, modify, and distribute this program freely for non-commercial purposes. If you are planning to use the program or any parts of the distribution for any commercial purpose, you must ask for the authors permission before you do so. A copy of the GPL has been included in the distribution.

 

LIBMIX PROTOCOL STRUCTURES

LibMix defines a set of network protocol structures which can be used universally in conjunction with LibMix-based programs. It defines the network protocols: eth (Ethernet), lmip (IP), lmtcp (BSD style TCP header), lmtcp2 (TCP header with single flags), sa (inet sockaddr), su (unix sockaddr), tribe (tribe header), and the protocol numbers and header sizes.

/* IP protocols, common */
#define P_IP 0
#define P_ICMP 1
#define P_IGMP 2
#define P_TCP 6
#define P_UDP 17
#define P_RAW 255

/* Protocol header sizes */
#define M_SIN   16
#define M_ETH   14
#define M_IP    20
#define M_ICMP   8
#define M_TCP   20
#define M_UDP    8

struct sa
  {
    u16 fam, dp;        /* family, destination port */
    u32 add;            /* destination address */
    u8 zero[8];
  };

struct su
  {
    u16 fam;
    char path[108];
  };

struct eth
{
 unsigned char dst[6];  /* destination MAC address */
 unsigned char src[6];  /* source MAC address */
 unsigned short proto;
};

struct lmip
  {
#ifndef WORDS_BIGENDIAN
    u8 ihl:4, ver:4;    /* header length, version */
#else
    u8 ver:4, ihl:4;
#endif
    u8 tos;             /* type of service */
    u16 tl, id, off;    /* total length, ID, fragment offset */
    u8 ttl, pro;        /* time to live, protocol */
    u16 sum;            /* checksum, filled in by kernel */
    u32 src, dst;       /* IP source/destination addresses */
  };

struct lmtcp
  {
    u16 src, dst;       /* source/destination ports */
    u32 seq, ack;       /* sequence, ack sequence */
#ifndef WORDS_BIGENDIAN
    u8 x2:4, off:4;
#else
    u8 off:4, x2:4;
#endif
    u8 flg;             /* tcp flags (flag1 | flag2) */
#define FIN  0x01
#define SYN  0x02
#define RST  0x04
#define PUSH 0x08
#define ACK  0x10
#define URG  0x20
    u16 win, sum, urp;  /* window, checksum, urgent data pointer */
  };

struct lmtcp2
  {
    u16 src, dst;
    u32 seq, ackseq;
#ifndef WORDS_BIGENDIAN
    u16 res1:4;
    u16 doff:4;
    u16 fin:1;
    u16 syn:1;
    u16 rst:1;
    u16 psh:1;
    u16 ack:1;
    u16 urg:1;
    u16 res2:2;
#else
    u16 doff:4;
    u16 res1:4;
    u16 res2:2;
    u16 urg:1;
    u16 ack:1;
    u16 psh:1;
    u16 rst:1;
    u16 syn:1;
    u16 fin:1;
#endif
    u16 win, sum, urp;
  };

struct lmudp
  {
    /* source/destination port, datagram length, checksum */
    u16 src, dst, len, sum;
  };

struct lmicmp
  {
    u8 type, code;              /* icmp type, icmp code */
    u16 sum;                    /* checksum */
    u16 id, seq;                /* ID, sequence */
  };

struct tribe
  {
    char start, id, end;        /* random-ID, command ID, random-ID */
  };

For more information, please consult the include files in /usr/include/mix/.

 

CRYPTOGRAPHIC FUNCTIONS

To use the interface to AES cryptography, the variable alg can be set to one of the supported AES algorithms, which are CAST256, MARS, SAFERP, TWOFISH and RIJNDAEL. To find more about the supported algorithms, consult the include file mix/mix.h. The default algorithm is CAST256. The variable aes_binary determines whether the AES encrypted string will be returned in its binary form, or converted to ASCII by base64 encoding it. The latter setting (a value of 0) is the recommended default.

lm_keywillwork should be called to test whether a secret key/algorithm combination will work, or will be unclean (which happens in rare cases, especially with very short keys). The first argument is the algorithm (see above) and the second one is a pointer to the key you want to use.

aes_key is called to set a new key/password, whose effective size can be 256 bits (32 bytes). This function must also be called to set the password again each time a different algorithm is selected.

aes_encrypt will encrypt inbuf with the current password, and return a string allocated with LMNEW(), which can and should be freed with LMDELETE() later. The variable length must be passed as a pointer, since the string length will be padded to fit the AES block size of 16 bytes. The changed value may be used later during decryption. aes_decrypt will decrypt an AES encrypted buffer with the current password, and return the plaintext in a dynamically allocated buffer. aes_hash will set the input as password, then encrypt it with itself and return the encrypted result in a dynamically allocated buffer, which is suitable to be used as a cryptographic hash.

base64_in is a simple base64 encoding function, which returns a dynamically allocated buffer with the encoded string, and base64_out converts base64 encoded text back. This is used internally by the AES interface, and is useful to convert binary data to ASCII, to transmit it over 7-bit channels, or to perform string operations on it which interpret binary zeroes as buffer delimiter.

 

NETWORK FUNCTIONS (libnet/libpcap)

lm_device is the interface name on which to sniff and send raw packets over. It is initialized in lm_libnet_init() or lm_libpcap_init(), but can also be assinged manually, i.e. lm_device = "eth0".

pcap_l2offset is the offset of bytes from the level 2 link layer to the level 3 IP layer, specific to the current device and descriptor in use by libpcap.

pcap_fd is the descriptor opened by lm_libpcap_init(). Once this is opened, it can be used with standard pcap(3) calls, such as pcap_next().

srcmacp is a pointer to the source mac address of the first interface of this machine, which is initialized during lm_libnet_init().

tfn2k2_command stores the tfn2k2 command type (1-255) of the last packet that was successfully received via tfn2k2read().

lm_fd is the libnet file descriptor over which raw packets can be sent.

lm_libnet_init initializes the libnet variables and -subsystem of LibMix.

lm_libnet_destroy destroys the dynamic objects created my lm_libnet_init().

tfn2k2transmit is a stealth transmission function, much like tfntransmit. You have to set a key with aes_key() before calling this, and specify source IP address, destination IP address, transmission protocol ID, command type ID (can be anything) and the payload. WARNING: The first three bytes of the payload will be overwritten!

lm_libpcap_init initializes the libpcap variables and -subsystem of LibMix.

lm_libpcap_destroy destroys the dynamic objects created my lm_libpcap_init().

tfn2k2read is the counterpart to tfn2k2transmit(). It will sniff a packet from the wire and analyze and try to decrypt it. You need to set the correct aes_key() before calling this function. If the packet can be decrypted (i.e. is a valid tfn2k2 packet), then the plaintext payload will be returned, else NULL will be returned.

 

NETWORK FUNCTIONS

isip will determine, if the buffer contains a valid IP address in ASCII format, and returns 1, if this is the case, and 0 if not.

resolve is an easy way to resolve an IP address or hostname and return the address in longip format, which can be used, for example, in IP headers.

lm_ntoa and lm_addr are much faster substitutes for the respective original functions, inet_ntoa(3) and inet_addr(3) which are called with a long int instead of the in_addr struct. The old ntoa function is still included for the sake of compatibility, but depreceated.

sum will compute the RFC1071 checksum for IP-, ICMP-, and UDP datagrams. The first argument is a pointer to the beginning of the datagram header, and the second argument is the datagram length, including payload, right-shifted one bit (divides by 2).

incip parses an IP address in ASCII format, and increases it by one, going to the next host in the class C subnet, after the end of the class C subnet to the next class B subnet, and so on. decip will decrease an IP address in the same way.

rawsock allocates a raw socket of the internet protocol number indicated by protocol (either IP, TCP, or UDP, at SOCK_RAW level), and ensures that the header is included with the data, so it can be used to transmit custom IP datagrams or sniff traffic at IP protocol level.

psock allocates a packet level socket for ethernet/ip packets.

inet_gethostaddr will try to determine your local IP address by resolving your hostname. It returns the address in network byte order, if it succeeds, or 0 on failure. inet_local will try to determine the local IP address on your first external NIC by sending a raw packet and watching its source address. It returns the address in network byte order, if it succeeds, or 0 on failure.

ethsrc and ethdst are functions to set the ethernet MAC source and destination address in an ethernet header. The arguments are a pointer to the beginning of the ethernet header and the MAC address in hexadecimal format ("FF:FF:FF:FF:FF:FF").

lm_timed_read and lm_timed_connect are functions that work exactly like the system read() and write() with the difference of taking an additional parameter for the maximum amount of time that is allowed to pass for each call. Timing is realized using select(), and by temporarily using non-blocking sockets for connect()s.

tfntransmit will use stateless, stealth datagram transmission to send datagrams to a remote host. longip_src may or may not be your own IP address. If you do spoof your IP, the packet might be blocked by network ingress filters. longip_dst is the address of the recipient, which can, for example be found with resolve. For protocol, use 0 for ICMP, 1 for UDP, 2 for TCP, or a value smaller than 0 to make the function pick a random protocol (the protocol doesn't really matter here; its merely a matter of getting the packet routed). data contains the data payload that you want to transmit. It will be encrypted, if you use aes_key to set a password before calling tfntransmit. In that case, a key must also be set before tfnread is called.

tfnread will read one packet at a time. You have to pass this function three open raw sockets, icmpsock, udpsock, and tcpsock. Reading from the sockets returns all packets that have been transmitted over the network since they have been opened. If tfnread finds that the packet it reads was generated by tfntransmit, it will decrypt it, and return the original plaintext back in a dynamically allocated buffer.

 

MISCELLANEOUS FUNCTIONS

LMNEW() and LMDELETE() are macros for allocating and freeing memory blocks, wrapping around malloc(3) / free(3) if using C, or new / delete, if using C++. Their usage is preferred in all LibMix programs. The first argument to LMNEW() is the type, e.g. char, and the second one the size in bytes, e.g. 256. LMDELETE() must be called with the name of the pointer to the variable.

exclude_parse will read a line from the specified input, and parse it as a classless IP address range in CIDR notation into the internal exclude database. excluded is called with a long IP address as argument, and returns 1 if the address matches an excluded range, or 0 if the address should be processed. exclude_list will print all the currently excluded IP address ranges to standard output. exclude_free will free all memory occupied by the linked list holding the exclusion table. It should be used to clear old records, and at the end of every process that used the exclude functions.

getrandom will return a truly-random number between and including low and high. The function handles the initalization and re-initalization of internal random seed, which is feed by the systems random number generator, when necessary.

sighandler will install the specified signal handler for the signals HUP, INT, FPE, BUS, TRAP, IOTRAP, PIPE, TTIN, TTOUT, TERM, and CHLD.

strchop "cuts" a string at the first occurrence of a newline or return character, by inserting a binary zero. strlower scans a string for upper characters and converts all occurrences to lowercase. strnsubst will remove binary zeroes in a string by replacing them with the specified character. strscpy attempts to split the buffer in at the first occurrence of the character specified by the 4th argument c. The first part of the string will be put in the buffer the 2nd argument points to, and if the 3rd argument is non-null, the second part, which is the rest of the buffer, will be copied there.

pattern works like strstr(3), except that it compares the string needle with an array haystack, which can be useful to skim through a list or configuration database, searching for a specific string. It returns 1 when the pattern was found in haystack.

log can be used to quickly log anything into a file. The first argument is the filename, which, if it can be opened and written to, will be written to. The function uses stdarg(3) and can be used in the same way as functions like sprintf. fatal will print an error message of variable length and terminate the current program. disguise tries to change the name of the current process by copying the first argument over argv[0]. Note that this technique will not work on Solaris. isactive will write the current process id into the specified file. Further calls of the function with the same filename will determine if a previous process is still active and return zero instead of saving their own process id. nstrdup acts like strdup(), but returns a buffer allocated by the C++ expression 'new' instead of malloc(), which is freed with 'delete' instead of free().

sexecve is a new, easier and more elegant function to do process cloaking. The first arguments are the original argc, argv, and envp of the main() function, respectively. Argument newpath is the full pathname and newexec is only the executable name. sexecve() will return 1 if this is already the cloaked process, or 0 on success (which means the old noncloaked process should exit). IMPORANT: sexecve() programs must be run from the current directory, (e.g. cd /usr/bin ; program), or must be called explicitly with FULL pathname, (e.g. /usr/bin/program).

sexec is a now deprecated function to do process cloaking. The first argument is the full path of the executable you want to run. The second argument is the new path and name that the executable should appear to be running from. The third argument is the new processes' argv0, or the basename of the name of the NEW executable. Further arguments are passed like in an execl call, and should be set to NULL when not needed.

lm_scan_run is a backend function that can be used for scanners or similar applications. It reads IP addresses or hostnames from the input descriptor, and calls the callback function func with each IP address accordingly. The parameter forking, when set to 1, will spawn a child for the whole process, making lm_scan_run return the child pid, and when set to 2, a child is spawned for each function call for each separate IP address. The callback function's interface has to return void and have a single argument, an unsigned int, which will contain the current IP address in network byte order.

ioterm is an asynchronous I/O terminal which connects the descriptors infd and outfd, acting as a pipe and exchanging data between them until one read or write call fails. If encryption is 1, and a key has been set with aes_key, then all data sent to the first descriptor, infd, will be AES encrypted with the current password, and data sent to the second descriptor, outfd, will be decrypted. If both a server and client use this function, they can use it to establish an encryption tunnel.

 

BUGS

tfntransmit and tfnread do not work reliably on some systems. Use the much better tfn2k2transmit and tfn2k2read instead which should work practically everywhere. Crypto algorithms may screw up on some exotic keys. Use lm_keywillwork to make sure your key will never cause this. Please report any unknown bugs you might find to mixter@newyorkoffice.com.

 

AUTHOR

This library was written by
Mixter <mixter@newyorkoffice.com>.


Many thanks to YounGoat and pratap for bug tracking.

See http://mixter.warrior2k.com for possible future updates.


 

Index

NAME
SYNOPSIS
LICENSE
LIBMIX PROTOCOL STRUCTURES
CRYPTOGRAPHIC FUNCTIONS
NETWORK FUNCTIONS (libnet/libpcap)
NETWORK FUNCTIONS
MISCELLANEOUS FUNCTIONS
BUGS
AUTHOR