simple JSON pretty printer that you can easily copy paste

Simple JSON pretty printer that you can easily copy paste. Useful when you need to read a big JSON output and you are on a remote machine on which you can not install a lot.


python -c 'import sys; import json; import pprint; pprint.pprint(json.loads(sys.stdin.read()))'

Usage:

somecommand_that_generates_json_output | python -c 'import sys; import json; import pprint; pprint.pprint(json.loads(sys.stdin.read()))'

adding SOCKS5 support to python3 http client using just standard libs

I had a need for a simple way of running some HTTP queries through SOCKS5 (think OpenSSH -D) proxy. All the examples I could find on the internet required usage of external libraries, I prefer to just use the standard ones, makes things simpler in the end.

Here is the code I come up with, I borrowed some code from a different tool that I wrote sometime ago. Gist can be found here.

#!/usr/bin/env python3

import http.client
import socket
from struct import pack, unpack

class HTTPSocks5(http.client.HTTPConnection):

  def setsocksproxy(self, host, port):
    self.socks5host = host
    self.socks5port = port

  def connect(self):
    if hasattr(self, "socks5host") and self.socks5host:
      self.sock = self._create_connection(
        (self.socks5host,self.socks5port), self.timeout, self.source_address)

      error = ["succeeded", "general SOCKS server failure",\
        "connection not allowed by ruleset", "Network unreachable",\
        "Host unreachable", "Connection refused", "TTL expired",\
        "Command not supported", "Address type not supported", "unassigned"]

      data = pack('!3B',5,1,0) # lets connect to socks5 server
      self.sock.send(data)
      data = self.sock.recv(2)
      auth = unpack('2B',data)[1] # do we need to authenticate
      if auth != 255:
        nport = pack('!H',self.port)
        try:
          if ":" in self.host: # we most likely have IPv6 here
            data = pack('!4B',5,1,0,4)+\
              socket.inet_pton(socket.AF_INET6,self.host)+nport
          else: # IPv4
            data = pack('!4B',5,1,0,1)+\
              socket.inet_pton(socket.AF_INET,self.host)+nport
        except socket.error: # or just a hostname to resolve by the SOCKS srv
          data = pack('!5B',5,1,0,3,len(self.host))+\
            bytearray(self.host,'UTF-8')+nport

        self.sock.send(data)
        data = self.sock.recv(256) # getting the status code
        try:
          code = unpack('BBB',data[:3])[1]
        except:
          raise("socks server sent a wrong replay")

        if code != 0:
          if code > 9:
            code = 9
          raise("socks server sent an error: %s" % (error[code],))
      else:
        raise("socks server requires authentication")
    else:
      self.sock = self._create_connection(
        (self.host,self.port), self.timeout, self.source_address)


a very simple and quick to copy and paste cli hex editor - python

A very simple thing but maybe somebody will find this useful.
I had a need for a simple hex editor, so I wrote this:

 #!/usr/bin/env python
import sys
"""
a very simple cli hex file editor
"""
if len(sys.argv) < 3:
  print "usage: %s filename hex_offset " % (sys.argv[0])
  sys.exit(0)
fd = open(sys.argv[1],"rw+")
fd.seek(int(sys.argv[2],16))
print "offset:0x%s char:%s" % (sys.argv[2], hex(ord(fd.read(1))))
fd.seek(int(sys.argv[2],16))
if len(sys.argv) > 3:
  fd.write(chr(int(sys.argv[3],16)))
  fd.seek(int(sys.argv[2],16))
  print "offset:0x%s char:%s" % (sys.argv[2], hex(ord(fd.read(1))))
fd.close()

Usage is simple, it takes three arguments (third one is optional), first is the path to the file you want to edit, second is offset in hex from the beginning of that file. If you do not provide the third argument then only a value under given offset is printed to the screen (nothing is changed), if you provide third value (in hex) then this value is written under that offset.

Example:
> dd if=/dev/urandom of=test_file.dat count=1 bs=32
1+0 records in
1+0 records out
32 bytes (32 B) copied, 0.0002849 s, 112 kB/s 
> cat test_file.dat | xxd
00000000: 4721 d36c 0335 572f cb51 323d d4ec bc3e  G!.l.5W/.Q2=...>
00000010: 6e00 905a c484 3fbf ca6e d202 f0ec bc18  n..Z..?..n...... 
> ./edit_file.py test_file.dat 10
offset:0x10 char:0x6e 
> ./edit_file.py test_file.dat 10 ff
offset:0x10 char:0x6e
offset:0x10 char:0xff 
> cat test_file.dat | xxd
00000000: 4721 d36c 0335 572f cb51 323d d4ec bc3e  G!.l.5W/.Q2=...>
00000010: ff00 905a c484 3fbf ca6e d202 f0ec bc18  ...Z..?..n......

EDIT (added 2016/01/08):

A bit improved (and just slightly bigger) version that can be found here, it is able to also handle ranges.

Example:

> cat test_file.dat | xxd
00000000: 4721 d36c 0335 572f cb51 323d d4ec bc3e  G!.l.5W/.Q2=...>
00000010: 6e00 905a c484 3fbf ca6e d202 f0ec bc18  n..Z..?..n......


> hedit.py test_file.dat 10-4
offset:0x10 6e00905a


> hedit.py test_file.dat 10-4 abcdef
offset:0x10 6e00905a
offset:0x10 abcdef5a


> cat test_file.dat | xxd
00000000: 4721 d36c 0335 572f cb51 323d d4ec bc3e  G!.l.5W/.Q2=...>
00000010: abcd ef5a c484 3fbf ca6e d202 f0ec bc18  ...Z..?..n......