SHARE
TWEET

Untitled

a guest Mar 8th, 2017 60 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <sys/types.h>
  6. #include <sys/socket.h>
  7. #include <netinet/in.h>
  8. #include <dlfcn.h>
  9. #include <errno.h>
  10. #include <arpa/inet.h>
  11.  
  12.  
  13. int debug_enabled = 1 ;
  14.  
  15. int (*real_bind)(int, const struct sockaddr *, socklen_t);
  16. int (*real_connect)(int, const struct sockaddr *, socklen_t);
  17.  
  18. uint32_t bind_addr_saddr = 0;
  19. struct sockaddr_in local_sockaddr_in[] = { 0 };
  20.  
  21. unsigned int bind_port_saddr = 0;
  22. unsigned int reuse_port = 0;
  23. unsigned int reuse_addr = 0;
  24. unsigned int ip_transparent = 0;
  25.  
  26. void _init (void){
  27.     const char *err;
  28.  
  29.     real_bind = dlsym (RTLD_NEXT, "bind");
  30.     if ((err = dlerror ()) != NULL) {
  31.         fprintf (stderr, "dlsym (bind): %s\n", err);
  32.     }
  33.  
  34.     real_connect = dlsym (RTLD_NEXT, "connect");
  35.     if ((err = dlerror ()) != NULL) {
  36.         fprintf (stderr, "dlsym (connect): %s\n", err);
  37.     }
  38.  
  39.     char *bind_addr_env;
  40.     if ((bind_addr_env = getenv ("BIND_ADDR"))) {
  41.         bind_addr_saddr = inet_addr (bind_addr_env);
  42.         local_sockaddr_in->sin_family = AF_INET;
  43.         local_sockaddr_in->sin_addr.s_addr = bind_addr_saddr;
  44.         local_sockaddr_in->sin_port = htons (0);
  45.     }
  46.  
  47.     char *bind_port_env;
  48.     if ((bind_port_env = getenv ("BIND_PORT"))) {
  49.         bind_port_saddr = atoi(bind_port_env);
  50.         local_sockaddr_in->sin_port = htons (bind_port_saddr);
  51.     }
  52.  
  53.     char *reuse_addr_env;
  54.     if ((reuse_addr_env = getenv ("REUSE_ADDR"))) {
  55.         reuse_addr = atoi(reuse_addr_env);
  56.     }
  57.  
  58.     char *reuse_port_env;
  59.     if ((reuse_port_env = getenv ("REUSE_PORT"))) {
  60.         reuse_port = atoi(reuse_port_env);
  61.     }
  62.  
  63.     char *ip_transparent_env;
  64.     if ((ip_transparent_env = getenv ("IP_TRANSPARENT"))) {
  65.         ip_transparent = atoi(ip_transparent_env);
  66.     }
  67. }
  68.  
  69. unsigned short get_address_family(const struct sockaddr *sk){
  70.     /*
  71.         As defined in linux/socket.h ,__kernel_sa_family_t is 2 bytes wide.
  72.         We read the first two bytes of sk without using cast to protocol families
  73.    
  74.     */
  75.     unsigned short _pf = *((unsigned short*) sk);
  76.     return _pf;
  77. }
  78.  
  79.  
  80. int bind (int fd, const struct sockaddr *sk, socklen_t sl){
  81.    
  82.        
  83.     unsigned short _pf = get_address_family(sk);
  84.     switch (_pf){
  85.     case AF_INET:
  86.     {
  87.         static struct sockaddr_in *lsk_in;
  88.  
  89.         lsk_in = (struct sockaddr_in *)sk;
  90.        
  91.         if (debug_enabled){
  92.             char original_ip [INET_ADDRSTRLEN];
  93.             inet_ntop(AF_INET,&(lsk_in->sin_addr),original_ip,INET_ADDRSTRLEN);
  94.             int original_port = ntohs(lsk_in->sin_port);
  95.             char *l_bind_addr = getenv ("BIND_ADDR");
  96.             char *l_bind_port = getenv ("BIND_PORT");
  97.             printf("[-] LIB received AF_INET bind request\n");
  98.             if (l_bind_addr && l_bind_port){                    
  99.                 printf("[-] Changing %s:%d to %s:%s\n" , original_ip,original_port,l_bind_addr,l_bind_port);      
  100.             }else if (l_bind_addr){
  101.                 printf("[-] Changing %s to %s\n" , original_ip,l_bind_addr);
  102.                 printf("[-] AF_INET: Leaving port unchanged\n");
  103.            
  104.             }else if (l_bind_port){
  105.                 printf("[-] Changing %d to %s\n" ,original_port,l_bind_port);
  106.                 printf("[-] AF_INET: Leaving ip unchanged\n");
  107.            
  108.             }
  109.             else{            
  110.                 printf("[!] AF_INET: Leaving request unchanged\n");
  111.             }      
  112.         }
  113.        
  114.  
  115.         if(bind_addr_saddr)
  116.             lsk_in->sin_addr.s_addr = bind_addr_saddr;
  117.  
  118.         if (bind_port_saddr)
  119.             lsk_in->sin_port = htons (bind_port_saddr);
  120.        
  121.         break;
  122.        
  123.     }
  124.        
  125.     case AF_UNIX:
  126.         if (debug_enabled){
  127.             printf("[-] LIB received AF_UNIX bind request\n");
  128.             printf("[-] AF_UNIX: Leaving request unchanged\n");
  129.         }
  130.         break;
  131.        
  132.     /*
  133.         Other families handling
  134.        
  135.     */
  136.    
  137.     default:
  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.         static struct sockaddr_in *rsk_in;
  180.  
  181.         rsk_in = (struct sockaddr_in *)sk;
  182.  
  183.         if ((rsk_in->sin_family == AF_INET) && (bind_addr_saddr || bind_port_saddr)) {
  184.             bind (fd, sk, sizeof (struct sockaddr));
  185.         }
  186.         return real_connect (fd, (struct sockaddr *)local_sockaddr_in, sl);
  187.     }
  188.     else {
  189.         if (debug_enabled){
  190.             printf("[-] connect(): ignoring to change local address for non AF_INET socket\n");
  191.         }
  192.         return real_connect (fd, sk, sl);
  193.        
  194.     }
  195.    
  196.    
  197. }
  198.  
  199. int main(int argc,char **argv){
  200.     return 0;
  201. }
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