RecordDetailFragment.java 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511
  1. package de.tudarmstadt.informatik.hostage.ui.fragment;
  2. import java.io.File;
  3. import java.io.FileOutputStream;
  4. import java.io.IOException;
  5. import java.util.ArrayList;
  6. import java.util.Date;
  7. import java.util.regex.Matcher;
  8. import java.util.regex.Pattern;
  9. import android.app.Activity;
  10. import android.app.AlertDialog;
  11. import android.content.Context;
  12. import android.content.DialogInterface;
  13. import android.content.SharedPreferences;
  14. import android.os.Bundle;
  15. import android.os.Environment;
  16. import android.preference.PreferenceManager;
  17. import android.text.format.DateFormat;
  18. import android.view.LayoutInflater;
  19. import android.view.Menu;
  20. import android.view.MenuInflater;
  21. import android.view.MenuItem;
  22. import android.view.MotionEvent;
  23. import android.view.View;
  24. import android.view.ViewGroup;
  25. import android.widget.Button;
  26. import android.widget.ImageButton;
  27. import android.widget.LinearLayout;
  28. import android.widget.ScrollView;
  29. import android.widget.TextView;
  30. import android.widget.Toast;
  31. import de.tudarmstadt.informatik.hostage.R;
  32. import de.tudarmstadt.informatik.hostage.logging.Record;
  33. import de.tudarmstadt.informatik.hostage.ui.model.LogFilter;
  34. import de.tudarmstadt.informatik.hostage.ui.activity.MainActivity;
  35. import de.tudarmstadt.informatik.hostage.logging.MessageRecord;
  36. import de.tudarmstadt.informatik.hostage.persistence.HostageDBOpenHelper;
  37. /**
  38. * Displays detailed informations about an record.
  39. *
  40. * @author Fabio Arnold
  41. * @author Alexander Brakowski
  42. * @author Julien Clauter
  43. */
  44. public class RecordDetailFragment extends UpNavigatibleFragment {
  45. /**
  46. * Hold the record of which the detail informations should be shown
  47. */
  48. private Record mRecord;
  49. /**
  50. * The database helper to retrieve data from the database
  51. */
  52. public HostageDBOpenHelper mDBOpenHelper;
  53. /**
  54. * The layout inflater
  55. */
  56. private LayoutInflater mInflater;
  57. /*
  58. * References to the views in the layout
  59. */
  60. private View mRootView;
  61. private LinearLayout mRecordOverviewConversation;
  62. private TextView mRecordDetailsTextAttackType;
  63. private TextView mRecordDetailsTextSsid;
  64. private TextView mRecordDetailsTextBssid;
  65. private TextView mRecordDetailsTextRemoteip;
  66. private TextView mRecordDetailsTextProtocol;
  67. private ImageButton mRecordDeleteButton;
  68. public SharedPreferences pref;
  69. public int port;
  70. public StringBuilder portArray;
  71. /**
  72. * Sets the record of which the details should be displayed
  73. * @param rec the record to be used
  74. */
  75. public void setRecord(Record rec) {
  76. this.mRecord = rec;
  77. }
  78. /**
  79. * Retriebes the record which is used for the display of the detail informations
  80. * @return the record
  81. */
  82. public Record getRecord() {
  83. return this.mRecord;
  84. }
  85. /**
  86. * Retrieves the id of the layout
  87. * @return the id of the layout
  88. */
  89. public int getLayoutId() {
  90. return R.layout.fragment_record_detail;
  91. }
  92. /**
  93. * {@inheritDoc}
  94. */
  95. @Override
  96. public void onCreate(Bundle savedInstanceState) {
  97. super.onCreate(savedInstanceState);
  98. setHasOptionsMenu(true);
  99. pref = PreferenceManager.getDefaultSharedPreferences(this.getActivity());
  100. }
  101. /**
  102. * {@inheritDoc}
  103. */
  104. @Override
  105. public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
  106. super.onCreateView(inflater, container, savedInstanceState);
  107. mInflater = inflater;
  108. getActivity().setTitle(mRecord.getSsid());
  109. this.mDBOpenHelper = new HostageDBOpenHelper(this.getActivity().getBaseContext());
  110. this.mRootView = inflater.inflate(this.getLayoutId(), container, false);
  111. this.assignViews(mRootView);
  112. this.configurateRootView(mRootView);
  113. return mRootView;
  114. }
  115. /**
  116. * {@inheritDoc}
  117. */
  118. @Override
  119. public void onStart() {
  120. super.onStart();
  121. }
  122. /**
  123. * Retrieves all the views from the given view
  124. *
  125. * @param view the layout view
  126. */
  127. private void assignViews(View view) {
  128. mRecordOverviewConversation = (LinearLayout) view.findViewById(R.id.record_overview_conversation);
  129. mRecordDetailsTextAttackType = (TextView) view.findViewById(R.id.record_details_text_attack_type);
  130. mRecordDetailsTextSsid = (TextView) view.findViewById(R.id.record_details_text_ssid);
  131. mRecordDetailsTextBssid = (TextView) view.findViewById(R.id.record_details_text_bssid);
  132. mRecordDetailsTextRemoteip = (TextView) view.findViewById(R.id.record_details_text_remoteip);
  133. mRecordDetailsTextProtocol = (TextView) view.findViewById(R.id.record_details_text_protocol);
  134. mRecordDeleteButton = (ImageButton) view.findViewById(R.id.DeleteButton);
  135. }
  136. /**
  137. * Configures the given view and fills it with the detail information
  138. *
  139. * @param rootView the view to use to display the informations
  140. */
  141. private void configurateRootView(View rootView) {
  142. mRecordDetailsTextAttackType.setText(mRecord.getWasInternalAttack() ? R.string.RecordInternalAttack : R.string.RecordExternalAttack);
  143. mRecordDetailsTextBssid.setText(mRecord.getBssid());
  144. mRecordDetailsTextSsid.setText(mRecord.getSsid());
  145. if (mRecord.getRemoteIP() != null)
  146. mRecordDetailsTextRemoteip.setText(mRecord.getRemoteIP() + ":" + mRecord.getRemotePort());
  147. mRecordDetailsTextProtocol.setText(mRecord.getProtocol());
  148. ArrayList<Record> conversation = this.mDBOpenHelper.getConversationForAttackID(mRecord.getAttack_id());
  149. // display the conversation of the attack
  150. for (Record r : conversation) {
  151. View row;
  152. String from = r.getLocalIP() == null ? "-" : r.getLocalIP() + ":" + r.getLocalPort();
  153. String to = r.getRemoteIP() == null ? "-" : r.getRemoteIP() + ":" + r.getRemotePort();
  154. if (r.getType() == MessageRecord.TYPE.SEND) {
  155. row = mInflater.inflate(R.layout.fragment_record_conversation_sent, null);
  156. } else {
  157. row = mInflater.inflate(R.layout.fragment_record_conversation_received, null);
  158. String tmp = from;
  159. from = to;
  160. to = tmp;
  161. }
  162. TextView conversationInfo = (TextView) row.findViewById(R.id.record_conversation_info);
  163. TextView conversationContent = (TextView) row.findViewById(R.id.record_conversation_content);
  164. conversationContent.setOnTouchListener(new View.OnTouchListener() {
  165. @Override
  166. public boolean onTouch(final View v, final MotionEvent motionEvent) {
  167. if (v.getId() == R.id.record_conversation_content) {
  168. if (v.canScrollVertically(1) || v.canScrollVertically(-1)) { // if the view is scrollable
  169. v.getParent().requestDisallowInterceptTouchEvent(true);
  170. switch (motionEvent.getAction() & MotionEvent.ACTION_MASK) {
  171. case MotionEvent.ACTION_UP:
  172. v.getParent().requestDisallowInterceptTouchEvent(false);
  173. break;
  174. }
  175. }
  176. }
  177. return false;
  178. }
  179. });
  180. Date date = new Date(r.getTimestamp());
  181. conversationInfo.setText(String.format(getString(R.string.record_details_info), from, to, getDateAsString(date), getTimeAsString(date)));
  182. if (r.getPacket() != null)
  183. conversationContent.setText(r.getPacket());
  184. mRecordOverviewConversation.addView(row);
  185. }
  186. mRecordDeleteButton.setOnClickListener(new View.OnClickListener() {
  187. @Override
  188. public void onClick(View v) {
  189. Activity activity = getActivity();
  190. if (activity == null) {
  191. return;
  192. }
  193. new AlertDialog.Builder(getActivity())
  194. .setTitle(android.R.string.dialog_alert_title)
  195. .setMessage(R.string.record_details_confirm_delete)
  196. .setPositiveButton(R.string.yes,
  197. new DialogInterface.OnClickListener() {
  198. public void onClick(DialogInterface dialog,
  199. int which) {
  200. mDBOpenHelper.deleteByAttackID(mRecord.getAttack_id());
  201. MainActivity.getInstance().navigateBack();
  202. }
  203. }
  204. ).setNegativeButton(R.string.no, null)
  205. .setIcon(android.R.drawable.ic_dialog_alert).show();
  206. }
  207. });
  208. }
  209. @Override
  210. public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
  211. // Inflate the menu items for use in the action bar
  212. if (mRecord.getProtocol().contains("HTTP")){
  213. inflater.inflate(R.menu.records_detail_actions, menu);
  214. }
  215. else if (mRecord.getProtocol().contains("MODBUS")){
  216. inflater.inflate(R.menu.records_detail_actions, menu);
  217. }
  218. else if (mRecord.getProtocol().contains("MULTISTAGE")){
  219. inflater.inflate(R.menu.records_detail_actions, menu);
  220. }
  221. else if (mRecord.getProtocol().contains("FILE INJECTION")){
  222. inflater.inflate(R.menu.records_detail_actions, menu);
  223. }
  224. }
  225. @Override
  226. public boolean onOptionsItemSelected(MenuItem item) {
  227. switch (item.getItemId()) {
  228. case R.id.bro_sig:
  229. AlertDialog.Builder builder = new AlertDialog.Builder(this.getActivity());
  230. builder.setTitle(MainActivity.getInstance().getString(R.string.bro_signature));
  231. builder.setMessage(MainActivity.getInstance().getString(R.string.bro_message));
  232. builder.setPositiveButton(R.string.generate,
  233. new DialogInterface.OnClickListener() {
  234. public void onClick(DialogInterface dialog,
  235. int which) {
  236. try {
  237. getConversation();
  238. } catch (IOException e) {
  239. e.printStackTrace();
  240. }
  241. //mDBOpenHelper.deleteByAttackID(mRecord.getAttack_id());
  242. MainActivity.getInstance().navigateBack();
  243. }
  244. }
  245. ).setNegativeButton(R.string.cancel, null);
  246. builder.create();
  247. builder.show();
  248. return true;
  249. }
  250. return false;
  251. }
  252. public int protocol2Port(String protocol){
  253. if(protocol.contains("HTTP")){port=80;}
  254. else if(protocol.contains("MODBUS")){port=502;}
  255. else if(protocol.contains("TELNET")){port=23;}
  256. else if(protocol.contains("SMB")){port=80;}
  257. else if(protocol.contains("HTTPS")){port=443;}
  258. else if(protocol.contains("ECHO")){port=7;}
  259. else if(protocol.contains("FTP")){port=21;}
  260. else if(protocol.contains("MySQL")){port=3306;}
  261. else if(protocol.contains("S7COMM")){port=102;}
  262. else if(protocol.contains("SIP")){port=1025;}
  263. else if(protocol.contains("SMTP")){port=25;}
  264. else if(protocol.contains("SNMP")){port=161;}
  265. else if(protocol.contains("SSH")){port=22;}
  266. return port;
  267. }
  268. private void getConversation() throws IOException {
  269. ArrayList<Record> conversation = this.mDBOpenHelper.getConversationForAttackID(mRecord.getAttack_id());
  270. for (Record r : conversation) {
  271. String mydata = r.getPacket();
  272. ArrayList<String> myTokensList = new ArrayList<String>();
  273. String tokens[]=mydata.split("\n");
  274. for (String tok : tokens) {
  275. if (tok.contains("Protocol:")) {
  276. myTokensList.add(tok.split(":")[1]);
  277. }
  278. }
  279. ArrayList<Integer> myPortList = new ArrayList<Integer>();
  280. for (String tok : myTokensList) {
  281. myPortList.add(protocol2Port(tok));
  282. }
  283. System.out.print(myPortList);
  284. if (mRecord.getProtocol().contentEquals("MULTISTAGE")){
  285. String signature = createMultistageSignature(r.getRemoteIP(), myPortList);
  286. createSignatureFile(signature);
  287. }
  288. else if(mRecord.getProtocol().contentEquals("HTTP")){
  289. /*String signature = createHTTPSignature(r.getRemoteIP(), port);
  290. createSignatureFile(signature);*/
  291. }
  292. else if(mRecord.getProtocol().contentEquals("MODBUS")){
  293. /*String signature = createMODBUSSignature(r.getRemoteIP(), port);
  294. createSignatureFile(signature);*/
  295. }
  296. else if(mRecord.getProtocol().contentEquals("FILE INJECTION")){
  297. /*String signature = createFILEINJECTIONSignature(r.getRemoteIP(), port);
  298. createSignatureFile(signature);*/
  299. }
  300. }
  301. }
  302. private String createMultistageSignature(String ip,ArrayList portList) {
  303. int portListSize=0;
  304. StringBuilder portArray = new StringBuilder();
  305. for (Object tok : portList) {
  306. portArray.append(tok+"/tcp");
  307. portListSize++;
  308. if(portListSize!=portList.size()){
  309. portArray.append(",");
  310. }
  311. }
  312. String defaultSignature = "@load base/frameworks/notice\n" +
  313. "\n" +
  314. "\n" +
  315. "\n" +
  316. "export{\n" +
  317. "\tredef enum Notice::Type += {\n" +
  318. "\t\tMultistage\n" +
  319. "\t};\n" +
  320. "}\n" +
  321. "global attack_ip ="+ ip+";\n" +
  322. "global attack_port = set("+portArray+");\n" +
  323. "global attack_count = 0;\n" +
  324. "\n" +
  325. "\n" +
  326. "\n" +
  327. "event connection_established(c: connection)\n" +
  328. "{\n" +
  329. "\n" +
  330. "print fmt (\"Initiating.............\");\n" +
  331. "print c$id$orig_h;\n" +
  332. "print c$id$resp_p;\n" +
  333. "\n" +
  334. "for (i in attack_port){\n" +
  335. "\n" +
  336. "\tif(count==0){\n" +
  337. "\t\t\n" +
  338. "\tif ((c$id$orig_h==attack_ip) && (c$id$resp_p==attack_prot1))\n" +
  339. " {\n" +
  340. "\tprint fmt(\"Inside the loop\");\n" +
  341. " ++attack_count;\n" +
  342. "\tprint attack_count;\n" +
  343. " }\n" +
  344. "\n" +
  345. "\telse{break;}\n" +
  346. "\t}\n" +
  347. "\n" +
  348. " \n" +
  349. "\n" +
  350. "}\n" +
  351. "\n" +
  352. " else {\n" +
  353. "\n" +
  354. " if ((c$id$orig_h==attack_ip) && (c$id$resp_p == attack_prot2)){\n" +
  355. "\t\n" +
  356. "\tprint fmt (\"MULTISTAGE ATTACK!!!\");\n" +
  357. " NOTICE([$note = Multistage,\n" +
  358. " $conn = c,\n" +
  359. " $msg = fmt(\"Multistage Attack! from %s\",c$id$orig_h)]);\n" +
  360. "\tattack_count = 0;\n" +
  361. "\t\n" +
  362. " }\n" +
  363. "\n" +
  364. " }\n" +
  365. "\n" +
  366. "\n" +
  367. "}\n";
  368. return defaultSignature;
  369. }
  370. private void createSignatureFile(String signature) throws IOException {
  371. FileOutputStream sig;
  372. Long tsLong = System.currentTimeMillis() / 1000;
  373. String ts = tsLong.toString();
  374. String fileName = "Bro_sig"+ts+".bro";
  375. String externalLocation = pref.getString("pref_external_location", "");
  376. String root = Environment.getExternalStorageDirectory().toString();
  377. if (root != null && isExternalStorageWritable()) {
  378. File dir = new File(root + externalLocation);
  379. dir.mkdirs();
  380. File file = new File(dir, fileName);
  381. sig = new FileOutputStream(file);
  382. sig.write(signature.getBytes());
  383. sig.write(System.getProperty("line.separator").getBytes());
  384. sig.flush();
  385. sig.close();
  386. Toast.makeText(this.getActivity().getApplicationContext(),"Signature file"+fileName +"created",Toast.LENGTH_LONG).show();
  387. } else {
  388. Toast.makeText(this.getActivity(),"Could not write to SD Card",Toast.LENGTH_SHORT).show();
  389. return;
  390. }
  391. }
  392. private boolean isExternalStorageWritable() {
  393. String state = Environment.getExternalStorageState();
  394. if (Environment.MEDIA_MOUNTED.equals(state)) {
  395. return true;
  396. }
  397. return false;
  398. }
  399. /*****************************
  400. *
  401. * Date Transform
  402. *
  403. * ***************************/
  404. /**
  405. * Converts the given data to an localized string
  406. *
  407. * @param date the date to convert
  408. * @return the converted date as an string
  409. */
  410. private String getDateAsString(Date date) {
  411. return DateFormat.getDateFormat(getActivity()).format(date);
  412. }
  413. /**
  414. * Converts the given date to an localized time
  415. *
  416. * @param date the date to convert
  417. * @return the converted time as an string
  418. */
  419. private String getTimeAsString(Date date) {
  420. return DateFormat.getTimeFormat(getActivity()).format(date);
  421. }
  422. }