Skip to content

Instantly share code, notes, and snippets.

@qryxip
Created July 15, 2020 18:57
Show Gist options
  • Save qryxip/ec0231554a58574ca99773cef97a1629 to your computer and use it in GitHub Desktop.
Save qryxip/ec0231554a58574ca99773cef97a1629 to your computer and use it in GitHub Desktop.
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