前期准备
已知可发送b't3 12.2.1\nAS:255\nHL:19\n\n'
来触发T3协议,所以可以写一个小脚本来重复发送请求,方便分析:
import socket
from time import sleep
def send(ip, port, data):
# data = data.encode("utf8")
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = (ip, int(port))
try:
sock.connect(server_address)
sock.sendall(data)
response = sock.recv(1024)
sleep(1)
print(response)
except socket.error as e:
print('[!] Socket Error')
finally:
sock.close()
if __name__ == '__main__':
t3 = b"t3 12.2.1\nAS:255\nHL:19\n\n"
while input("[*] Go?(Y/N):")[0].lower() == 'y':
send('192.168.126.128', 7001, t3)
分析
分析的版本为10.3.6
Weblogic判断协议过程
断点下在server/lib/weblogic.jar/weblogic/socket/PosixSocketMuxer.class
的第129行,如图:
之后一直调试,直到server/lib/weblogic.jar/weblogic/socket/SocketMuxer.class
第643行var1.isMessageComplete()
,如图:
该方法经反编译后的代码如下:
public boolean isMessageComplete() {
int var1 = 0;
for(int var2 = 0; var2 < this.handlers.length; ++var2) {
ProtocolHandler var3 = this.handlers[var2];
if (var3.claimSocket(this.head)) {
this.claimedIndex = var2;
break;
}
var1 = Math.max(var1, var3.getHeaderLength());
}
if (this.availBytes < var1) {
return false;
} else if (this.claimedIndex < 0) {
SocketLogger.logConnectionRejected(this.channels[0].getChannelName());
SocketMuxer.getMuxer().deliverHasException(this.getSocketFilter(), new ProtocolException("Incoming socket: '" + this.getSocket() + "' has unhandled protocol prefix"));
return false;
} else {
return true;
}
}
this.headers
中存储着weblogic规定的协议,this.head
中存储着我们发送的数据,claimSocket
方法用来判断我们发送的数据属于哪种协议,其反编译后的代码如下:
public boolean claimSocket(Chunk var1) {
return this.claimSocket(var1, "GIOP");
}
GIOP
就是协议的名字,this.claimSocket
反编译后的代码如下:
protected boolean claimSocket(Chunk var1, String var2) {
int var3 = var2.length();
if (var1.end < var3) {
return false;
} else {
byte[] var4 = var1.buf;
for(int var5 = 0; var5 < var3; ++var5) {
if (var4[var5] != var2.charAt(var5)) {
return false;
}
}
return true;
}
}
很简单,大概意思就是比较前几位是不是为指定的字符(比如判断前4位是否为GIOP
),根据判断协议的不同,该函数也会变。
最后当发送的数据不符合IIOP、T3、LDAP、SNMP所规定的形式时,就会被归类到HTTP去
weblogic对T3协议的处理
在判断了发送的数据是什么协议之后,会通过dispatch()
(server/lib/weblogic.jar/weblogic/socket/MuxableSocketDiscriminator
,74行)去获取真正的协议名:
然后在maybeFilter
中根据系统设置判断是否要更换一下协议名:
之后提取我们发送的信息中的版本号、AS、HL信息(weblogic/rjvm/t3/MuxableSocketT3.class
中readBootstrapMessage
方法)
然后在weblogic/socket/Login.class
中的connectReplyOK
中构造我们看到的HELO
等信息,并将它们传回来(可能会出现刚发完HELO
就断开连接的情况,可以视自己手速加一下sleep):