2012-12-24 14 views
5

według http://kernelnewbies.org/Linux_3.0#head-c5bcc118ee946645132a834a716ef0d7d05b282e możemy teraz ping jako użytkownik nieuprzywilejowany i mogę rodzaju zmusić go do pracy.pyton z nieuprzywilejowany ping w Linuksie IPPROTO_ICMP

pomocą https://github.com/jedie/python-ping I zmodyfikowaną linię 210 wyglądać

current_socket = socket.socket (socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_ICMP)

root I „echa 1000 1000>/Proc/sys/net/ipv4/ping_group_range”

moja grupa jest 1000

i mogę uruchomić ping.py jak ja jako zwykły użytkownik, widzę echo echo żądania i odpowiedzi w tcpdump

18:33:24.840291 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto ICMP (1), length 269) 
    127.0.0.1 > 127.0.0.1: ICMP echo request, id 38, seq 0, length 249 
18:33:24.840309 IP (tos 0x0, ttl 64, id 37939, offset 0, flags [none], proto ICMP (1), length 269) 
    127.0.0.1 > 127.0.0.1: ICMP echo reply, id 38, seq 0, length 249 

ale ping.py nie widzi odpowiedzi i mówi limitu czasu.

Jakieś pomysły, jak to działa?

edit:

mi zawężenie problemu.

print "c", icmp_header, address, self.own_id 
if icmp_header["packet_id"] == self.own_id: # Our packet 

problem jest icmp_header [ "packet_id"] jest zawsze 8247 i self.own_id jest PID ping.py. 8247 to 2037 na heksie, co widzę dość długo na wysypisku.

Jest to pełny zrzut ping na drucie

19:25:15.513285 00:00:00:00:00:00 > 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 283: (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto ICMP (1), length 269) 
    127.0.0.1 > 127.0.0.1: ICMP echo request, id 70, seq 2, length 249 
    0x0000: 4500 010d 0000 4000 4001 3bee 7f00 0001 [email protected]@.;..... 
    0x0010: 7f00 0001 0800 d932 0046 0002 5b36 362c .......2.F..[66, 
    0x0020: 2036 372c 2036 382c 2036 392c 2037 302c .67,.68,.69,.70, 
    0x0030: 2037 312c 2037 322c 2037 332c 2037 342c .71,.72,.73,.74, 
    0x0040: 2037 352c 2037 362c 2037 372c 2037 382c .75,.76,.77,.78, 
    0x0050: 2037 392c 2038 302c 2038 312c 2038 322c .79,.80,.81,.82, 
    0x0060: 2038 332c 2038 342c 2038 352c 2038 362c .83,.84,.85,.86, 
    0x0070: 2038 372c 2038 382c 2038 392c 2039 302c .87,.88,.89,.90, 
    0x0080: 2039 312c 2039 322c 2039 332c 2039 342c .91,.92,.93,.94, 
    0x0090: 2039 352c 2039 362c 2039 372c 2039 382c .95,.96,.97,.98, 
    0x00a0: 2039 392c 2031 3030 2c20 3130 312c 2031 .99,.100,.101,.1 
    0x00b0: 3032 2c20 3130 332c 2031 3034 2c20 3130 02,.103,.104,.10 
    0x00c0: 352c 2031 3036 2c20 3130 372c 2031 3038 5,.106,.107,.108 
    0x00d0: 2c20 3130 392c 2031 3130 2c20 3131 312c ,.109,.110,.111, 
    0x00e0: 2031 3132 2c20 3131 332c 2031 3134 2c20 .112,.113,.114,. 
    0x00f0: 3131 352c 2031 3136 2c20 3131 372c 2031 115,.116,.117,.1 
    0x0100: 3138 2c20 3131 392c 2031 3230 5d   18,.119,.120] 
