{ "info": { "author": "sasdf", "author_email": "", "bugtrack_url": null, "classifiers": [ "Development Status :: 1 - Planning", "Environment :: Plugins", "Intended Audience :: Developers", "License :: Other/Proprietary License", "Operating System :: OS Independent", "Programming Language :: Python :: 3 :: Only", "Topic :: Security", "Topic :: Software Development :: Libraries" ], "description": "# FirstBlood\n\n> I'm not writing production scripts, I just want to get the firstblood.\n\nThis is a python 3 library which will add some method to builtin objects,\nand provide some useful utilities.\n\nIt's still WIP and needs a lot of refactoring.\n\nWARNING: THIS LIBRARY MAY CHANGE THE BEHAVIOR OF PYTHON,\nWHICH SHOULD NOT BE USED IN PRODUCTION ENVIRONMENT.\n\n\n## TOC\n* Bytes, String and Hash\n* Method Chaining\n* Iterable\n* Function\n* Integer and Modulo\n* Object\n* JSON\n* Type Conversion\n* Unified I/O\n\n\n## Get Started\n```python\nfrom firstblood.all import *\n```\n\n\n## Get Started - Bytes, String and Hash\nPython 3 has many great features,\nbut it's not very suitable for CTF due to the seperation of str and bytes.\nThe concept of bytes is really useful,\nyou should follow it to handle encoding correctly in production.\nBut it is annoying when you have a tight deadline (e.g. during the CTF).\n\nTake base64 encoding for an example,\nhere how it looks like in python 2:\n```python\nstr_var.encode('base64')\n```\nin python 3:\n```python\nimport binascii\nbinascii.b2a_base64(str_var.encode('utf8')).decode('utf8')\n```\nWith this library, you can write:\n```python\nstr_var.b64e\n# or\nstr_var.base64e\n# or\nstr_var.enc('base64')\n```\n\nWe also have a `xor` method which is very useful for crypto tasks:\n```python\n>>> 'abc'.xor('cde')\nb'\\x02\\x06\\x06'\n>>> 'abc'.xor(32)\nb'ABC'\n```\n\nTo convert between bytes, str and int:\n```python\n>>> 'abc'.bytes\nb'abc'\n>>> 'abc'.bytes.str\n'abc'\n>>> 'a'.ord # ord\n97\n>>> b'1337'.int10 # decimal\n1337\n>>> b'1337'.int16 # hex\n4919\n>>> b'\\x39\\x05'.int # little endian\n1337\n>>> b'\\x05\\x39'.Int # big endian\n1337\n>>> b'\\x39\\x05'.u16 # integer modulo ring\n(1337 mod 2^16)\n```\n\nWe also bind hashlib digest to str and bytes:\n```python\n>>> 'abc'.sha1\nb'\\xa9\\x99>6G\\x06\\x81j\\xba>%qxP\\xc2l\\x9c\\xd0\\xd8\\x9d'\n>>> 'abc'.sha1.hexe\n'a9993e364706816aba3e25717850c26c9cd0d89d'\n>>> 'abc'.blake2s\nb'P\\x8c^\\x8c2|\\x14\\xe2\\xe1\\xa7+\\xa3N\\xebE/7E\\x8b \\x9e\\xd6:)M\\x99\\x9bL\\x86gY\\x82'\n>>> 'abc'.blake2s.hexe\n'508c5e8c327c14e2e1a72ba34eeb452f37458b209ed63a294d999b4c86675982'\n```\n\n\n## Get Started - Method Chaining\nThe nature of python is nesting function call:\n```python\nlen(listA)\n# or\nlist(map(str, listA))\n# or\nenumerate(zip(listA, listB))\n# or\nb2a_base64(sha1(a2b_base64(str_var)).digest()).decode('utf8')\n```\nBut I'm a big fan of method chaining like what we do in Javascript.\nWith this library, we can write:\n```python\nlistA.len\n# or\nlistA.map(str).list\n# or\nlistA.zip(listB).enum\n# or\nstr_var.b64d.sha1.b64e\n```\nThe order of method is same as the order of execution.\nMuch better, right :)\n\n\n## Get Started - Iterable and Function\nWe intergrate builtin functions and a powerful module, itertools,\nto iterables itself.\n\nIf we want to bruteforce length 3 pairs of a given set:\n```python\n>>> range(2).product(3).take(5).list\n[(0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 1, 1), (1, 0, 0)]\n>>> 'ab'.product(3).take(5).list\n['aaa', 'aab', 'aba', 'abb', 'baa']\n```\n\nAnd some useful utilities for processing iterables:\n```python\n>>> 'abcabc'.rev\n'cbacba'\n>>> 'abcabc'.sorted\n'aabbcc'\n>>> 'abcabc'.chunk(2).list\n['ab', 'ca', 'bc']\n>>> 'abcabc'.nchunks(2).list\n['abc', 'abc']\n>>> range(4).xor(32).list\n[32, 33, 34, 35]\n```\n\nWe also add some numpy-like functions:\n```python\n>>> range(5, 10).sum\n35\n>>> range(5, 10).mean\n7.0\n>>> range(5, 10).min\n5\n>>> range(5, 10).argmin\n0\n>>> range(5, 10).max\n9\n>>> range(5, 10).argmax\n4\n>>> range(10).all\nFalse\n>>> range(10).any\nTrue\n>>>\n```\n\nConvert between different iterables is very easy:\n```python\n>>> 'abcabc'.list # list\n['a', 'b', 'c', 'a', 'b', 'c']\n>>> 'abcabc'.uniq # set\n{'a', 'b', 'c'}\n>>> 'abcabc'.tuple # tuple\n('a', 'b', 'c', 'a', 'b', 'c')\n>>> 'abcabc'.counter # collections.Counter\nCounter({'a': 2, 'b': 2, 'c': 2})\n>>> 'abcabc'.list.joinby(', ')\n'a, b, c, a, b, c'\n>>> 'abcabc'.list.joinby(b', ')\nb'a, b, c, a, b, c'\n```\n\n\n## Get Started - Function\nSimilar to itertools, we have functools for functions,\nwe bind `partial` method on it:\n```python\n>>> (lambda x: x).partial(10)()\n10\n>>> (lambda x: x).bind(10)()\n10\n```\n\n#### TODO\ncompose\n\n\n## Get Started - Integer and Modulo\nWe provide different ways to convert to hex and bin:\n```python\n>>> (1337).hex\n'0539'\n>>> (1337).bin\n'0000010100111001'\n```\nwhere `hex` is aligned to two chars and `bin` is aligned to 8 chars.\n\nWe have a special module for calculation modulo arithmetic:\n```python\n>>> (13).u16\n(13 mod 2^16)\n>>> (13).u16 << 15\n(32768 mod 2^16)\n>>> (13).u16 << 16\n(0 mod 2^16)\n\n>>> (13).mod(100) * 10\n(30 mod 100)\n>>> (13).mod(100) / 3\n(71 mod 100)\n>>> (71).mod(100) * 3\n(13 mod 100)\n>>> 1 / (13).mod(100)\n(77 mod 100)\n>>> (13).mod(100).inv\n(77 mod 100)\n```\n\nSome utilities:\n```python\n>>> (30).align(8)\n32\n>>> (32).align(8)\n32\n>>> (30).bin\n'00011110'\n>>> (30).mask(4).bin\n'00010000'\n```\n\nTo convert between int, bytes and str:\n```python\n>>> (97).chr\n'a'\n>>> (1952802156).str\n'1952802156'\n>>> (1952802156).bytes\nb'leet'\n>>> (1952802156).p32\nb'leet'\n>>> (1952802156).p64\nb'leet\\x00\\x00\\x00\\x00'\n```\n\n\n## Get Started - Object\nWe bind some builtin functions to Object:\n```python\n>>> str.dir.take(5).list\n['Int', '__add__', '__class__', '__contains__', '__delattr__']\n>>> str.hasattr('__name__')\nTrue\n>>> str.getattr('__name__')\n'str'\n>>> str.setattr('__name__', 'error')\nTraceback (most recent call last):\n File \"\", line 1, in \nTypeError: cant set attributes of built-in/extension type 'str'\n```\n\n\n## Get Started - JSON\nConverting between data and JSON string can be done with attributes:\n```python\n>>> 'abc'.json\n'\"abc\"'\n>>> (1337).json\n'1337'\n>>> {'a': 1}.json\n'{\"a\": 1}'\n>>> {'a': 1}.json.jsond\n{'a': 1}\n```\n\n\n## Get Started - Type conversion\nTBD\n\nBinding codecs module to attribute.\n```python\nstr_var.enc(encoding)\nstr_var.dec(encoding)\n```\n\n\n## Get Started - Unified I/O\nTBD\n\nInspired by the awesome interface of pwntools,\nwe provide a unified interface for communicating between proceess, network, or even files.\n```python\nr.line([size, keep=False]) # read a line up to size bytes. alias of r.readline([size])\nr.line(data) # alias of r.writeline(data)\nr.lines([hint, keep=False]) # read all lines up to hint bytes. alias of r.readlines([hint])\nr.until('input: ', [keep=False, drop=True]) # alias of r.readuntil('input: ')\nr.read([n]) # read up to n bytes\nr.peek([n]) # peek up to n bytes\nr.write(data) # write data\nr.seek(n) # file only\n```\nMoreover, we make it chainable to provide a cleaner interface.\n```python\nr.after('input: ').line(data).read(5)\nr.before('0x').line()\n```\n\nWe also provide shortcuts to files to avoid `with open` block:\n```python\ndata = uio.read('/path/to/file') # r mode\ndata = uio.readbin('/path/to/file') # rb mode\ndata = uio.readline('/path/to/file') # r mode\ndata = uio.readbinline('/path/to/file') # rb mode\ndata = uio.readlines('/path/to/file') # r mode\ndata = uio.readbinlines('/path/to/file') # rb mode\ndata = uio.readuntil('/path/to/file', 'end') # r mode\ndata = uio.readbinuntil('/path/to/file', b'end') # r mode\ndata = uio.write('/path/to/file', data) # r mode\ndata = uio.writebin('/path/to/file', data) # r mode\ndata = uio.writeline('/path/to/file', data) # r mode\ndata = uio.writebinline('/path/to/file', data) # r mode\ndata = uio.writelines('/path/to/file', lines) # r mode\ndata = uio.writebinlines('/path/to/file', lines) # r mode\n```\n[Future] Maybe we can bind uio and pathlib to str attributes?\n```python\ndata = '/path/to/file'.read()\ndata = '/path/to/file'.readbin()\ndata = '/path/to/file'.readlines()\ndata = '/path/to/file'.write(data)\n\nf = '/path/to/file'.open()\nfiles = '/path/to/dir'.iterdir()\n```\n\n\n## API\nTBD\n\nThe project is still working in progress,\nwe does'nt has any stable api now.\n\n\n## Current Limitation\nOverriding operators of builtin type cannot be done in pure python,\nthose types save C function pointers directly.", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/sasdf/firstblood", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "firstblood", "package_url": "https://pypi.org/project/firstblood/", "platform": "", "project_url": "https://pypi.org/project/firstblood/", "project_urls": { "Homepage": "https://github.com/sasdf/firstblood" }, "release_url": "https://pypi.org/project/firstblood/0.0.1/", "requires_dist": null, "requires_python": "", "summary": "Write exploit faster with up-to-date python 3", "version": "0.0.1" }, "last_serial": 4426655, "releases": { "0.0.1": [ { "comment_text": "", "digests": { "md5": "03aab950fb0dcc6d61a32707efc254e9", "sha256": "3b14db1ac93eaae753293c43ff1267d753cc19524edc8e9372382e948d90e0c6" }, "downloads": -1, "filename": "firstblood-0.0.1-py3.7.egg", "has_sig": false, "md5_digest": "03aab950fb0dcc6d61a32707efc254e9", "packagetype": "bdist_egg", "python_version": "3.7", "requires_python": null, "size": 44416, "upload_time": "2018-10-29T08:30:14", "url": "https://files.pythonhosted.org/packages/83/ca/74c3a9a1c6d50122b8b7c02d27c0cf6d60f18398dc662d3afa8e9f1bd0c0/firstblood-0.0.1-py3.7.egg" }, { "comment_text": "", "digests": { "md5": "f69eba2030a0e849868813970f715857", "sha256": "d4fc80160b70805da63db6c8366aff883df5fa31d2f1640904f044b4bc7f317b" }, "downloads": -1, "filename": "firstblood-0.0.1.tar.gz", "has_sig": false, "md5_digest": "f69eba2030a0e849868813970f715857", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18137, "upload_time": "2018-10-29T08:30:18", "url": "https://files.pythonhosted.org/packages/40/62/e74ed8bd4bf61d7f2295737c6acf1d7b4d5134802b862617f92055d83fe3/firstblood-0.0.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "03aab950fb0dcc6d61a32707efc254e9", "sha256": "3b14db1ac93eaae753293c43ff1267d753cc19524edc8e9372382e948d90e0c6" }, "downloads": -1, "filename": "firstblood-0.0.1-py3.7.egg", "has_sig": false, "md5_digest": "03aab950fb0dcc6d61a32707efc254e9", "packagetype": "bdist_egg", "python_version": "3.7", "requires_python": null, "size": 44416, "upload_time": "2018-10-29T08:30:14", "url": "https://files.pythonhosted.org/packages/83/ca/74c3a9a1c6d50122b8b7c02d27c0cf6d60f18398dc662d3afa8e9f1bd0c0/firstblood-0.0.1-py3.7.egg" }, { "comment_text": "", "digests": { "md5": "f69eba2030a0e849868813970f715857", "sha256": "d4fc80160b70805da63db6c8366aff883df5fa31d2f1640904f044b4bc7f317b" }, "downloads": -1, "filename": "firstblood-0.0.1.tar.gz", "has_sig": false, "md5_digest": "f69eba2030a0e849868813970f715857", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18137, "upload_time": "2018-10-29T08:30:18", "url": "https://files.pythonhosted.org/packages/40/62/e74ed8bd4bf61d7f2295737c6acf1d7b4d5134802b862617f92055d83fe3/firstblood-0.0.1.tar.gz" } ] }