ฉันจะระบุกระบวนการที่ทำให้การรับส่งข้อมูล UDP บน Linux เป็นอย่างไร


39

เครื่องของฉันกำลังทำการส่งคำขอ udp dns อย่างต่อเนื่อง สิ่งที่ฉันต้องรู้ก็คือ PID ของกระบวนการที่สร้างทราฟฟิกนี้

วิธีปกติในการเชื่อมต่อ TCP คือการใช้ netstat / lsof และรับกระบวนการที่เกี่ยวข้องที่ pid

UDP คือการเชื่อมต่อเป็น stateles ดังนั้นเมื่อฉันโทร netastat / lsof ฉันสามารถดูได้เฉพาะเมื่อซ็อกเก็ต UDP เปิดอยู่และกำลังส่งทราฟฟิก

ฉันได้ลองlsof -i UDPและด้วยnestat -anpueแต่ฉันไม่สามารถหากระบวนการที่จะทำตามคำขอเพราะฉันต้องเรียก lsof / netstat ว่าเมื่อปริมาณการใช้ udp ถูกส่งถ้าฉันเรียก lsof / netstat ก่อน / หลัง udp ดาต้าที่ถูกส่งคือ ไม่สามารถดูซ็อกเก็ต UDP ที่เปิดอยู่

โทร netstat / lsof เมื่อแพ็คเก็ต 3/4 udp ถูกส่งเป็น IMPOSSIBLE

ฉันจะระบุกระบวนการที่น่าอับอายได้อย่างไร ฉันได้ตรวจสอบการรับส่งข้อมูลแล้วเพื่อพยายามระบุ PID ที่ส่งจากเนื้อหาของแพ็คเก็ต แต่ไม่สามารถระบุได้จากการรับส่งข้อมูล

ใครช่วยฉันได้บ้าง

ฉันรูทเครื่องนี้ FEDORA 12 Linux noise.company.lan 2.6.32.16-141.fc12.x86_64 # 1 SMP พุธ 7 ก.ค. 49 04:49:59 UTC 2010 x86_64 x86_64 x86_64 GNU / Linux

คำตอบ:


48

การตรวจสอบ Linux สามารถช่วยได้ อย่างน้อยมันจะค้นหาผู้ใช้และกระบวนการที่ทำการเชื่อมต่อเครือข่ายดาตาแกรม แพ็กเก็ต UDP เป็นดาตาแกรม

ขั้นแรกให้ติดตั้งauditdเฟรมเวิร์กบนแพลตฟอร์มของคุณและตรวจสอบให้แน่ใจว่าauditctl -lส่งคืนบางสิ่งแม้ว่าจะระบุว่าไม่มีการกำหนดกฎ

จากนั้นเพิ่มกฎเพื่อดูการโทรของระบบsocket()และติดแท็กเพื่อให้ค้นหาได้ง่ายในภายหลัง ( -k) ฉันต้องการที่จะคิดว่าคุณจะอยู่บนสถาปัตยกรรม 64 บิต แต่คุณสามารถทดแทนb32ในสถานที่ของb64ถ้าคุณไม่ได้

auditctl -a exit,always -F arch=b64 -F a0=2 -F a1\&=2 -S socket -k SOCKET

คุณต้องเลือก man page และไฟล์ส่วนหัวเพื่อสร้างสิ่งนี้ แต่สิ่งที่จับได้คือการเรียกของระบบ: socket(PF_INET, SOCK_DGRAM|X, Y)โดยที่พารามิเตอร์ที่สามไม่ได้ระบุ แต่บ่อยครั้งเป็นศูนย์ PF_INETคือ 2 และSOCK_DGRAMเป็น 2. การเชื่อมต่อ TCP จะใช้ซึ่งจะตั้งSOCK_STREAM a1=1( SOCK_DGRAMในพารามิเตอร์ที่สองอาจ ORed ด้วยSOCK_NONBLOCKหรือSOCK_CLOEXECดังนั้นจึงเป็นการ&=เปรียบเทียบ) นี่-k SOCKETคือคำหลักของเราที่เราต้องการใช้เมื่อค้นหาหลักฐานการตรวจสอบในภายหลัง มันสามารถเป็นอะไรก็ได้ แต่ฉันชอบที่จะทำให้มันง่าย