19:25:15.513300 00:00:00:00:00:00 > 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 283: (tos 0x0, ttl 64, id 37971, offset 0, flags [none], proto ICMP (1), length 269) 
    127.0.0.1 > 127.0.0.1: ICMP echo reply, id 70, seq 2, length 249 
    0x0000: 4500 010d 9453 0000 4001 e79a 7f00 0001 [email protected] 
    0x0010: 7f00 0001 0000 e132 0046 0002 5b36 362c .......2.F..[66, 
    0x0020: 2036 372c 2036 382c 2036 392c 2037 302c .67,.68,.69,.70, 
    0x0030: 2037 312c 2037 322c 2037 332c 2037 342c .71,.72,.73,.74, 
    0x0040: 2037 352c 2037 362c 2037 372c 2037 382c .75,.76,.77,.78, 
    0x0050: 2037 392c 2038 302c 2038 312c 2038 322c .79,.80,.81,.82, 
    0x0060: 2038 332c 2038 342c 2038 352c 2038 362c .83,.84,.85,.86, 
    0x0070: 2038 372c 2038 382c 2038 392c 2039 302c .87,.88,.89,.90, 
    0x0080: 2039 312c 2039 322c 2039 332c 2039 342c .91,.92,.93,.94, 
    0x0090: 2039 352c 2039 362c 2039 372c 2039 382c .95,.96,.97,.98, 
    0x00a0: 2039 392c 2031 3030 2c20 3130 312c 2031 .99,.100,.101,.1 
    0x00b0: 3032 2c20 3130 332c 2031 3034 2c20 3130 02,.103,.104,.10 
    0x00c0: 352c 2031 3036 2c20 3130 372c 2031 3038 5,.106,.107,.108 
    0x00d0: 2c20 3130 392c 2031 3130 2c20 3131 312c ,.109,.110,.111, 
    0x00e0: 2031 3132 2c20 3131 332c 2031 3134 2c20 .112,.113,.114,. 
    0x00f0: 3131 352c 2031 3136 2c20 3131 372c 2031 115,.116,.117,.1 
    0x0100: 3138 2c20 3131 392c 2031 3230 5d   18,.119,.120] 

AFAICT, nagłówek ICMP mogą być pakowane w błędzie. ale to tylko dzikie ukłucie, wpatruję się w to trochę później, w międzyczasie każda pomoc będzie doceniona.

Odpowiedz

3

Są dwie rzeczy, które nie biorą pod uwagę:

  • Po otrzymaniu wiadomości na ten nowy typ gniazda, nagłówek IP nie jest wliczony w cenę. Ponieważ kod modyfikujesz spodziewa się używać gniazd RAW (co nie zawierają nagłówek IP w odebranych wiadomościach), trzeba zmienić sporo rzeczy:
    • linii 306 ekstrakty nagłówka ICMP z packet_data[20:28] ale oczywiście od nagłówek IP nie został uwzględniony, przesunięcie o 20 bajtów nie ma sensu. To musi stać się packet_data[0:8]
    • W linii 310 kod próbuje wyodrębnić nagłówek IP z początku pakietu, ale go nie ma. Tak więc ten kod wyodrębni śmieci. Istnieją dodatkowe opcje, które możesz ustawić, jeśli chcesz poznać takie rzeczy jak TTL (patrz: documentation which accompanies the patch that enabled the functionality).
  • Dzięki tej nowej funkcjonalności jądro kontroluje identyfikator ICMP za pośrednictwem mechanizmu powiązania z gniazdem. Możesz pozwolić jądrowi wybrać ID (niejawne powiązanie) lub ustawić ID (jawne powiązanie). Lepiej jest polegać na niejawnym powiązaniu, ponieważ jądro gwarantuje wybór ID, który jest bezpłatny.

    W linii 309 kod sprawdza, czy odpowiedź należy do nas, sprawdzając identyfikator przed self.own_id.Ale używając niejawnego wiązania jądro wybiera identyfikator dla nas. Możemy ustawić self.own_id z identyfikatorem jądro przypisanego wykorzystaniem

    self.own_id = current_socket.getsockname()[1] 
    

    (umieścić tego prawa po self.send_one_ping on line 221)

    Ale w rzeczywistości sprawdzić przed self.own_id nie jest nawet konieczne, w każdym razie, ponieważ jądro już czyni jasne, że widzimy tylko odpowiedzi, które powinniśmy zobaczyć.

+0

Niesamowite, to bardzo pomogło. "Istnieją dodatkowe opcje, które możesz ustawić, jeśli chcesz poznać takie rzeczy jak TTL (zobacz dokumentację towarzyszącą łatce, która włącza tę funkcję)." Właśnie to utknąłem. – chesty

+0

Tak, to trudne. Aby uzyskać dostęp do systemu pomocniczego, należy użyć wywołania systemowego 'recvmsg' zamiast' recvfrom'. Następnie musisz przeanalizować dane za pomocą całej gamy makr "CMSG", które, jak sądzę, są dostępne tylko w C. [To pytanie] (http://stackoverflow.com/questions/6314982/what-is-recvmsg- odpowiednik w pythonie) potwierdza, że ​​'recvmsg' nie jest dostępny w Pythonie. Zobacz także Python [issue 6560] (http://bugs.python.org/issue6560): wydaje się, że dodanie go nie jest proste. Jednak przynajmniej to wpływa tylko na TTL. Za pomocą 'recvfrom' możesz zrobić wszystko inne. – Celada

+0

OK, dzięki Celada, postawiłeś mnie na właściwej ścieżce, z tego co przeczytałem tutaj http://stackoverflow.com/questions/9237006/getting-ttl-of-incoming-udp-packet-in-python libpcap może być najprostszą opcją. – chesty