SHARE
TWEET

Untitled

a guest Mar 8th, 2017 80 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/types.h>
  4. #include <sys/socket.h>
  5. #include <netinet/in.h>
  6. #include <dlfcn.h>
  7. #include <errno.h>
  8. #include <arpa/inet.h>
  9.  
  10.  
  11. int debug_enabled = 1 ;
  12.  
  13. int (*real_bind)(int, const struct sockaddr *, socklen_t);
  14. int (*real_connect)(int, const struct sockaddr *, socklen_t);
  15.  
  16. uint32_t bind_addr_saddr = 0;
  17. struct sockaddr_in local_sockaddr_in[] = { 0 };
  18.  
  19. unsigned int bind_port_saddr = 0;
  20. unsigned int reuse_port = 0;
  21. unsigned int reuse_addr = 0;
  22. unsigned int ip_transparent = 0;
  23.  
  24. void _init (void){
  25.     const char *err;
  26.  
  27.     real_bind = dlsym (RTLD_NEXT, "bind");
  28.     if ((err = dlerror ()) != NULL) {
  29.         fprintf (stderr, "dlsym (bind): %s\n", err);
  30.     }
  31.  
  32.     real_connect = dlsym (RTLD_NEXT, "connect");
  33.     if ((err = dlerror ()) != NULL) {
  34.         fprintf (stderr, "dlsym (connect): %s\n", err);
  35.     }
  36.  
  37.     char *bind_addr_env;
  38.     if ((bind_addr_env = getenv ("BIND_ADDR"))) {
  39.         bind_addr_saddr = inet_addr (bind_addr_env);
  40.         local_sockaddr_in->sin_family = AF_INET;
  41.         local_sockaddr_in->sin_addr.s_addr = bind_addr_saddr;
  42.         local_sockaddr_in->sin_port = htons (0);
  43.     }
  44.  
  45.     char *bind_port_env;
  46.     if ((bind_port_env = getenv ("BIND_PORT"))) {
  47.         bind_port_saddr = atoi(bind_port_env);
  48.         local_sockaddr_in->sin_port = htons (bind_port_saddr);
  49.     }
  50.  
  51.     char *reuse_addr_env;
  52.     if ((reuse_addr_env = getenv ("REUSE_ADDR"))) {
  53.         reuse_addr = atoi(reuse_addr_env);
  54.     }
  55.  
  56.     char *reuse_port_env;
  57.     if ((reuse_port_env = getenv ("REUSE_PORT"))) {
  58.         reuse_port = atoi(reuse_port_env);
  59.     }
  60.  
  61.     char *ip_transparent_env;
  62.     if ((ip_transparent_env = getenv ("IP_TRANSPARENT"))) {
  63.         ip_transparent = atoi(ip_transparent_env);
  64.     }
  65. }
  66.  
  67. unsigned short get_address_family(const struct sockaddr *sk){
  68.     /*
  69.         As defined in linux/socket.h ,__kernel_sa_family_t is 2 bytes wide.
  70.         We read the first two bytes of sk without using cast to protocol families
  71.    
  72.     */
  73.     unsigned short _pf = *((unsigned short*) sk);
  74.     return _pf;
  75. }
  76.  
  77.  
  78. int bind (int fd, const struct sockaddr *sk, socklen_t sl){
  79.    
  80.        
  81.     unsigned short _pf = get_address_family(sk);
  82.     switch (_pf){
  83.     case AF_INET:
  84.     {
  85.         static struct sockaddr_in *lsk_in;
  86.  
  87.         lsk_in = (struct sockaddr_in *)sk;
  88.        
  89.         if (debug_enabled){
  90.             char original_ip [INET_ADDRSTRLEN];
  91.             inet_ntop(AF_INET,&(lsk_in->sin_addr),original_ip,INET_ADDRSTRLEN);
  92.             int original_port = ntohs(lsk_in->sin_port);
  93.             char *l_bind_addr = getenv ("BIND_ADDR");
  94.             char *l_bind_port = getenv ("BIND_PORT");
  95.             printf("[-] LIB received AF_INET bind request\n");
  96.             if (l_bind_addr && l_bind_port){                    
  97.                 printf("[-] Changing %s:%d to %s:%s\n" , original_ip,original_port,l_bind_addr,l_bind_port);      
  98.             }else if (l_bind_addr){
  99.                 printf("[-] Changing %s to %s\n" , original_ip,l_bind_addr);
  100.                 printf("[-] AF_INET: Leaving port unchanged\n");
  101.            
  102.             }else if (l_bind_port){
  103.                 printf("[-] Changing %d to %s\n" ,original_port,l_bind_port);
  104.                 printf("[-] AF_INET: Leaving ip unchanged\n");
  105.            
  106.             }
  107.             else{            
  108.                 printf("[!] AF_INET: Leaving request unchanged\n");
  109.             }      
  110.         }
  111.        
  112.  
  113.         if(bind_addr_saddr)
  114.             lsk_in->sin_addr.s_addr = bind_addr_saddr;
  115.  
  116.         if (bind_port_saddr)
  117.             lsk_in->sin_port = htons (bind_port_saddr);
  118.        
  119.         break;
  120.        
  121.     }
  122.        
  123.     case AF_UNIX:
  124.         if (debug_enabled){
  125.             printf("[-] LIB received AF_UNIX bind request\n");
  126.             printf("[-] AF_UNIX: Leaving request unchanged\n");
  127.         }
  128.         break;
  129.        
  130.     /*
  131.         Other families handling
  132.        
  133.     */
  134.    
  135.     default:
  136.         if (debug_enabled){
  137.             printf("[!] LIB received unmanaged address family\n");
  138.         }
  139.         break;
  140.  
  141.     }
  142.  
  143.    
  144.    
  145.     /*
  146.         FIXME: Be careful when using setsockopt  
  147.         Is it valid to use these options for AF_UNIX?
  148.         Must be checked
  149.    
  150.     */
  151.     if (reuse_addr){
  152.         setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse_addr, sizeof(reuse_addr));
  153.     }
  154.  
  155. #ifdef SO_REUSEPORT
  156.     if (reuse_port){
  157.         setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &reuse_port, sizeof(reuse_port));
  158.     }
  159. #endif
  160.  
  161.     if (ip_transparent){
  162.         int opt =1;
  163.         setsockopt(fd, SOL_IP, IP_TRANSPARENT, &ip_transparent, sizeof(ip_transparent));
  164.     }
  165.  
  166.     return real_bind (fd, sk, sl);
  167. }
  168.  
  169. int connect (int fd, const struct sockaddr *sk, socklen_t sl){
  170.     unsigned short _pf = get_address_family(sk);
  171.     if (_pf == AF_INET){
  172.         /*
  173.             FIXME: connect function's logic does not make sense.
  174.             it binds the local socket to the same address to which it calls real_connect to connect to.
  175.             In other words it connects to itself (why?)
  176.             to make things less weird I changed the code to only does it's strange task for AF_INET
  177.            
  178.         */
  179.         if (debug_enabled){
  180.             printf("[!] connect(): AF_INET connect() call\n");
  181.         }
  182.         static struct sockaddr_in *rsk_in;
  183.  
  184.         rsk_in = (struct sockaddr_in *)sk;
  185.  
  186.         if ((rsk_in->sin_family == AF_INET) && (bind_addr_saddr || bind_port_saddr)) {
  187.             bind (fd, sk, sizeof (struct sockaddr));
  188.         }
  189.         return real_connect (fd, (struct sockaddr *)local_sockaddr_in, sl);
  190.     }
  191.     else {
  192.         if (debug_enabled){
  193.             printf("[-] connect(): ignoring to change local address for non AF_INET socket\n");
  194.         }
  195.         return real_connect (fd, sk, sl);
  196.        
  197.     }
  198.    
  199.    
  200. }
  201.  
  202. int main(int argc,char **argv){
  203.     return 0;
  204. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top