PageRenderTime 56ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/isrcore/shellz.pm

http://isr-evilgrade.googlecode.com/
Perl | 547 lines | 426 code | 35 blank | 86 comment | 19 complexity | c7d0543067d17d0e7c5f29a14a3de7ff MD5 | raw file
Possible License(s): GPL-2.0
  1. ###############
  2. # shellz.pm
  3. #
  4. # Copyright 2010 Francisco Amato
  5. #
  6. # This file is part of isr-evilgrade, www.infobytesec.com .
  7. #
  8. # isr-evilgrade is free software; you can redistribute it and/or modify
  9. # it under the terms of the GNU General Public License as published by
  10. # the Free Software Foundation version 2 of the License.
  11. #
  12. # isr-evilgrade is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. # GNU General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU General Public License
  18. # along with isr-evilgrade; if not, write to the Free Software
  19. # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  20. #
  21. # '''
  22. ##
  23. package isrcore::shellz;
  24. use strict;
  25. #internal modules
  26. use base qw(isrcore::Shell);
  27. use isrcore::webserver;
  28. use isrcore::main;
  29. use isrcore::ASCIITable;
  30. use isrcore::dnsserver;
  31. #external modules
  32. use Data::Dump qw(dump);
  33. #ignore child's process to avoid zombie
  34. $SIG{CHLD} = 'IGNORE';
  35. ##########################################################################
  36. # FUNCTION init
  37. # RECEIVES
  38. # RETURNS
  39. # EXPECTS
  40. # DOES class initialize
  41. my $ppid=0;
  42. sub init {
  43. my $self = shift;
  44. my $webserver = isrcore::webserver->new();
  45. my $dnsserver = isrcore::dnsserver->new();
  46. my $isrmain = isrcore::main->new();
  47. if( $shellz::ppid == 0 )
  48. {
  49. $shellz::ppid= getppid();
  50. }
  51. #Loadmodules
  52. my $ret = $isrmain->loadmodules();
  53. if ($ret != 1){ # loadmodules error
  54. $isrmain->println($ret);
  55. exit;
  56. }
  57. $self->{'dnsserver'}=$dnsserver;
  58. $self->{'webserver'}=$webserver;
  59. $self->{'isrmain'}=$isrmain;
  60. $self->{'VERSION'}="2.0.1";
  61. $self->{'path'}="";
  62. $self->{'prompt'}="evilgrade";
  63. $self->{'change'}=0;
  64. }
  65. ##########################################################################
  66. # FUNCTION prompt_str
  67. # RECEIVES
  68. # RETURNS
  69. # EXPECTS
  70. # DOES return shell's prompt
  71. sub prompt_str {
  72. my $self =shift;
  73. my $prompt = $self->{'prompt'};
  74. if ($self->{'path'}){
  75. $prompt .= "($self->{'path'})";
  76. }
  77. $prompt .= ">";
  78. "$prompt"
  79. } #()
  80. ##########################################################################
  81. # SHELLS COMMANDS
  82. ##########################################################################
  83. ##########################################################################
  84. # FUNCTION run_show
  85. # RECEIVES cmd
  86. # RETURNS
  87. # EXPECTS
  88. # DOES show [object]'s information
  89. sub run_show {
  90. my $self = shift;
  91. my ($cmd) = @_;
  92. my $mods=0;
  93. if ($cmd eq "modules"){
  94. $self->{'isrmain'}->ptitle("List of modules");
  95. foreach my $module (sort(keys %{$self->{'isrmain'}->{'modules'}})){
  96. $self->{'isrmain'}->println("$module\n");
  97. $mods++;
  98. }
  99. $self->{'isrmain'}->println("- $mods modules available.\n\n");;
  100. $self->{'isrmain'}->println("\n");
  101. }elsif ($cmd eq "status"){
  102. $self->run_status($self);
  103. }elsif ($cmd eq "version"){
  104. $self->run_version($self);
  105. }elsif ($cmd eq "vhosts"){
  106. $self->run_vhosts($self);
  107. }elsif ($cmd eq "active"){
  108. $self->{'isrmain'}->ptitle("List of actived modules");
  109. foreach my $module (@{$self->{'webserver'}->{'current'}}){
  110. $self->{'isrmain'}->println("$module\n");
  111. $mods++;
  112. }
  113. $self->{'isrmain'}->println("- $mods modules loaded.\n\n");;
  114. $self->{'isrmain'}->println("\n");
  115. }elsif ($cmd eq "options"){
  116. $self->{'isrmain'}->ptitle("Display options");
  117. my $object;
  118. if ($self->{'path'}){
  119. $object = $self->{'isrmain'}->{'modules'}->{$self->{'path'}}->{'Base'};
  120. $self->{'isrmain'}->println("Name = $object->{'name'}\n");
  121. $self->{'isrmain'}->println("Version = $object->{'version'}\n");
  122. $self->{'isrmain'}->println("Author = ".dump($object->{'author'})."\n");
  123. $self->{'isrmain'}->println("Description = ".dump($object->{'description'})."\n");
  124. $self->{'isrmain'}->println("VirtualHost = ".dump($object->{'vh'})."\n\n");
  125. }else{
  126. $object = $self->{'isrmain'}->{'Base'};
  127. }
  128. my $t = new isrcore::ASCIITable;
  129. $t->setCols(['Name','Default','Description']);
  130. foreach my $module (keys %{$object->{'options'}}){
  131. if (!$object->{'options'}->{$module}->{'hidden'}){ #Verify if it's a hidden option
  132. $t->addRow($module,$object->{'options'}->{$module}->{'val'},$object->{'options'}->{$module}->{'desc'});
  133. }
  134. }
  135. $self->{'isrmain'}->println($t->draw()."\n");
  136. }
  137. }
  138. ##########################################################################
  139. # FUNCTION run_set
  140. # RECEIVES cmd,value
  141. # RETURNS
  142. # EXPECTS
  143. # DOES configure option
  144. sub run_set {
  145. my $self = shift;
  146. my ($cmd,$value) = @_;
  147. $self->{'isrmain'}->println("set $cmd, $value\n");
  148. my $object;
  149. if ($self->{'path'}){
  150. $object = \$self->{'isrmain'}->{'modules'}->{$self->{'path'}}->{'Base'}->{'options'};
  151. }else{
  152. $object = \$self->{'isrmain'}->{'Base'}->{'options'};
  153. }
  154. if (!$cmd){
  155. $self->{'isrmain'}->println("(*) Please specify option name\n");
  156. return
  157. }else{
  158. if (!exists($$object->{$cmd})){
  159. $self->{'isrmain'}->println("(*) Option name ($cmd) did not exists\n");
  160. return
  161. }else {
  162. $self->{'change'}=1;
  163. $$object->{$cmd}->{'val'} =$value; #TODO: check exists val
  164. #TODO: Message required webserver restart
  165. }
  166. }
  167. }
  168. ##########################################################################
  169. # FUNCTION run_configure
  170. # RECEIVES cmd
  171. # RETURNS
  172. # EXPECTS
  173. # DOES configure modules
  174. sub run_configure {
  175. my $self = shift;
  176. my ($cmd) = @_;
  177. if ($cmd){
  178. if (!exists($self->{'isrmain'}->{'modules'}->{$cmd})){
  179. $self->{'isrmain'}->println("(*) Module name ($cmd) did not exists\n");
  180. return
  181. }
  182. $self->{'path'}=$cmd
  183. }else {
  184. $self->{'path'}="";
  185. }
  186. }
  187. ##########################################################################
  188. # FUNCTION run_vhosts
  189. # RECEIVES cmd
  190. # RETURNS
  191. # EXPECTS
  192. # DOES display vhosts available
  193. sub run_vhosts{
  194. my $self = shift;
  195. my ($cmd) = @_;
  196. $self->{'isrmain'}->ptitle("Virtual hosts");
  197. print $self->{'isrmain'}->println(dump($self->{'dnsserver'}->{'Base'}->{'domains'}));
  198. }
  199. ##########################################################################
  200. # FUNCTION run_version
  201. # RECEIVES cmd
  202. # RETURNS
  203. # EXPECTS
  204. # DOES display console version
  205. sub run_version{
  206. my $self = shift;
  207. my ($cmd) = @_;
  208. $self->{'isrmain'}->println("version " . $self->{'VERSION'}."\n");
  209. }
  210. ##########################################################################
  211. # FUNCTION run_reload
  212. # RECEIVES
  213. # RETURNS
  214. # EXPECTS
  215. # DOES reload modules
  216. sub run_reload {
  217. my $self = shift;
  218. $self->{'isrmain'}->println("reload\n");
  219. $self->{'isrmain'}->loadmodules();
  220. }
  221. ##########################################################################
  222. # FUNCTION run_start
  223. # RECEIVES
  224. # RETURNS
  225. # EXPECTS
  226. # DOES start servers
  227. sub run_start {
  228. my $self = shift;
  229. my ($cmd) = @_;
  230. start_server( $self, "webserver",$cmd);
  231. start_server( $self, "dnsserver",$cmd) unless ( $self->{'isrmain'}->{'Base'}->{'options'}->{'DNSEnable'}->{'val'} == 0 );
  232. }
  233. sub start_server {
  234. my $self = shift;
  235. my $server_type = shift;
  236. my ($cmd) = @_;
  237. if ($self->{$server_type}->status() ){
  238. $self->{'isrmain'}->println("$self->{$server_type}->{'Base'}->{'whoami'} : (pid $self->{$server_type}->{'Base'}->{'child'}) already running\n");
  239. return;
  240. }
  241. my $response = $self->{$server_type}->loadconfig($self->{'isrmain'});
  242. if ($response != 1){ #error loadconfig
  243. $self->{'isrmain'}->println($response);
  244. return;
  245. }
  246. if( $server_type == "webserver" ){
  247. #solo para webserver esto
  248. $self->{'comm'}->{'parent'} = $self->{'parent'};
  249. $self->{'comm'}->{'child'} = $self->{'child'};
  250. }
  251. my $child;
  252. my $line;
  253. # crear el fork para salir
  254. die "Can't fork: $!" unless defined ($child = fork());
  255. if ($child==0) {
  256. my $line;
  257. $self->{$server_type}->start($self);
  258. if ($self->{$server_type}->{'Base'}->{'error'}){
  259. $self->{'isrmain'}->println("\n\nError: $self->{$server_type}->{'Base'}->{'error'}\n");
  260. }
  261. exit 0;
  262. }
  263. $self->{$server_type}->{'Base'}->{'child'} = $child;
  264. }
  265. ##########################################################################
  266. # FUNCTION run_status
  267. # RECEIVES
  268. # RETURNS
  269. # EXPECTS
  270. # DOES display servers status
  271. sub get_status {
  272. my $self = shift;
  273. my $server_type = shift;
  274. if ($self->{$server_type}->status()){
  275. $self->{'isrmain'}->println("$self->{$server_type}->{'Base'}->{'whoami'} : (pid $self->{$server_type}->{'Base'}->{'child'}) already running\n");
  276. }
  277. else{
  278. $self->{'isrmain'}->println("$self->{$server_type}->{'Base'}->{'whoami'} : stopped.\n");
  279. }
  280. }
  281. sub run_status{
  282. my $self = shift;
  283. get_status($self,"webserver");
  284. get_status($self,"dnsserver") unless ( $self->{'isrmain'}->{'Base'}->{'options'}->{'DNSEnable'}->{'val'} == 0 );
  285. my $j=0;
  286. $self->{'isrmain'}->ptitle("Users status");
  287. my $t = new isrcore::ASCIITable;
  288. $t->setCols(['Client','Module','Status','Md5,SHA256,Cmd,File']);
  289. foreach my $ip (keys %{$self->{'webserver'}->{'users'}}){
  290. foreach my $module (keys %{$self->{'webserver'}->{'users'}->{$ip}}){
  291. my ($obj,$file) = $self->{'webserver'}->{'users'}->{$ip}->{$module};
  292. $file = $obj->{'file'} if ($obj->{'file'});
  293. $t->addRow($ip,$module,$obj->{'status'},$file);
  294. }
  295. $j++;
  296. }
  297. if ($j){ #object found
  298. $self->{'isrmain'}->println($t->draw()."\n");
  299. }else{
  300. $self->{'isrmain'}->println("[*] Waiting users..\n")
  301. }
  302. }
  303. ##########################################################################
  304. # FUNCTION run_stop
  305. # RECEIVES
  306. # RETURNS
  307. # EXPECTS
  308. # DOES stop servers
  309. sub stop_server {
  310. my $self = shift;
  311. my $server_type = shift;
  312. if ($self->{$server_type}->status()){
  313. $self->{$server_type}->stop();
  314. $self->{'isrmain'}->println("Stopping $self->{$server_type}->{'Base'}->{'whoami'} [OK]\n");
  315. }
  316. else{
  317. $self->{'isrmain'}->println("$self->{$server_type}->{'Base'}->{'whoami'} : stopped\n");
  318. }
  319. }
  320. sub run_stop {
  321. my $self = shift;
  322. stop_server($self,"webserver");
  323. stop_server($self,"dnsserver") unless ( $self->{'isrmain'}->{'Base'}->{'options'}->{'DNSEnable'}->{'val'} == 0 );
  324. }
  325. ##########################################################################
  326. # FUNCTION run_restart
  327. # RECEIVES
  328. # RETURNS
  329. # EXPECTS
  330. # DOES restart servers
  331. sub run_restart {
  332. my $self = shift;
  333. $self->run_stop();
  334. $self->run_start();
  335. }
  336. ##########################################################################
  337. # FUNCTION run_exit
  338. # RECEIVES
  339. # RETURNS
  340. # EXPECTS
  341. # DOES exit console
  342. sub run_exit {
  343. my $self = shift;
  344. if( getppid() == $shellz::ppid ){
  345. $self->run_stop();
  346. kill KILL => $self->{pid};
  347. $self->{on_signal}=1;
  348. $self->stoploop();
  349. $self->SUPER::DESTROY;
  350. system("reset");
  351. }
  352. # $self->SUPER::DESTROY;
  353. # require Term::Screen;
  354. # my $terminal = new Term::Screen;
  355. # $terminal->clrscr();
  356. # $terminal::DESTROY;
  357. # sleep 2;
  358. exit 0;
  359. }
  360. ##########################################################################
  361. # FUNCTION console_cmd
  362. # RECEIVES xml cmd command
  363. # RETURNS
  364. # EXPECTS
  365. # DOES communication commands between thread and parent (called from Shell)
  366. sub console_cmd {
  367. my $self = shift;
  368. my ($cmd) = @_;
  369. my ($action,$module,$ip,$file);
  370. #TODO: Move to object
  371. my $action =$1 if $cmd =~ /\<action\>([\w]+)\<\/action\>/;
  372. my $module =$1 if $cmd =~ /\<module\>([\w\:\_\-]+)\<\/module\>/;
  373. my $ip =$1 if $cmd =~ /\<ip\>([\d\.]+)\<\/ip\>/;
  374. my $file =$1 if $cmd =~ /<file\>([\w\W]+)\<\/file\>/;
  375. my $md5 =$1 if $cmd =~ /<md5\>([\w\W]+)\<\/md5\>/;
  376. my $sha256 =$1 if $cmd =~ /<sha256\>([\w\W]+)\<\/sha256\>/;
  377. my $cwd =$1 if $cmd =~ /<cmd\>([\w\W]+)\<\/cmd\>/;
  378. my $tfile=$self->{'webserver'}->{'users'}->{$ip}->{$module}->{'file'};
  379. $self->{'webserver'}->{'users'}->{$ip}->{$module}->{'status'}=$action if ($action);
  380. if ($file) {
  381. $self->{'webserver'}->{'users'}->{$ip}->{$module}->{'file'}=($tfile) ? "$tfile\n$md5,$sha256,'$cwd',$file" :"$md5,$sha256,'$cwd',$file";
  382. }
  383. }
  384. ##########################################################################
  385. ## HELP
  386. ##########################################################################
  387. sub smry_show {"Display information of <object>."}
  388. sub smry_version {"Display framework version."}
  389. sub smry_set {"Configure variables"}
  390. sub smry_configure {"Configure <module-name>"}
  391. sub smry_reload {"Reload to update all the modules"}
  392. sub smry_start {"Start webserver"}
  393. sub smry_status {"Get webserver status"}
  394. sub smry_stop {"Stop webserver"}
  395. sub smry_restart {"Restart webserver"}
  396. sub smry_vhosts {"Show vhosts enable"}
  397. sub help_show {
  398. my ($o,$cmd) = @_;
  399. <<'END';
  400. Display information of <object>
  401. END
  402. }
  403. ##########################################################################
  404. ## AUTOCOMPLETE
  405. ##########################################################################
  406. ##########################################################################
  407. # FUNCTION comp_show
  408. # RECEIVES
  409. # RETURNS
  410. # EXPECTS
  411. # DOES autocomplete command show
  412. sub comp_show{
  413. my ($o, $word, $line, $start) = @_;
  414. my @comp = ('modules','active','options','status','version','vhosts');
  415. @comp = sort @comp;
  416. @comp;
  417. }
  418. ##########################################################################
  419. # FUNCTION comp_configure
  420. # RECEIVES
  421. # RETURNS
  422. # EXPECTS
  423. # DOES autocomplete command configure
  424. sub comp_configure {
  425. my ($o, $word, $line, $start) = @_;
  426. my @comp = keys %{$o->{'isrmain'}->{'modules'}};
  427. @comp = sort @comp;
  428. @comp;
  429. }
  430. ##########################################################################
  431. # FUNCTION gtime
  432. # RECEIVES
  433. # RETURNS parsed time string
  434. # EXPECTS
  435. # DOES get parsed localtime
  436. sub gtime{
  437. my @t = localtime(time);
  438. return "[".$t[3]."/".(int($t[4])+1)."/".(int($t[5])+1900).":".$t[2].":".$t[1].":".$t[0]."] - ";
  439. }
  440. ##########################################################################
  441. ## PUBLIC FUNCTIONS
  442. ##########################################################################
  443. ##########################################################################
  444. # FUNCTION printshell
  445. # RECEIVES msg
  446. # RETURNS
  447. # EXPECTS message,debug,time
  448. # DOES print information to the console thread
  449. sub printshell{
  450. my $self = shift;
  451. my ($msg,$debug,$time) = @_;
  452. #return if
  453. return if ($debug && $self->{'isrmain'}->{'Base'}->{'options'}->{'debug'}->{'val'} == 0);
  454. local *PARENT = $self->{'comm'}->{'parent'};
  455. my $data;
  456. $data=$self->gtime if (!$time);
  457. $data .= "[DEBUG] - " if ($debug);
  458. $data .=$msg;
  459. print PARENT $data;
  460. sleep 1;
  461. }
  462. ##########################################################################
  463. # FUNCTION sendcommand
  464. # RECEIVES msg
  465. # RETURNS
  466. # EXPECTS
  467. # DOES send internal command between child and parent
  468. sub sendcommand{
  469. my $self = shift;
  470. my ($msg) = @_;
  471. local *PARENT = $self->{'comm'}->{'parent'};
  472. print PARENT $msg;
  473. }
  474. 1;