ปล่อยให้เวลาผ่านไปสักครู่และทบทวนเส้นทางการตรวจสอบ คุณสามารถบังคับให้แพ็กเก็ตสองสามตัวโดยส่งโฮสต์ออกทางเน็ตซึ่งจะทำให้เกิดการค้นหา DNS ที่จะเกิดขึ้นซึ่งใช้ UDP ซึ่งควรเดินทางไปแจ้งเตือนการตรวจสอบของเรา

ausearch -i -ts today -k SOCKET

และผลลัพธ์ที่คล้ายกับส่วนด้านล่างจะปรากฏขึ้น ฉันย่อมันเพื่อเน้นส่วนที่สำคัญ

type=SYSCALL ... arch=x86_64 syscall=socket success=yes exit=1 a0=2 a1=2 ... pid=14510 ... auid=zlagtime uid=zlagtime ... euid=zlagtime ... comm=ping exe=/usr/bin/ping key=SOCKET

ในผลลัพธ์ข้างต้นเราจะเห็นว่าpingคำสั่งทำให้ซ็อกเก็ตที่จะเปิด ฉันสามารถเรียกใช้strace -p 14510กระบวนการถ้ามันยังคงทำงานอยู่ ppid(รหัสการปกครอง) นอกจากนี้ยังมีการระบุไว้ในกรณีที่มันเป็นสคริปต์ที่ spawns เด็กที่มีปัญหามาก

ตอนนี้ถ้าคุณมีทราฟฟิก UDP จำนวนมากสิ่งนี้จะไม่ดีพอและคุณต้องหันไปใช้OProfileหรือSystemTapซึ่งทั้งสองอย่างนี้อยู่นอกเหนือความเชี่ยวชาญของฉัน

สิ่งนี้จะช่วยให้สิ่งต่าง ๆ แคบลงในกรณีทั่วไป

เมื่อเสร็จแล้วให้ลบกฎการตรวจสอบออกโดยใช้บรรทัดเดียวกับที่คุณใช้ในการสร้างมันขึ้นมาแทนที่-aด้วย-dเท่านั้น

auditctl -d exit,always -F arch=b64 -F a0=2 -F a1\&=2 -S socket -k SOCKET

ฉันจะลอง แต่ฉันคิดว่าเป็นคำตอบที่ถูกต้อง
boos

นี่ไม่ใช่การรับส่งข้อมูลที่ถูกทิ้งโดย iptables อย่างน้อยสำหรับฉัน
2rs2ts

1
+1 สำหรับความเรียบง่ายเมื่อเทียบกับวิธีการ systemtap (ซึ่งเป็นการวิเคราะห์มากขึ้น แต่ความต้องการของเคอร์เนลแพคเกจ devel)
basos

23

คุณสามารถใช้ netstat แต่คุณต้องการแฟล็กที่ถูกต้องและใช้งานได้ก็ต่อเมื่อกระบวนการที่ส่งข้อมูลยังมีชีวิตอยู่ มันจะไม่พบร่องรอยของสิ่งที่มาชั่วชีวิตส่งการจราจร UDP จากนั้นก็หายไป นอกจากนี้ยังต้องใช้สิทธิ์รูทท้องถิ่น ที่กล่าวว่า:

ที่นี่ฉันเริ่ม ncat บนโฮสต์ในพื้นที่ของฉันส่งการรับส่งข้อมูล UDP ไปยังพอร์ต 2345 บนเครื่อง (ไม่มีอยู่จริง) 10.11.12.13:

