{"id":13775552,"url":"https://github.com/wraith-wireless/pyric","last_synced_at":"2026-01-17T09:48:14.411Z","repository":{"id":46462291,"uuid":"58327744","full_name":"wraith-wireless/PyRIC","owner":"wraith-wireless","description":"Python wireless library for Linux","archived":false,"fork":false,"pushed_at":"2022-08-21T09:04:39.000Z","size":4922,"stargazers_count":95,"open_issues_count":27,"forks_count":50,"subscribers_count":7,"default_branch":"master","last_synced_at":"2024-11-11T21:34:19.740Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://wraith-wireless.github.io/PyRIC ","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wraith-wireless.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-05-08T19:30:24.000Z","updated_at":"2024-10-26T06:54:04.000Z","dependencies_parsed_at":"2022-09-09T16:01:47.544Z","dependency_job_id":null,"html_url":"https://github.com/wraith-wireless/PyRIC","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wraith-wireless%2FPyRIC","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wraith-wireless%2FPyRIC/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wraith-wireless%2FPyRIC/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wraith-wireless%2FPyRIC/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wraith-wireless","download_url":"https://codeload.github.com/wraith-wireless/PyRIC/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225027455,"owners_count":17409437,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-03T17:01:41.044Z","updated_at":"2026-01-17T09:48:14.367Z","avatar_url":"https://github.com/wraith-wireless.png","language":"Python","funding_links":[],"categories":["\u003ca id=\"eec238a1a2657b70f7bbbe68a4421249\"\u003e\u003c/a\u003e其他"],"sub_categories":["\u003ca id=\"b239f12aca7aa942b45836032cbef99a\"\u003e\u003c/a\u003e转换"],"readme":"# PyRIC 0.1.6.4: Python Radio Interface Controller\n## Linux wireless library for the Python Wireless Developer and Pentester\n![](docs/logo.png?raw=true)\n\n[![License: GPLv3](https://img.shields.io/pypi/l/PyRIC.svg)](https://github.com/wraith-wireless/PyRIC/blob/master/LICENSE)\n[![PyPI Version](https://img.shields.io/pypi/v/PyRIC.svg)](https://pypi.python.org/pypi/PyRIC)\n![Supported Python Versions](https://img.shields.io/pypi/pyversions/PyRIC.svg)\n![Software status](https://img.shields.io/pypi/status/PyRIC.svg)\n\n## 1 DESCRIPTION:\nPyRIC (is a Linux only) library providing wireless developers and pentesters the\nability to identify, enumerate and manipulate their system's wireless cards\nprogrammatically in Python. Pentesting applications and scripts written in Python\nhave increased dramatically in recent years. However, these tools still rely on\nLinux command lines tools to setup and prepare and restore the system for use.\nUntil now. Why use subprocess.Popen, regular expressions and str.find to interact\nwith your wireless cards? PyRIC is:\n\n1. Pythonic: no ctypes, SWIG etc. PyRIC redefines C header files as Python and\nuses sockets to communicate with the kernel.\n2. Self-sufficient: No third-party files used. PyRIC is completely self-contained.\n3. Fast: (relatively speaking) PyRIC is faster than using command line tools\nthrough subprocess.Popen\n4. Parseless: Get the output you want without parsing output from command line\ntools. Never worry about newer iw versions and having to rewrite your parsers.\n5. Easy: If you can use iw, you can use PyRIC.\n\nAt it's heart, PyRIC is a Python port of (a subset of) iw and by extension, a\nPython port of Netlink w.r.t nl80211 functionality. The original goal of PyRIC\nwas to provide a simple interface to the underlying nl80211 kernel support,\nhandling the complex operations of Netlink seamlessy while maintaining a minimum\nof \"code walking\" to understand, modify and extend. But, why stop there? Since\nit's initial inception, PyRIC has grown. PyRIC puts iw, ifconfig, rfkill,\nudevadm, airmon-ng and macchanger in your hands (or your program).\n\n### a. Additions to iw\nSeveral \"extensions\" have been added to iw (See docs/PyRIC.pdf for more\ninformation):\n* Persistent sockets: pyw provides the caller with functions \u0026 ability to pass\ntheir own netlink (or ioctl socket) to pyw functions;\n* One-time request for the nl80211 family id: pyw stores the family id in a\nglobal variable\n* Consolidate different \"reference\" values to wireless NICs in one class\n(Cards are tuples t=(dev,phy #,ifindex)\n\nThese are minimal changes but they can improve the performance of any progams\nthat needs to access the wireless nic repeatedly as shown in the table below.\n\n| chset      | Total    | Avg    | Longest   | Shortest |\n|------------|----------|--------|-----------|----------|\n| Popen(iw)  | 588.3059 | 0.0588 | 0.0682    | 0.0021   |\n| one-time   | 560.3559 | 0.0560 | 0.0645    | 0.0003   |\n| persistent | 257.8293 | 0.0257 | 0.0354    | 0.0004   |\n\nThe table shows benchmarks for hop time on a Alfa AWUS036NH 10000 times. Note that\nthere is no implication that PyRIC is faster than iw. Rather, the table shows that\nPyRIC is faster than using Popen to execute iw. Using one-time sockets, there is\na difference of 28 seconds over Popen and iw with a small decrease in the average\nhoptime. Not a big difference. However, the performance increased dramatically when\npersistent netlink sockets are used with the total time and average hop time nearly\nhalved.\n\n### b. Current State\nPyRIC is in the process of porting compatibility to Python 3. At present, it will\nwork on Python 2.7 and Python 3.5. It will also work on Python 3.0 except you\nwill have to manually enter your devices in the examples (as argparse is not\nsupported) and you will not be able to run pyw.unittest.py.\n\nATT, PyRIC provides the following:\n* enumerate interfaces and wireless interfaces\n* identify a cards driver, chipset and manufacturer\n* get/set hardware address\n* get/set ip4 address, netmask and or broadcast\n* turn card on/off\n* get supported standards, commands or modes\n* get if info\n* get dev info\n* get phy info\n* get link info\n* get STA (connected AP) info\n* get/set regulatory domain\n* get/set mode\n* get/set coverage class, RTS threshold, Fragmentation threshold \u0026 retry limits\n* add/delete interfaces\n* determine if a card is connected\n* get link info for a connected card\n* enumerate ISM and UNII channels\n* block/unblock rfkill devices\n\nIn utils, several helpers can be found that can be used to:\n* enumerate channels and frequencies and convert between the two\n* manipulate mac addresses and generate random ones\n* fetch and parse the IEEE oui text file\n* further rfkill operations to include listing all rfkill devices\n\nFor a full listing of every function offered by pyw and helpers see the user\nguide PyRIC.pdf.\n\nPyRIC also provides limited help functionality concerning nl80211 commands/attributes\nfor those who wish to add additional commands. However, it pulls directly from\nthe comments nl80211 header file and may be vague.\n\n### c. What is PyRIC?\n\nTo avoid confusion, PyRIC is the system as a whole, including all header files\nand \"libraries\" that are required to communicate with the kernel. pyw is a\ninterface to these libraries providing specific funtions.\n\nWhat it does - defines programmatic access to a subset of iw, ifconfig and rkill.\nIn short, PyRIC provides Python wireless pentesters the ability to work with\nwireless cards directly from Python without having to use command line tools\nthrough Popen.\n\n## 2. INSTALLING/USING:\n\n### a. Requirements\nPyRIC has only two requirements: Linux and Python. There has been very little\ntesting (on my side) on kernel 4.x and Python 3 but unit testing confirms\nfunctionality on Python 2.7 and kernel 3.13.x.\n\n### b. Install from Package Manager\nObviously, the easiest way to install PyRIC is through PyPI:\n\n    sudo pip install PyRIC\n\n### c. Install from Source\nThe PyRIC source (tarball) can be downloaded from https://pypi.python.org/pypi/PyRIC\nor http://wraith-wireless.github.io/PyRIC. Additionally, the source, as a zip file,\ncan be downloaded from https://github.com/wraith-wireless/PyRIC. Once downloaded,\nextract the files and from the PyRIC directory run:\n\n    sudo python setup.py install\n\n### d. Test without Installing\n\nIf you just want to test PyRIC out, download your choice from above. After extraction,\nmove the pyric folder (the package directory) to your location of choice and from\nthere start Python and import pyw. It is very important that you do not try and\nrun it from PyRIC which is the distribution directory. This will break the imports\npyw uses.\n\nYou will only be able to test PyRIC from the pyric directory but, if you want to,\nyou can add it to your Python path and run it from any program or any location.\nTo do so, assume you untared PyRIC to /home/bob/PyRIC. Create a text file named\npyric.pth with one line\n\n    /home/bob/PyRIC\n\nand save this file to /usr/lib/python2.7/dist-packages (or /usr/lib/python3/dist-packages\nif you want to try it in Python 3).\n\n### e. Stability vs Latest\n\nKeep in mind that the most stable version and easist installallation but oldest\nrelease is on PyPI (installed through pip). The source on http://wraith-wireless.github.io/PyRIC tends to be\nnewer but may have some bugs. The most recent source but hardest to install is on\nhttps://github.com/wraith-wireless/pyric/releases/ It is not guaranteed to be stable\n(as I tend to commit changes periodically while working on the code) and may in\nfact not run at all.\n\n## 3. USING\nTo use PyRIC, see the examples folder or read throuhg PyRIC.pdf. However, for\nthose impatient types:\n\n```python\nimport pyric             # pyric errors\nimport pyric.pyw as pyw  # iw functionality\n```\n\nwill import the basic requirements and unless otherwise stated is assumed for the\nexamples below. It is also assumed that the system is in the US and has three\ndevices lo, eth0 and wlan0 (only wlan0 of course being wireless). Keep in mind\nthat these examples use one-time sockets.\n\nAlthough not all functions require root, we assume that the below have been\nexecuted with root permissions.\n\nBefore proceeding with the examples, let's talk about pyric error handling. The\npyric module imports the errorcodes found in the errno module as its own. The \npyric error subclasses EnvironmentError and all pyric errors are tuples of the \nform t = (error code,error message).\n\n```python\n\u003e\u003e\u003e try:\n...     #some pyric code\n... except pyric.error as e:\n...     #handle the error\n```\n\nRead the user guide, or type dir(pyw) in your console to get a full listing\nof all pyw functions.\n\nThe examples below can also be run with named arguments.\n\n### a. System/Wireless Core Functionality\nThese functions do not work with a specific device rather with the system.\n\n```python\n\u003e\u003e\u003e pyw.interfaces() # get all system interfaces\n['lo','eth0','wlan']\n\u003e\u003e\u003e pyw.isinterface('eth0') # deterimine if eth0 is an interface\nTrue\n\u003e\u003e\u003e pyw.isinterface('bob0')\nFalse\n\u003e\u003e\u003e pyw.winterfaces() # get all system wireless interfaces\n['wlan0']\n\u003e\u003e\u003e pyw.isinterface('eth0') # check eth0 for wireless\nFalse\n\u003e\u003e\u003e pyw.iswireless('wlan0')\nTrue\n\u003e\u003e\u003e pyw.phylist() # list all current phys (Note device ASW phy1)\n[(1,'phy1), (0, 'phy0')]\n\u003e\u003e\u003e pyw.regget() # get the regulatory domain\n'US'\n\u003e\u003e\u003e pyw.regset('BO') # set the regulatory domain\nTrue\n\u003e\u003e\u003e pyw.regget()\n'BO'\n\u003e\u003e\u003e\n```\n\n### b. Interface Specific\nRecall that PyRIC utilizes a Card object - this removes the necessity of having\nto remember what to pass each function i.e. whether you have to pass a device name,\nphysical index or ifindex. Unless otherwise stated, we will be using the card\nw0 instantiated as:\n\n```python\n\u003e\u003e\u003e w0 = pyw.getcard('wlan0') # get a card for wlan0\n\u003e\u003e\u003e w0\nCard(phy=0,dev='wlan0',ifindex=2)\n```\n\nThere are other methods to get a Card object: \n* pyw.devinfo, in addition to information, will return a Card object, \n* pyw.devadd and pyw.phyadd return a card object for the newly created virtual \ninterface, and\n* pyw.ifaces returns a lists of Cards for every interface sharing the same phy.\n\nIt is also important to note while most functions require a Card object, some\ndo not and some will take a Card or a specific identifier. Read the user\nguide or code for additional information.\n\nBefore continuing you may find that a Card can become invalid. For example, I\nhave an older system where the USB tends to fall out. You can confirm that your\ncard is still valid:\n\n```python\n\u003e\u003e\u003e pyw.validcard(w0)\nTrue\n\u003e\u003e\u003e\n```\n\n#### i. Why is my Card not Working?\nSometimes you may need to turn your Card on, or possibly unblock it.\n\n```python\n\u003e\u003e\u003e pyw.isup(w0)\nTrue\n\u003e\u003e\u003e pyw.down(w0)\n\u003e\u003e\u003e pyw.isup(w0)\nFalse\n\u003e\u003e\u003e pyw.up(w0)\n\u003e\u003e\u003e pyw.isblocked(w0) # returns tup;e (Soft Block, Hard Block)\n(True,False)\n\u003e\u003e\u003e pyw.unblock(w0) # turn off the softblock\n\u003e\u003e\u003e pyw.isblocked(w0)\n(False,False)\n\u003e\u003e\u003e\n```\n\n#### ii. Working with Mac and IP Addresses\n\n```python\n\u003e\u003e\u003e mac = pyw.macget(w0) # get the hw addr\n\u003e\u003e\u003e mac\n'a0:b1:c2:d3:e4:f5'\n\u003e\u003e\u003e\n\u003e\u003e\u003e pyw.down(w0): # turn the card off to set the mac\n\u003e\u003e\u003e pyw.macset(w0,'00:1F:32:00:01:00') # lets be a nintendo device\n\u003e\u003e\u003e pyw.up(w0) # bring wlan0 back up\n\u003e\u003e\u003e pyw.macget(w0) # see if it worked\n'00:1F:32:00:01:00'\n\u003e\u003e\u003e\n\u003e\u003e\u003e pyw.inetget(w0) # not associated, inet won't return an address\n(None, None, None)\n\u003e\u003e\u003e # NOTE: to set the inet, bcast or netmask, the card does not have to be down\n...\n\u003e\u003e\u003e pyw.inetset(w0,'192.168.3.23','255.255.255.192','192.168.3.63')\nTrue\n\u003e\u003e\u003e pyw.inetget(w0)\n('192.168.3.23', '255.255.255.192', '192.168.3.255')\n\u003e\u003e\u003e\n\u003e\u003e\u003e # You can also use ip4set, netmaskset and broadcastset\n```\n\nIt is important to note that (like ifconfig), erroneous values can be set\nwhen setting the inet addresses: for example you can set the ip address on\n192.168.3.* network with a broadcast address of 10.255.255.255.\n\n#### iii. WLAN Radio Properties\nYou may want to set power management or other radio properties when pentesting.\nParticulary, if you are configuring a rogue AP.\n\n```python\n\u003e\u003e\u003e pyw.pwrsaveget(w0)\nTrue\n\u003e\u003e\u003e pyw.pwrsaveset(w0, False) # turn off powermanagement\n\u003e\u003e\u003e pyw.pwrsaveget(w0)\nFalse\n\u003e\u003e\u003e pyw.covclassset(w0, 1) # set the coverage class\npyric.error: [Errno 95] Operation not supported\n\u003e\u003e\u003e # My internal intel card does not support setting the coverage class\n...\n\u003e\u003e\u003e pyw.retryshortset(w0, 5)\n\u003e\u003e\u003e pyw.retrylongset(w0, 5)\n\u003e\u003e\u003e # We'll check these values out shortly\n...\n\u003e\u003e\u003e pyw.rtsthreshset(w0, 1024)\n\u003e\u003e\u003e pyw.fragthreshset(w0, 8000)\n\u003e\u003e\u003e\n```\n\nFor a brief description of coverage class and retry limits,\nsee http://www.computerhope.com/unix/iwconfig.htm. For a description of the RTS\nand Fragmentation thresholds see http://resources.infosecinstitute.com/rts-threshold-configuration-improved-wireless-network-performance/.\nThe IEEE 802.11-2012 also covers these. \n\n#### iv. Getting Info On Your Card\n\n```python\n\u003e\u003e\u003e iinfo = pyw.ifinfo(w0)\n\u003e\u003e\u003e for i in iinfo: print i, iinfo[i]\n... \nmask 255.255.255.192\ndriver iwlwifi\nhwaddr a0:88:b4:9e:68:58\nchipset Intel 4965/5xxx/6xxx/1xxx\nbcast 192.168.3.63\ninet 192.168.3.7\nmanufacturer Intel Corporate\n\u003e\u003e\u003e\n\u003e\u003e\u003e dinfo = pyw.devinfo(w0)\n\u003e\u003e\u003e for d in dinfo: print d, dinfo[d]\n...\nwdev 1\nRF None\nCF None\nmac 00:1F:32:00:01:00\nmode managed\nCHW None\ncard Card(phy=0,dev=wlan0,ifindex=3)\n\u003e\u003e\u003e # NOTE: since we are not associated, RF, CF and CHW are None\n...\n\u003e\u003e\u003e pyw.txget(w0)\n20\n\u003e\u003e\u003e pyw.devstds(w0)\n['b', 'g', 'n']\n\u003e\u003e\u003e pinfo = pyw.phyinfo(w0) # dict with 12 key-\u003evalue pairs see info.py\n\u003e\u003e\u003e for p in pinfo: print p, pinfo[p]\n...\n\u003e\u003e\u003e pinfo['retry_short'], pinfo['retry_long']\n(5, 5)\n\u003e\u003e\u003e pinfo['rts_thresh'], pinfo['frag_thresh']\n(1024, 8000)\n\u003e\u003e\u003e pinfo['cov_class']\n0\n\u003e\u003e\u003e pinfo['generation']\n1\n\u003e\u003e\u003e pinfo['scan_ssids']\n20\n\u003e\u003e\u003e pinfo['ciphers']\n['WEP-40', 'WEP-104', 'TKIP', 'CCMP']\n\u003e\u003e\u003e\n\u003e\u003e\u003e pinfo['modes']\n['ibss', 'managed', 'AP', 'AP VLAN', 'monitor']\n\u003e\u003e\u003e pinfo['swmodes']\n['AP VLAN', 'monitor']\n\u003e\u003e\u003e\n\u003e\u003e\u003e pinfo['commands']\n[u'new_interface', u'set_interface', u'new_key', u'start_ap', u'new_station',\nu'new_mpath', u'set_mesh_config', u'set_bss', u'authenticate', u'associate',\nu'deauthenticate', u'disassociate', u'join_ibss', u'join_mesh',\nu'set_tx_bitrate_mask', u'frame', u'frame_wait_cancel', u'set_wiphy_netns',\nu'set_channel', u'set_wds_peer', u'probe_client', u'set_noack_map',\nu'register_beacons', u'start_p2p_device', u'set_mcast_rate', u'connect',\nu'disconnect']\n\u003e\u003e\u003e\n\u003e\u003e\u003e for d in pinfo['bands']:\n...     print 'Band: ', d, pinfo['bands'][d]['HT'], pinfo['bands'][d]['VHT']\n...     pinfo['bands'][d]['rates']\n...     pinfo['bands'][d]['rfs']\n... \nBand:  5GHz True False\n[6.0, 9.0, 12.0, 18.0, 24.0, 36.0, 48.0, 54.0]\n[5180, 5200, 5220, 5240, 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560, \n5580, 5600, 5620, 5640, 5660, 5680, 5700, 5745, 5765, 5785, 5805, 5825]\nBand:  2GHz HT True False\n[1.0, 2.0, 5.5, 11.0, 6.0, 9.0, 12.0, 18.0, 24.0, 36.0, 48.0, 54.0]\n[2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467, \n2472]\n\u003e\u003e\u003e\n```\n\n#### v. Virtual Interfaces\nIn my experience, virtual interfaces are primarily used to recon, attack or some\nother tomfoolery but can also be used to analyze your wireless network. In either\ncase, it is generally advised to create a virtual monitor interface and delete\nall others (on the same phy) - this makes sure that some external process like\nNetworkManager does not interfere with your shenanigans. In the below example,\nin addition to creating an interface in monitor mode, we find all interfaces\non the same physical index and delete them. You may not need to do this.\n\nNOTE: When creating a device in monitor mode, you can also set flags (see\nNL80211_MNTR_FLAGS in nl80211_h), although some cards (usually atheros) do not\nalways obey these flag requests.\n\n```python\n\u003e\u003e\u003e 'monitor' in pyw.devmodes(w0) # make sure we can set wlan0 to monitor\nTrue\n\u003e\u003e\u003e\n\u003e\u003e\u003e m0 = pyw.devadd(w0,'mon0','monitor') # create mon0 in monitor mode\n\u003e\u003e\u003e m0\nCard(phy=0,dev=mon0,ifindex=4)\n\u003e\u003e\u003e pyw.winterfaces()\n['mon0', 'wlan0']\n\u003e\u003e\u003e for card,_ in pyw.ifaces(w0):   # delete all interfaces\n...     print card\n...     if not card.dev == m0.dev:  # that are not our monitor\n...         pyw.devdel(card)        # on the this phy\n...\n(Card(phy=0,dev=mon0,ifindex=4), 'monitor')\n(Card(phy=0,dev=wlan0,ifindex=3), 'managed')\n\u003e\u003e\u003e\n\u003e\u003e\u003e\n\u003e\u003e\u003e pyw.txget(w0)\n15\n\u003e\u003e\u003e pyw.txset(w0,30,'fixed')\n\u003e\u003e\u003e # NOTE: my card does not support setting the tx power.\n...\n\u003e\u003e\u003e pyw.up(m0) # bring the new card up to use\n\u003e\u003e\u003e pyw.chset(m0,6,None) # and set the card to channel 6\nTrue\n\u003e\u003e\u003e\n```\n\nNOTE: If you don't want to add a virtual interface, you can set the mode of a current\none with modeset.\n\nOnce you are done, you will probably want to delete the virtual interface and\nrestore your original one.\n\n```python\n\u003e\u003e\u003e w0 = pyw.devadd(m0,'wlan0','managed') # restore wlan0 in managed mode\n\u003e\u003e\u003e pyw.devdel(m0) # delete the monitor interface\nTrue\n\u003e\u003e\u003e pyw.up(w0) # and bring the card up\n\u003e\u003e\u003e\n```\n\nSo, perhaps you do not care for the previous method of creating a card\nin monitor mode and deleting all associated interfaces and would prefer \nto execute an airmon-ng(ish) method. \n\n```python\n\u003e\u003e\u003e w0\nCard(phy=0,dev='wlan0',ifindex=2)\n\u003e\u003e\u003e w1 = pyw.devset(w0, 'wlan1')\n\u003e\u003e\u003e w1\nCard(phy=0,dev=wlan1,ifindex=3)\n\u003e\u003e\u003e pyw.modeset(w1, 'monitor')\n\u003e\u003e\u003e pyw.up(w1)\n\u003e\u003e\u003e pyw.chset(w1, 1, None)\n```\n\nThe above commands replicate the behaviour of airmon-ng. To verify, open a \ncommand prompt and execute the following:\n\n```bash\n?\u003e iw dev wlan0 info # replace wlan0 with your nic\nInterface wlan0\n\tifindex 3\n\twdev 0x1\n\taddr a0:88:b4:9e:68:58\n\ttype managed\n\twiphy 0\n?\u003e sudo airmon-ng start wlan0\nFound 2 processes ...\n?\u003e \n?\u003e iw dev wlan0mon info \nInterface wlan0mon\n\tifindex 6\n\twdev 0x2\n\taddr a0:88:b4:9e:68:58\n\ttype monitor\n\twiphy 0\n\tchannel 10 (2457 MHz), width: 20 MHz (no HT), center1: 2457 MHz\n?\u003e\n?\u003e sudo airmon-ng stop wlan0mon\n...\n?\u003e iw dev wlan0 info\nInterface wlan0\n\tifindex 7\n\twdev 0x3\n\taddr a0:88:b4:9e:68:59\n\ttype managed\n\twiphy 0\n```\n\nAs you can see, under the covers, airmon-ng deletes the specified nic \n(wlan0 in this example), creates a new one, sets the mode to monitor and\nsets the channel (10 in this case). While the physical index remains the \nsame, wiphy 0, the ifindex and wdev change. So, what looks like a simple\nrenaming of your nic and setting the mode to monitor is in face multiple\nsteps requiring several communications with the kernel. As stated previously,\nI prefer the first method of setting a card to monitor because by \ndeleting all associated interfaces, there is a smaller risk of some other\nprocess interfering with you.\n\nIf you wanted, you could easily write your own python function to replicate\nairmon-ng programmatically. as done below\n\n```python\nimport pyric\nimport pyric.pyw as pyw\nimport pyric.lib.libnl as nl\n\ndef pymon(card, start=True, ch=None):\n    \"\"\"\n     sets the Card card monitor mode or returns it to managed mode\n     :param card: a Card object\n     :param start: True = set|False = reset\n     :param ch: initial ch to start on\n     :returns: the new card\n    \"\"\"\n    newcard = None\n    if start:\n        if pyw.modeget(card) == 'monitor':\n            raise RuntimeError(\"Card is already in monitor mode\")\n        newcard = pyw.devset(card, card.dev + 'mon')\n        pyw.modeset(newcard, 'monitor')       \n        pyw.up(newcard)\n        if ch: pyw.chset(w1, ch, None) \n    else:\n        if pyw.modeget(card) == 'managed':\n            raise RuntimeError(\"Card is not in monitor mode\")\n        newcard = pyw.devset(card, card.dev[:-3])\n        pyw.modeset(newcard, 'managed')        \n        pyw.up(newcard)\n    return newcard\n```\n\n##### o Virtual Interfaces and Issues in Kernel 4.x \nAfter recently upgrading my distro, my kernel was upgraded from 3.x to 4.x. I \nnoticed that in some situations, adding a virtual interface (VIF) did not have \nthe desired effect. Namely, new VIFs did not have the dev name I had specified.\nFurthermore, regardless of the naming convention I was currently using (old \nschool like wlan0, eth0 etc or the newer predictable names i.e. wlp3s0) the\nnew VIF would have a predictable name and the MAC address would be one up from \nthat of the actual cards MAC address. For more details, check out my blog \nat https://wraithwireless.wordpress.com/2016/07/24/linux-kernel-bug/. This is\nan issue at the kernel and nl80211 level and not a PyRIC bug.\n\nThis situtation will only occur if you are attempting to (a) create a VIF with\nthe same dev name as the original, (b) in managed mode and (c) there are currently\nother VIFs sharing the same phy. \n\n```python\n\u003e\u003e\u003e pyw.winterfaces()\n['alfa0']\n\u003e\u003e\u003e card = pyw.getcard('alfa0')\n\u003e\u003e\u003e card\nCard(phy=1,dev=alfa0,ifindex=5)\n\u003e\u003e\u003e mcard\nCard(phy=1,dev=mon0,ifindex=6)\n\u003e\u003e\u003e pyw.devdel(card)\n\u003e\u003e\u003e pyw.winterfaces()\n['mon0']\n\u003e\u003e\u003e pyw.devadd(mcard,'alfa0','managed')\nCard(phy=1,dev=alfa0,ifindex=7)\n\u003e\u003e\u003e pyw.winterfaces()\n['mon0', 'wlx00c0ca59afa7']\n\u003e\u003e\u003e pyw.devdel(pyw.getcard('wlx00c0ca59afa7'))\n\u003e\u003e\u003e pyw.winterfaces()\n['wlan0mon', 'mon0']\n\u003e\u003e\u003e pyw.phyadd(mcard,'alfa0','managed')\nCard(phy=1,dev=alfa0,ifindex=8)\n\u003e\u003e\u003e pyw.winterfaces()\n['wlan0mon', 'mon0', 'wlx00c0ca59afa7']\n```\n\nAll three of the above most be True for this to occur. So, for example:\n\n```python\n\u003e\u003e\u003e pyw.winterfaces()\n['mon0']\n\u003e\u003e\u003e pyw.devadd(mcard,'alfa0','monitor')\nCard(phy=1,dev=alfa0,ifindex=10)\n\u003e\u003e\u003e pyw.winterfaces()\n['mon0', 'alfa0']\n```\n\nworks because case (b) is false.\n\nSome things to note:\n* it does not matter if you are using devadd (creating a VIF via the ifindex) or\nphyadd (creating a VIF via the physical index)\n* nl80211 believes that new VIF has the name you specified so I believe this is\nsomething related to the kernel itself or possibly udev. If you look at the source\ncode for phyadd or devadd, the returned card uses the indicators returned by the\nkernel.\n\nI had considered several options of rectifying this for PyRIC but, doing so would\nrequire either mutliple checks on kernel version or breaking backward compatibility\nfor users with kernel 3.x and possibly breaking forward compatibility (if this \nissue does get fixed at some future kernel version). Besides, being aware of \nthe state that must be true for this to happen, users can easily workaround it.\n\nOne way, as we saw earlier, is to create a VIF in monitor mode and then set it \nto managed.\n\n```python\n\u003e\u003e\u003e pyw.winterfaces()\n['mon0']\n\u003e\u003e\u003e pyw.devadd(mcard,'alfa0','monitor')\nCard(phy=1,dev=alfa0,ifindex=10)\n\u003e\u003e\u003e pyw.winterfaces()\n['mon0', 'alfa0']\n\u003e\u003e\u003e pyw.devdel(pyw.getcard('mon0'))\n\u003e\u003e\u003e card = pyw.getcard('alfa0')\n\u003e\u003e\u003e pyw.down(card)\n\u003e\u003e\u003e pyw.modeset(card,'managed')\n\u003e\u003e\u003e pyw.up\n\u003cfunction up at 0x7f76339c99b0\u003e\n\u003e\u003e\u003e pyw.up()\nTraceback (most recent call last):\n  File \"\u003cstdin\u003e\", line 1, in \u003cmodule\u003e\nTypeError: up() takes at least 1 argument (0 given)\n\u003e\u003e\u003e pyw.up(card)\n\u003e\u003e\u003e pyw.winterfaces()\n['wlan0mon', 'alfa0']\n\u003e\u003e\u003e pyw.devinfo(card)\n{'wdev': 4294967302, 'RF': None, 'CF': None, 'mac': '00:c0:ca:59:af:a6', \n'mode': 'managed', 'CHW': None, 'card': Card(phy=1,dev=alfa0,ifindex=10)}\n```\n\nBut, I think this is sloppy. The better way is to use phyadd. Recall that \nphyadd accepts either a Card or the phy and that even though a card is deleted,\nsome of its reference values are still valid. In the case of deleting a card,\nthe phy is still present. So, you could use a phy or a Card that was previously\ndeleted because the phy is still valid. \n\n```python\n\u003e\u003e\u003e pyw.winterfaces()\n['mon0']\n\u003e\u003e\u003e phy = mcard.phy\n\u003e\u003e\u003e pyw.devdel(mcard)\n\u003e\u003e\u003e pyw.winterfaces()\n[]\n\u003e\u003e\u003e card = pyw.phyadd(phy,'alfa0','managed')\n\u003e\u003e\u003e card\nCard(phy=1,dev=alfa0,ifindex=12)\n\u003e\u003e\u003e pyw.winterfaces()\n['alfa0']\n```\n\nThis works, but remember you have to delete all interfaces with the same phy\nas the one you are creating before creating it.\n\n#### vi. STA Related Functions\nI have recently begun adding STA functionality to PyRIC. These are not necessarily \nrequired for a pentester, although the ability to disconnect a Card may come in \nhandy. The difficulty is that iw only provides connect functionality through Open\nor WEP enabled APs which means that I am attempting to determine which commands \nand attributes are required. If all else fails I will look to wpa_supplicant for \nmore information. Additionally, iw will not connect if wpa_supplicant is running.\n\n```python\n\u003e\u003e\u003e pyw.isconnected(w0)\nTrue\n\u003e\u003e\u003e pyw.disconnect(w0)\n\u003e\u003e\u003e pyw.isconnected(w0)\nFalse\n\u003e\u003e\u003e\n```\n\nFrom a pentester's point of view iw link provides information of limited\nquality/concern but can be useful at times. As such, link has now been\nimplemented. \n\n```python\n\u003e\u003e\u003e link=pyw.link(w0)\n\u003e\u003e\u003e for d in link:\n...     print d, link[d]\n... \nstat associated\nssid ****net\nbssid XX:YY:ZZ:00:11:22\nchw 20\nint 100\nfreq 5765\ntx {'pkts': 256, 'failed': 0, 'bytes': 22969, 'bitrate': {'rate': 6.0}, \n    'retries': 31}\nrx {'pkts': 29634, 'bitrate': {'width': 40, 'rate': 270.0, \n    'mcs-index': 14, 'gi': 0}, 'bytes': 2365454}\nrss -50\n\u003e\u003e\u003e\n```\n\nNOTE: the rx gives additional key-\u003evalue pairs for bitrate. Depending on\nwhether the Card is transmitting (or receiving) 802.11n, the bitrate may\ninclude values for width, mcs-index and guard interval (gi). If we look\nup these values in Table 20-35 of IEEE Std 802.11-2012, we see that at \n40 MHz width, an mcs-index of 14 with a short guard interval (400ns)\nthe rate = 270.\n\nOne can also use pyw.stainfo to retrieve only tx/rx metrics.\n\n#### vii. Miscelleaneous Utilities\nSeveral additional tools are located in the utils directory. Two of these are:\n * channels.py: defines ISM and UNII band channels/frequencies and provides\n functions to convert between channel and frequency and vice-versa\n * ouifetch.py: retrieves and parses oui.txt from the IEEE website and stores\n  the oui data in a file that can be read by hardware.py functions\nThe others will be demonstrated in the following\n\nhardware.py\nDriver, chipset and mac address related functions can be found here:\n\n``` python\nimport pyric.utils.hardware as hw\n\nouis = hw.parseoui() # load the oui dict\nlen(ouis)\n=\u003e 22128\n\nmac = 'a0:88:b4:9e:68:58'\ndev = 'wlan0'\n\nhw.oui(mac)\n=\u003e 'a0:88:b4'\n\nhw.ulm(mac)\n=\u003e '9e:68:58'\n\nhw.manufacturer(ouis,mac)\n=\u003e 'Intel Corporate'\n\nhw.randhw(ouis) # generate a random mac address\n=\u003e'00:03:f0:5a:a1:fc'\n\nhw.manufacturer(ouis,'00:03:f0:5a:a1:fc')\n=\u003e 'Redfern Broadband Networks'\n\nhw.ifcard('wlan0') # get driver \u0026 chipset\n=\u003e ('iwlwifi', 'Intel 4965/5xxx/6xxx/1xxx')\n```\n\nrfkill.py\nSometimes, your card has a soft block (or hard block) on it and it is not\nrecognized by command line tools or pyw. Use rkill to list, turn on or turn\noff soft blocks.\n\n``` python\nimport pyric.utils.rfkill as rfkill\n\nrfkill.rfkill_list() # list rfkill devices\n=\u003e {'tpacpi_bluetooth_sw': {'soft': True, 'hard': False, 'type': 'bluetooth', 'idx': 1},\n    'phy3': {'soft': False, 'hard': False, 'type': 'wlan', 'idx': 5},\n    'phy0': {'soft': False, 'hard': False, 'type': 'wlan', 'idx': 0}}\n\nidx = rfkill.getidx(3)\nidx\n=\u003e 5\n\nrfkill.getname(idx)\n=\u003e phy3\n\nrfkill.gettype(idx)\n=\u003e 'wlan'\n\nrfkill.soft_blocked(idx)\n=\u003e False\n\nrfkill.hard_blocked(idx)\n=\u003e False\n\nrfkill.rfkill_block(idx)\n\nrfkill.list()\n=\u003e {'tpacpi_bluetooth_sw': {'soft': False, 'hard': True, 'type': 'bluetooth', 'idx': 1},\n    'phy3': {'soft': True, 'hard': True, 'type': 'wlan', 'idx': 5},\n    'phy0': {'soft': True, 'hard': True, 'type': 'wlan', 'idx': 0}}\n\nrfkill.rfkill_unblock(idx)\n\nrfkill.rfkill_list()\n=\u003e {'tpacpi_bluetooth_sw': {'soft': True, 'hard': False, 'type': 'bluetooth', 'idx': 1},\n    'phy3': {'soft': False, 'hard': False, 'type': 'wlan', 'idx': 5},\n    'phy0': {'soft': False, 'hard': False, 'type': 'wlan', 'idx': 0}}\n```\n\nNote that rfkill_list lists all 'wireless' devices: wlan, bluetooth, wimax, wwan,\ngps, fm and nfc. Another important thing to note is that the rfkill index is not\nthe same as the interface index.\n\n## 4. EXTENDING:\n\nExtending PyRIC is fun and easy too, see the user guide PyRIC.pdf.\n\n## 5. ARCHITECTURE/HEIRARCHY:\nBrief Overview of the project file structure. Directories and/or files annotated\nwith (-) are not included in pip installs or PyPI downloads\n\n* PyRIC                   root Distribution directory\n  - \\_\\_init\\_\\_.py       initialize distrubution PyRIC module\n  - examples              example folder\n    + pentest.py          create wireless pentest environment example\n    + info.py             display device information\n  - tests (-)             test folder\n    + pyw.unittest.py     unit test for pyw functions\n  - docs                  User Guide resources\n    + nlsend.png (-)      image for user guide\n    + nlsock.png (-)      image for user guide\n    + logo.png (-)        pyric logo\n    + PyRIC.tex (-)       User tex file\n    + PyRIC.bib (-)       User Guide bibliography\n    + PyRIC.pdf           User Guide\n  - setup.py              install file\n  - setup.cfg             used by setup.py\n  - MANIFEST.in           used by setup.py\n  - README.md             this file\n  - LICENSE               GPLv3 License\n  - CHANGES               revision file\n  - TODO                  todos for PyRIC\n  - pyric                 package directory\n    + \\_\\_init\\_\\_.py     initialize pyric module\n    + pyw.py              wireless nic functionality\n    + utils               utility directory\n     * \\_\\_init\\_\\_.py    initialize utils module\n     * channels.py        802.11 ISM/UNII freqs. \u0026 channels\n     * hardware.py        device, chipset and mac address utility functions\n     * rfkill.py          rfkill functions\n     * ouifetch.py        retrieve and store oui dict from IEEE\n     * data               data folder for ouis\n      - oui.txt           oui file fetched from IEEE\n    + net                 linux header ports\n      * \\_\\_init\\_\\_.py   initialize net subpackage\n      * if_h.py           inet/ifreq definition\n      * sockios_h.py      socket-level I/O control calls\n      * genetlink_h.py    port of genetlink.h\n      * netlink_h.py      port of netlink.h\n      * policy.py         defines attribute datatypes\n      * wireless          wireless subpackage\n        - \\_\\_init\\_\\_.py initialize wireless subpackage\n        - nl80211_h.py    nl80211 constants\n        - nl80211_c.py    nl80211 attribute policies\n        - rfkill_h.py     rfkill header file\n        - wlan.py         ieee80211.h port (subset of)\n    + lib                 library subpackages\n      * \\_\\_init\\_\\_.py   initialize lib subpackage\n      * libnl.py          netlink helper functions\n      * libio.py          sockios helper functions\n    + nlhelp              netlinke documentation/help\n      * \\_\\_init\\_\\_.py   initialize nlhelp subpackage\n      * nsearch.py        nl80211 search\n      * commands.help     nl80211 commands help data\n      * attributes.help   nl80211 attributes help data\n    + scripts             script subpackage\n      * ouiupdate         fetch oui.txt \u0026 update oui dict\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwraith-wireless%2Fpyric","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwraith-wireless%2Fpyric","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwraith-wireless%2Fpyric/lists"}