Advertisement
Guest User

Untitled

a guest
Oct 25th, 2013
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 4.16 KB | None | 0 0
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4.  
  5. use DBI;
  6. use POE qw(Component::IRC::State);
  7.  
  8. my $own_nick = shift;
  9.  
  10. # SQL
  11. my $dbh = DBI->connect(
  12.   'DBI:mysql:bot',
  13.   'bot',
  14.   '',
  15.   {'mysql_auto_reconnect' => 1}
  16. ) or die 'DBI: ' . $DBI::errstr;
  17.  
  18. # IRC
  19. my $irc = POE::Component::IRC->spawn(
  20.   nick => $own_nick,
  21.   ircname => 'servotron',
  22.   server => '127.0.0.1',
  23.   port => 6667,
  24. ) or die 'POE::Component::IRC: ' . $!;
  25.  
  26. POE::Session->create(
  27.   package_states => [ main => [ qw(_start irc_msg) ] ],
  28.   heap => { irc => $irc }
  29. );
  30.  
  31. $poe_kernel->run();
  32.  
  33. sub _start {
  34.   $irc->yield(register => 'all');
  35.   $irc->yield(connect => {});
  36. }
  37.  
  38. sub irc_msg {
  39.   my ($sender, $who, $recipients, $what) = @_[SENDER, ARG0 .. ARG2];
  40.   my $nick = (split /!/, $who)[0];
  41.  
  42.   open(LOG, ">> /home/bot/logs/" . $own_nick . ".txt");
  43.   print LOG $who . ': ' . $what . "\n";
  44.   close(LOG);
  45.  
  46.   $irc->yield(privmsg => $nick => answer($what));
  47. }
  48.  
  49. sub answer {
  50.   # To make it more interesting I split the userinput at whitespaces. This way
  51.   # the attacker can not use them in the injection. Not hard to bypass though.
  52.   my @what = split /\s/, shift;
  53.  
  54.   # Now let's parse the input.
  55.   my $output;
  56.  
  57.   if (($#what == 0) && ($what[0] eq "credits")) {
  58.     $output = 'All hail to our robotic overlord lama \0/';
  59.   }
  60.   elsif (($#what == 0) && ($what[0] eq "help")) {
  61.     $output = 'help; details [movie id]; search [keyword]; add movie [title]; add robot [movie id] [name]';
  62.   }
  63.   elsif (($#what == 1) && ($what[0] eq "details")) {
  64.     $output = details_request($what[1]);
  65.   }
  66.   elsif (($#what == 1) && ($what[0] eq "search")) {
  67.     $output = search_request($what[1]);
  68.   }
  69.   elsif (($#what == 2) && ($what[0] eq "add") && ($what[1] eq "movie")) {
  70.     $output = add_movie_request($what[2]);
  71.   }
  72.   elsif (($#what == 3) && ($what[0] eq "add") && ($what[1] eq "robot")) {
  73.     $output = add_actor_request($what[2], $what[3]);
  74.   }
  75.  
  76.   if ($output) {
  77.     return $output;
  78.   }
  79.   else {
  80.     return '?SYNTAX ERROR';
  81.   }
  82. }
  83.  
  84. sub search_request {
  85.   my $keyword = shift;
  86.  
  87.   my $query = $dbh->prepare(
  88.     "SELECT movies.id, movies.title FROM movies WHERE movies.title LIKE ? LIMIT 5"
  89.   ) or return 0;
  90.  
  91.   $query->execute('%' . $keyword . '%') or return 0;
  92.  
  93.   if ($query->rows == 0) {
  94.     return '?OUT OF DATA';
  95.   }
  96.  
  97.   my $output = '';
  98.  
  99.   while (my ($id, $title) = $query->fetchrow_array()) {
  100.     $output .= $id . ': ' . $title . '; ';
  101.   }
  102.  
  103.   return $output;
  104. }
  105.  
  106. sub details_request {
  107.   my $movie_id = shift;
  108.  
  109.   # Sleep crashes the bot, so sadly I have to block it.
  110.   return 0 if ($movie_id =~ /(sleep|benchmark)/i);
  111.  
  112.   # Get the total number of actors for this movie. Here's the bug.
  113.   my $query1 = $dbh->prepare(
  114.     "SELECT COUNT(foo.id) AS cid FROM (\n" .
  115.       "SELECT actors.id FROM actors WHERE (actors.movie = '" . $movie_id . "')\n" .
  116.     ") foo"
  117.   ) or return 0;
  118.  
  119.   $query1->execute() or return 0;
  120.  
  121.   my ($count) = $query1->fetchrow_array();
  122.  
  123.   # Get the movie title.
  124.   my $query2 = $dbh->prepare(
  125.     "SELECT movies.title FROM movies WHERE movies.id = ?"
  126.   ) or return 0;
  127.  
  128.   $query2->execute($movie_id) or return 0;
  129.  
  130.   if ($query2->rows == 0) {
  131.     return '?OUT OF DATA';
  132.   }
  133.  
  134.   my ($title) = $query2->fetchrow_array();
  135.   my $output = $title . ': ';
  136.  
  137.   # Get the last 5 added robots of that movie.
  138.   my $query3 = $dbh->prepare(
  139.     "SELECT actors.name FROM actors WHERE actors.movie = ? ORDER BY actors.id DESC LIMIT 5"
  140.   ) or return 0;
  141.  
  142.   $query3->execute($movie_id) or return 0;
  143.  
  144.   if ($query3->rows > 0) {
  145.     while (my ($name) = $query3->fetchrow_array()) {
  146.       $output .= $name . '; ';
  147.     }
  148.   }
  149.  
  150.   # Add the total number of robots (the limitation makes the seperate total count realistic).
  151.   return $output . '(' . $count . ' total)';
  152. }
  153.  
  154. sub add_movie_request {
  155.   my $title = shift;
  156.  
  157.   my $query = $dbh->prepare('INSERT INTO movies (`title`) VALUES (?)');
  158.   $query->execute($title) or return 0;
  159.  
  160.   return '!OK';
  161. }
  162.  
  163. sub add_actor_request {
  164.   my $movie_id = shift;
  165.   my $name = shift;
  166.  
  167.   my $query = $dbh->prepare('INSERT INTO actors (`movie`, `name`) VALUES (?, ?)');
  168.   $query->execute($movie_id, $name) or return 0;
  169.  
  170.   return '!OK';
  171. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement