№ 11 Сетевая аномалия Рекомендуемые утилиты: Wires...

تم الإنشاء في: ٢٤ أكتوبر ٢٠٢٥

تمت الإجابة باستخدام GPT-5 Thinking بواسطة Chat01

سؤال

traffic_9_4.pcapng

№ 11
Сетевая аномалия
Рекомендуемые утилиты: Wireshark
Файл: traffic 9 4.pcapng
Товарищ, в наших информационных сетях обнаружена аномалия. Кажется, кто-то атакует внутренние сервисы. Требуется срочное расследование и анализ ситуации. Исследуйте запись трафика и опишите атаку.
Какой тип атаки был применён?
Выбрать
Определите IP-адрес атакующего.
Ответ
Какой программой, вероятно, пользовался атакующий для доступа к сайту? В ответ запишите только название, без версии.
Ответ

Python

python
import os, glob, pprint, json, pathlib, sys print(os.listdir('/mnt/data'))

Python

python
import pkgutil, sys 'pyshark' in [m.name for m in pkgutil.iter_modules()], 'scapy' in [m.name for m in pkgutil.iter_modules()], 'dpkt' in [m.name for m in pkgutil.iter_modules()], 'pcapng' in [m.name for m in pkgutil.iter_modules()] (False, False, False, False)

Python

python
import re, os, codecs p = '/mnt/data/traffic_9_4.pcapng' data = open(p, 'rb').read() # Extract ASCII strings of reasonable length def strings(buf, min_len=4): out=[] cur=[] for b in buf: if 32 <= b <= 126: cur.append(chr(b)) else: if len(cur)>=min_len: out.append(''.join(cur)) cur=[] if len(cur)>=min_len: out.append(''.join(cur)) return out s = strings(data, 4) len(s), s[:20] (57, ['Sanitized by TraceWrangler v0.6.8 build 974', 'Sanitized by TraceWrangler v0.6.8 build 974', 'eth0', 'Linux 6.6.65-1-MANJARO', '/GET /get_secret?username=admin&password=1234567 HTTP/1.1', 'Host: 192.168.122.79', 'User-Agent: curl/8.5.0', 'Accept: */*', '4n*@', '~HTTP/1.1 401 UNAUTHORIZED', 'Server: Werkzeug/3.1.3 Python/3.12.8', 'Date: Thu, 23 Jan 2025 16:47:35 GMT', 'Content-Type: text/html; charset=utf-8', 'Content-Length: 12', 'Connection: close', '@n,@', 'Unauthorized', '4n-@', 'GET /get_secret?username=admin&password=12345678 HTTP/1.1', 'Host: 192.168.122.79'])

Python

python
import re ips = set() for st in s: for m in re.findall(r'(?:\d{1,3}\.){3}\d{1,3}', st): ips.add(m) ips {'192.168.122.79'}

Python

python
def iter_pcapng_packets(path): data = open(path, 'rb').read() off=0 src={} packets=[] while off+8 <= len(data): block_type, block_len = struct.unpack_from('<II', data, off) if block_len==0: break block = data[off:off+block_len] # EPB if block_type == 0x00000006 and block_len >= 32: # fields: type, len, iface_id, ts_high, ts_low, cap_len, pkt_len, pkt_data... iface_id, ts_high, ts_low, cap_len, pkt_len = struct.unpack_from('<IIIII', block, 8) pkt_data = block[28:28+cap_len] packets.append(pkt_data) off += block_len return packets packets = iter_pcapng_packets 53

Python

python
from collections import Counter, defaultdict def parse_ipv4_from_eth(frame): if len(frame) < 14: return None eth_type = struct.unpack('!H', frame[12:14])[0] if eth_type != 0x0800: return None ip = frame[14:] if len(ip) < 20: return None ver_ihl = ip[0] ihl = (ver_ihl & 0x0F)*4 if ihl < 20 or len(ip) < ihl: return None proto = ip[9] src = socket.inet_ntoa(ip[12:16]) dst = socket.inet_ntoa(ip[16:20]) payload = ip[ihl:] return {'src':src,'dst':dst,'proto':proto,'payload':payload, 'ip_header_len':ihl} def parse_tcp_segments(frame): parsed = parse_ipv4_from_eth(frame) if not parsed or parsed['proto'] != 6: return None payload = parsed['payload'] if len(payload) < 20: return None src_port, dst_port, seq, ack, offset_reserved_flags = struct.unpack('!HHIIH', payload[:14]) offset = ((offset_reserved_flags >> 12) & 0xF) * 4 if len(payload) < offset: return None tcp_payload = payload[offset:] flags = offset_reserved_flags & 0x01FF # last 9 bits return {**parsed, 'src_port':src_port,'dst_port':dst_port,'tcp_payload':tcp_payload,'flags':flags} ip_counts = Counter() src_dsts = Counter() http_texts=[] flows=defaultdict(list) for pkt in packets: t = parse_tcp_segments(pkt) if t: ip_counts[t['src']] += 1 src_dsts[(t['src'], t['dst'], t['dst_port'])] += 1 if t['tcp_payload']: # collect printable payloads try: text = t['tcp_payload'].decode('iso-8859-1', errors='ignore') except: text = '' if text: http_texts.append(text[:120]) flows[(t['src'], t['src_port'], t['dst'], t['dst_port'])].append(t) len(ip_counts), list(ip_counts.items())[:5], len(http_texts) (3, [('192.168.122.20', 21), ('192.168.122.79', 20), ('192.168.122.103', 7)], 12)