[madhatta@risby]$ ncat -u 10.11.12.13 2345 < /dev/urandom

นี่คือเอาต์พุต tcpdump ที่พิสูจน์ว่าทราฟฟิกกำลังดำเนินการ:

[root@risby ~]# tcpdump -n -n port 2345
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
12:41:32.391750 IP 192.168.3.11.57550 > 10.11.12.13.2345: UDP, length 8192
12:41:32.399723 IP 192.168.3.11.57550 > 10.11.12.13.2345: UDP, length 8192
12:41:32.401817 IP 192.168.3.11.57550 > 10.11.12.13.2345: UDP, length 8192
12:41:32.407051 IP 192.168.3.11.57550 > 10.11.12.13.2345: UDP, length 8192
12:41:32.413492 IP 192.168.3.11.57550 > 10.11.12.13.2345: UDP, length 8192
12:41:32.417417 IP 192.168.3.11.57550 > 10.11.12.13.2345: UDP, length 8192

นี่คือบิตที่มีประโยชน์โดยใช้ netstat พร้อมกับแฟล็ก -a (เพื่อดูรายละเอียดพอร์ต) และแฟล็ก -p เพื่อดูรายละเอียด ID กระบวนการ เป็นแฟล็ก -p ที่ต้องใช้สิทธิ์รูท:

[root@risby ~]# netstat -apn|grep -w 2345
udp        0      0 192.168.3.11:57550          10.11.12.13:2345            ESTABLISHED 9152/ncat     

อย่างที่คุณเห็น pid 9152 ใช้นิ้วสัมผัสว่าเปิดการเชื่อมต่อกับพอร์ต 2345 บนรีโมตโฮสต์ที่ระบุ Netstat ให้ความช่วยเหลือในการดำเนินการผ่าน ps และบอกชื่อกระบวนการให้ฉันncatทราบ

หวังว่าจะเป็นประโยชน์


ทำได้ดีมากจริงๆ! : thumbup:
ThorstenS

2
แม้ว่าจะมีการจับ หากปัญหาเกิดจากเชลล์สคริปต์ทำการวางโพรซีเดอร์ย่อยที่ค้นหา DNS และกระบวนการนั้นออกอย่างรวดเร็วพอร์ตต้นทาง (57550 ด้านบน) จะเปลี่ยนตลอดเวลา ในกรณีนี้เทคนิคจะไม่ทำงานและคุณจะต้องใช้มาตรการรุนแรงมากขึ้น นอกจากนี้ netstat ของคุณควรทำgrep -w 57550เพราะกระบวนการหลายกระบวนการสามารถทำการค้นหา DNS ไปยังเซิร์ฟเวอร์เดียวกัน วิธีการของคุณจะไม่แยกพวกเขา
zerolagtime

1
ฉันเห็นด้วยกับการคัดค้านของคุณทั้งสอง zerolagtime (แต่ขอบคุณสำหรับคำพูดของคุณต่อไป ThorstenS!)
MadHatter รองรับโมนิก้า

17

ฉันมีปัญหาเดียวกันทั้งหมดและโชคauditdไม่ดีสำหรับฉัน

ฉันมีอัตราการเข้าชมจากบางส่วนของเซิร์ฟเวอร์ของฉันมุ่งหน้าไปยังที่อยู่ของ Google DNS, และ8.8.8.8 8.8.4.4ตอนนี้ผู้ดูแลระบบเครือข่ายของฉันมี OCD เล็กน้อยและเขาต้องการทำความสะอาดทราฟฟิกที่ไม่จำเป็นทั้งหมดเนื่องจากเรามีแคช DNS ภายในของเรา เขาต้องการปิดการใช้งานพอร์ตขาออก 53 สำหรับทุกคนยกเว้นเซิร์ฟเวอร์แคชเหล่านั้น

