http://qs321.pair.com?node_id=912016


in reply to Find and replace MD5 hash from file

I can see two problems with your system command: (1) parts of your hashed password strings contain $ signs which will be interpreted by the shell as environment variables. (2) If you then single quote your s/// expression to protect from shell interpolation, those same $ signs are interpreted as variables by Perl; the slashes are also interpreted by Perl. So replace this:

system("ssh -o StrictHostKeyChecking=no root\@localhost /usr/bin/perl +-p -i -e s/$hash2/$hash1/ee ha +shfile")

with this:

system("ssh -o StrictHostKeyChecking=no root\@localhost /usr/bin/perl +-p -i -e 's/\Q$hash2\E/\Q$hash1\E/' ha +shfile")

Replies are listed 'Best First'.
Re^2: Find and replace MD5 hash from file
by ikegami (Patriarch) on Jun 29, 2011 at 19:32 UTC

    If you then single quote your s/// expression to protect from shell interpolation

    Adding single quotes does not protect from shell interpolation.

    That will fail if $hash1 or $hash2 can contain «'», I don't think that's possible, but I don't know for sure.

    That's why I use

    $s =~ s/'/'\\''/g; return "'$s'";

    instead of

    return "'$s'";

    Update: philipbailey has since pointed out that the hash cannot contains quotes. While you can't context text to a shell literal using the second snippet in general, it appears to be safe in this particular circumstance.

      We've had this conversation before, ikegami. In this case the OP's base64-encoded strings never contain single quotes.

      Update: this is clarified in later nodes in this thread. The OP's output largely consists of base-64 strings together with 4 other (non-quote) characters, explained below.

        The OP doesn't have base64-encoded strings. He's got hashes which include base64 strings. They are not base64 strings, and I don't know if they can contain quotes or not.

        As for your comment about having this discussion before, it makes no sense. I'm telling the OP that just adding single quotes is not always acceptable, and I'm sure I've never told this to him before since he's never posted here before.

        You are probably referring to the thread where you recommended a buggy version of

        my $passwd_lit = $passwd; my $path_lit = $path; s#'#'\\''#g for $passwd_lit, $path_lit; system("mysqldump --add-drop-table -uroot -p'$passwd_lit' mydatabase | + gzip -9c > '$path_lit'");

        over

        my ($passwd_lit, $path_lit) = map text_to_shell_lit, $passwd, $path; system("mysqldump --add-drop-table -uroot -p$passwd_lit mydatabase | g +zip -9c > $path_lit");

        But that makes no sense either since you didn't use that code.