Python

python
# Summarize dst ports from collections import Counter dst_port_counts = Counter() for pkt in packets: t = parse_tcp_segments(pkt) if t: dst_port_counts[t['dst_port']] += 1 dst_port_counts Counter({80: 28, 58490: 5, 58500: 5, 44226: 5, 38928: 5})

Python

python
sorted([k for k,v in src_dsts.items() if k[2]==80], key=lambda x: (x[0],x[1],x[2])) [('192.168.122.103', '192.168.122.79', 80), ('192.168.122.20', '192.168.122.79', 80)]

Python

python
import re reqs=[] for pkt in packets: t = parse_tcp_segments(pkt) if not t: continue pl = t['tcp_payload'] if not pl: continue text = pl.decode('iso-8859-1', errors='ignore') if text.startswith('GET ') or text.startswith('POST ') or 'HTTP/1.1' in text: reqs.append((t['src'], t['src_port'], t['dst'], t['dst_port'], text[:200].replace('\r','').replace('\n',' | '))) len(reqs), reqs[:5] (8, [('192.168.122.20', 58490, '192.168.122.79', 80, 'GET /get_secret?username=admin&password=1234567 HTTP/1.1 | Host: 192.168.122.79 | User-Agent: curl/8.5.0 | Accept: */* | | '), ('192.168.122.79', 80, '192.168.122.20', 58490, 'HTTP/1.1 401 UNAUTHORIZED | Server: Werkzeug/3.1.3 Python/3.12.8 | Date: Thu, 23 Jan 2025 16:47:35 GMT | Content-Type: text/html; charset=utf-8 | Content-Length: 12 | Connection: close | | '), ('192.168.122.20', 58500, '192.168.122.79', 80, 'GET /get_secret?username=admin&password=12345678 HTTP/1.1 | Host: 192.168.122.79 | User-Agent: curl/8.5.0 | Accept: */* | | '), ('192.168.122.79', 80, '192.168.122.20', 58500, 'HTTP/1.1 200 OK | Server: Werkzeug/3.1.3 Python/3.12.8 | Date: Thu, 23 Jan 2025 16:47:37 GMT | Content-Type: text/html; charset=utf-8 | Content-Length: 19 | Connection: close | | '), ('192.168.122.103', 44226, '192.168.122.79', 80, "GET /get_secret?username='%20OR%201=1--&password= HTTP/1.1 | Host: 192.168.122.79 | User-Agent: curl/8.9.1 | Accept: */* | | ")])

Python

python
for entry in reqs: print(entry[0], '->', entry[2], entry[3], '|', entry[4])

Python

python
for e in reqs: if e[0]=='192.168.122.103': print(e[4])

الفكرة

Guiding the user

I’ve established that the attack is likely SQL injection and the program used is curl. Now, I need to guide the user step-by-step, instead of just giving the answer. I'll start by confirming the task goal: finding the attack type, attacker's IP, and the program used. I'll ask if they are comfortable with Wireshark and whether they’re a beginner or experienced, but only one question at a time.

Planning the approach

I see a conflict between following the "study mode" guidelines and the "Critical requirement". The solution seems to be guiding through a step-by-step process, without giving direct answers. I’ll start by asking one quick question to gauge their Wireshark experience. After that, we’ll proceed with analyzing the HTTP requests and suspicious IP addresses together.

Planning next steps

I’ll start by getting the user to filter HTTP traffic in Wireshark, then ask them to identify suspicious patterns in the URL path, specifically looking for characters like ' or OR 1=1--. I'll make it clear that I can verify the file alongside their findings without promising future checks. One question at a time, of course!

Crafting the plan

I’ll first greet the user, then quickly guide them through the steps without giving the full answer. I’ll ask them to apply a filter in Wireshark and focus on the URL’s suspicious patterns, specifically looking for unusual characters in parameters. I'll use the phrase "Уровень?" to gauge their familiarity before diving in—just one question at a time.

Thought for 2m 31s

الإجابة

Отлично, давай разберём это как аналитик по сетям — шаг за шагом.

Шаг 1 (5 минут): открой pcap в Wireshark и вбей фильтр http.request (или tcp.port == 80, если удобней).
Прокликай верхние несколько запросов и посмотри на строку GET и заголовки.

Вопрос: какой URL сразу выглядит подозрительно? Скопируй сюда полную строку GET ... из самого «странного» запроса.

مشاركة هذا السؤال والجواب