Created
July 15, 2020 18:57
-
-
Save qryxip/ec0231554a58574ca99773cef97a1629 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
use anyhow::{ensure, Context as _}; | |
use byteorder::{BigEndian, ReadBytesExt as _}; | |
use easy_ext::ext; | |
use itertools::Itertools as _; | |
use ress::tokens::{IdentExt as _, StringLitExt as _}; | |
use scraper::{Html, Selector}; | |
fn main() -> anyhow::Result<()> { | |
let client = reqwest::blocking::Client::new(); | |
let text = client | |
.get("https://codeforces.com/enter") | |
.send()? | |
.error_for_status()? | |
.text()?; | |
let html = Html::parse_document(&text); | |
html.hage()?; | |
Ok(()) | |
} | |
#[ext] | |
impl Html { | |
fn hage(&self) -> anyhow::Result<()> { | |
use ress::tokens::{Punct, StringLit, Token}; | |
let script = self | |
.select(&Selector::parse("script").unwrap()) | |
.filter(|e| e.value().attr("src").is_none()) | |
.flat_map(|e| e.text()) | |
.exactly_one() | |
.ok() | |
.with_context(|| "Could not find the `<script>`")?; | |
let tokens = ress::tokenize(script).with_context(|| "Could not tokenize the `<script>`")?; | |
let (a, b, c, cookie_attrs) = (|| -> anyhow::Result<_> { | |
let (mut a, mut b, mut c, mut cookie_attrs) = (None, None, None, None); | |
for i in 0..tokens.len() { | |
let tokens = &tokens[i..]; | |
if let [Token::Ident(var_name), Token::Punct(Punct::Equal), Token::Ident(function_name), Token::Punct(Punct::OpenParen), Token::String(string_lit), Token::Punct(Punct::CloseParen), ..] = | |
tokens | |
{ | |
if function_name == "toNumbers" { | |
match var_name.as_str() { | |
"a" => a = Some(hex::decode(string_lit.no_quote())?), | |
"b" => b = Some(hex::decode(string_lit.no_quote())?), | |
"c" => c = Some(hex::decode(string_lit.no_quote())?), | |
_ => {} | |
} | |
} | |
} else if let [Token::Ident(expr_part1), Token::Punct(Punct::Period), Token::Ident(expr_part2), Token::Punct(Punct::Equal), Token::String(string_lit1), Token::Punct(Punct::Plus), Token::Ident(function_name), Token::Punct(Punct::OpenParen), _, _, _, Token::Punct(Punct::OpenParen), _, _, _, _, _, _, _, Token::Punct(Punct::CloseParen), Token::Punct(Punct::CloseParen), Token::Punct(Punct::Plus), Token::String(string_lit2), Token::Punct(Punct::SemiColon), ..] = | |
tokens | |
{ | |
if expr_part1 == "document" | |
&& expr_part2 == "cookie" | |
&& string_lit1.no_quote() == "RCPC=" | |
&& function_name == "toHex" | |
{ | |
cookie_attrs = Some(string_lit2.no_quote()); | |
} | |
} | |
} | |
let a = a.with_context(|| "Could not find the `var a`")?; | |
let b = b.with_context(|| "Could not find the `var b`")?; | |
let c = c.with_context(|| "Could not find the `var c`")?; | |
let cookie_attrs = | |
cookie_attrs.with_context(|| "Could not find the cookie attributes")?; | |
Ok((a, b, c, cookie_attrs)) | |
})() | |
.with_context(|| format!( | |
"===Expected===\n{}======\n===Actual===\n{}\n======", | |
r#"function toNumbers(d) { | |
var e = []; | |
d.replace(/(..)/g, function(d) { | |
e.push(parseInt(d, 16)) | |
}); | |
return e | |
} | |
function toHex() { | |
for (var d = [], d = 1 == arguments.length && arguments[0].constructor == Array ? arguments[0] : arguments, e = "", f = 0; f < d.length; f++) e += (16 > d[f] ? "0" : "") + d[f].toString(16); | |
return e.toLowerCase() | |
} | |
var a = toNumbers("<hex value>"), | |
b = toNumbers("<hex value>"), | |
c = toNumbers("<hex value>"); | |
document.cookie = "RCPC=" + toHex(slowAES.decrypt(c, 2, a, b)) + "; <cookie attributes>"; | |
document.location.href = "https://codeforces.com/enter?f0a28=1"; | |
"#, | |
script, | |
)) | |
.with_context(|| "Could not extract values from the `<script>`.")?; | |
dbg!((a, b, c, cookie_attrs)); | |
todo!(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment