RecordDetailFragment.java 15 KB

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