ดังนั้นหลังจากล้มเหลวกับฉันขุดลงไปในauditctl systemtapฉันมากับสคริปต์ต่อไปนี้:

# cat >> udp_detect_domain.stp <<EOF
probe udp.sendmsg {
  if ( dport == 53 && daddr == "8.8.8.8" ) {
    printf ("PID %5d (%s) sent UDP to %15s 53\n", pid(), execname(), daddr)
  }
}
EOF

จากนั้นเรียกใช้:

stap -v udp_detect_domain.stp

นี่คือผลลัพธ์ที่ฉันได้รับ:

PID  3501 (python) sent UDP to  8.8.8.8 53
PID  3501 (python) sent UDP to  8.8.8.8 53
PID  3506 (python) sent UDP to  8.8.8.8 53

แค่นั้นแหละ! หลังจากเปลี่ยนresolv.confPID เหล่านั้นไม่ได้รับการเปลี่ยนแปลง


หวังว่าจะช่วย :)


5

นี่คือตัวเลือก systemtap โดยใช้โพรบ netfilter ที่มีอยู่ใน stap verson 1.8 และใหม่กว่า man probe::netfilter.ip.local_outดูเพิ่มเติม

# stap -e 'probe netfilter.ip.local_out {
  if (dport == 53) # or parametrize
      printf("%s[%d] %s:%d\n", execname(), pid(), daddr, dport)
}'
ping[24738] 192.168.1.10:53
ping[24738] 192.168.1.10:53
^C

4

ฉันจะใช้ net-sniffer เช่น tcpdump หรือ wireshark เพื่อดูคำขอ DNS เนื้อหาของแบบสอบถามสามารถให้แนวคิดว่าโปรแกรมกำลังออกอะไร


ไม่มีข้อมูลในปริมาณข้อมูลที่ฉันเพิ่งดู
boos

ไม่มีข้อมูล? แพ็กเก็ตว่างเปล่า สิ่งที่ฉันหมายถึงคือหากมีสิ่งใดที่พยายามแก้ไข updates.java.sun.com หรือ rss.cnn.com คุณอาจใช้บางอย่างที่เป็นประโยชน์จากมัน
RedGrittyBrick

แบบสอบถาม DNS ค้นหาพร็อกซีภายใน ตอนนี้ฉันพบกระบวนการที่หลากหลาย แต่คำถามยังมีชีวิตอยู่สำหรับเทคนิคการแก้ปัญหาทั่วไป
boos

lsof -i | awk '/ UDP /'
c4f4t0r

3

โปรดทราบว่าเมื่อใช้ autitctl ตัวอย่างเช่น nscd ใช้พารามิเตอร์ที่แตกต่างกันเล็กน้อยในการเรียกระบบซ็อกเก็ตเมื่อทำการสอบถาม DNS:

socket(AF_INET, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_IP)

ดังนั้นเพื่อให้แน่ใจว่าคุณได้รับแบบสอบถามเหล่านี้นอกเหนือจากที่กล่าวถึงข้างต้นคุณสามารถเพิ่มตัวกรองเพิ่มเติมโดยใช้ชื่อเดียวกันหากคุณต้องการ:

auditctl -a exit,always -F arch=b64 -F a0=2  -F a1=2050 -S socket -k SOCKET

ที่นี่ 2050 เป็นค่าบิตหรือของSOCK_DGRAM (2) และSOCK_NONBLOCK (2048)

จากนั้นการค้นหาจะค้นหาตัวกรองทั้งสองที่มีคีย์เดียวกันSOCKET:

ausearch -i -ts today -k SOCKET

ค่าฐานสิบหกสำหรับค่าคงที่ซ็อกเก็ตที่ฉันพบได้ที่นี่: https://golang.org/pkg/syscall/#pkg-constants

เนื่องจากฉันไม่มีคะแนนชื่อเสียงให้แสดงความคิดเห็นฉันเพิ่มสิ่งนี้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.