mirror of
https://github.com/Noratrieb/cluelessh.git
synced 2026-01-16 09:25:04 +01:00
stuff
This commit is contained in:
parent
b75db7c21f
commit
9c320c8b4c
5 changed files with 34 additions and 33 deletions
|
|
@ -1,5 +1,5 @@
|
||||||
[workspace]
|
[workspace]
|
||||||
members = ["ssh-transport"]
|
members = [ "ssh-transport"]
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "fakessh"
|
name = "fakessh"
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ pub(crate) struct Plaintext;
|
||||||
impl Keys for Plaintext {
|
impl Keys for Plaintext {
|
||||||
fn decrypt_len(&mut self, _: &mut [u8; 4], _: u64) {}
|
fn decrypt_len(&mut self, _: &mut [u8; 4], _: u64) {}
|
||||||
fn decrypt_packet(&mut self, raw: RawPacket, _: u64) -> Result<Packet> {
|
fn decrypt_packet(&mut self, raw: RawPacket, _: u64) -> Result<Packet> {
|
||||||
Packet::from_raw(raw.rest())
|
Packet::from_full(raw.rest())
|
||||||
}
|
}
|
||||||
fn encrypt_packet_to_msg(&mut self, packet: Packet, _: u64) -> Msg {
|
fn encrypt_packet_to_msg(&mut self, packet: Packet, _: u64) -> Msg {
|
||||||
Msg(MsgKind::PlaintextPacket(packet))
|
Msg(MsgKind::PlaintextPacket(packet))
|
||||||
|
|
@ -106,7 +106,7 @@ fn derive_key(k: [u8; 32], h: [u8; 32], letter: &str, session_id: [u8; 32]) -> [
|
||||||
//output[..sha2len].copy_from_slice(&hash.finalize());
|
//output[..sha2len].copy_from_slice(&hash.finalize());
|
||||||
|
|
||||||
for i in 0..(64 / sha2len) {
|
for i in 0..(64 / sha2len) {
|
||||||
let mut hash = sha2::Sha256::new();
|
let mut hash = <sha2::Sha256 as sha2::Digest>::new();
|
||||||
encode_mpint_for_hash(&k, |data| hash.update(data));
|
encode_mpint_for_hash(&k, |data| hash.update(data));
|
||||||
hash.update(h);
|
hash.update(h);
|
||||||
|
|
||||||
|
|
@ -193,7 +193,7 @@ impl SshChaCha20Poly1305 {
|
||||||
let encrypted_packet_content = bytes.content_mut();
|
let encrypted_packet_content = bytes.content_mut();
|
||||||
cipher.apply_keystream(encrypted_packet_content);
|
cipher.apply_keystream(encrypted_packet_content);
|
||||||
|
|
||||||
Packet::from_raw(encrypted_packet_content)
|
Packet::from_full(encrypted_packet_content)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encrypt_packet(&mut self, packet: Packet, packet_number: u64) -> EncryptedPacket {
|
fn encrypt_packet(&mut self, packet: Packet, packet_number: u64) -> EncryptedPacket {
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
mod channel;
|
mod channel;
|
||||||
mod keys;
|
mod keys;
|
||||||
mod packet;
|
pub mod packet;
|
||||||
mod parse;
|
pub mod parse;
|
||||||
|
|
||||||
use core::str;
|
use core::str;
|
||||||
use std::mem::take;
|
use std::{collections::VecDeque, mem::take};
|
||||||
|
|
||||||
use channel::ServerChannelsState;
|
use channel::ServerChannelsState;
|
||||||
use ed25519_dalek::ed25519::signature::Signer;
|
use ed25519_dalek::ed25519::signature::Signer;
|
||||||
|
|
@ -503,12 +503,12 @@ const PRIVKEY_BYTES: &[u8; 32] = &[
|
||||||
0x0b, 0x9a, 0x4a, 0x44, 0xd5, 0x47, 0xc7, 0x5b, 0x9e, 0x31, 0x7d, 0xa1, 0xd5, 0x75, 0x27, 0x99,
|
0x0b, 0x9a, 0x4a, 0x44, 0xd5, 0x47, 0xc7, 0x5b, 0x9e, 0x31, 0x7d, 0xa1, 0xd5, 0x75, 0x27, 0x99,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
macro_rules! client_error {
|
macro_rules! client_error {
|
||||||
($($tt:tt)*) => {
|
($($tt:tt)*) => {
|
||||||
$crate::SshStatus::ClientError(::std::format!($($tt)*))
|
$crate::SshStatus::ClientError(::std::format!($($tt)*))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
use client_error;
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
|
||||||
|
|
@ -122,9 +122,10 @@ length | padding_length | payload | random padding | MAC
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ encrypted using K2
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ encrypted using K2
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/// A plaintext SSH packet payload.
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub(crate) struct Packet {
|
pub struct Packet {
|
||||||
pub(crate) payload: Vec<u8>,
|
pub payload: Vec<u8>,
|
||||||
}
|
}
|
||||||
impl Packet {
|
impl Packet {
|
||||||
// -----
|
// -----
|
||||||
|
|
@ -178,7 +179,7 @@ impl Packet {
|
||||||
pub const SSH_MSG_CHANNEL_SUCCESS: u8 = 99;
|
pub const SSH_MSG_CHANNEL_SUCCESS: u8 = 99;
|
||||||
pub const SSH_MSG_CHANNEL_FAILURE: u8 = 100;
|
pub const SSH_MSG_CHANNEL_FAILURE: u8 = 100;
|
||||||
|
|
||||||
pub(crate) fn from_raw(bytes: &[u8]) -> Result<Self> {
|
pub(crate) fn from_full(bytes: &[u8]) -> Result<Self> {
|
||||||
let Some(padding_length) = bytes.first() else {
|
let Some(padding_length) = bytes.first() else {
|
||||||
return Err(client_error!("empty packet"));
|
return Err(client_error!("empty packet"));
|
||||||
};
|
};
|
||||||
|
|
@ -226,7 +227,7 @@ impl Packet {
|
||||||
new
|
new
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn payload_parser(&self) -> Parser<'_> {
|
pub fn payload_parser(&self) -> Parser<'_> {
|
||||||
Parser::new(&self.payload)
|
Parser::new(&self.payload)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,24 +4,24 @@ use std::fmt::Debug;
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
|
|
||||||
/// A simplified `byteorder` clone that emits client errors when the data is too short.
|
/// A simplified `byteorder` clone that emits client errors when the data is too short.
|
||||||
pub(crate) struct Parser<'a>(&'a [u8]);
|
pub struct Parser<'a>(&'a [u8]);
|
||||||
|
|
||||||
impl<'a> Parser<'a> {
|
impl<'a> Parser<'a> {
|
||||||
pub(crate) fn new(data: &'a [u8]) -> Self {
|
pub fn new(data: &'a [u8]) -> Self {
|
||||||
Self(data)
|
Self(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn u8(&mut self) -> Result<u8> {
|
pub fn u8(&mut self) -> Result<u8> {
|
||||||
let arr = self.array::<1>()?;
|
let arr = self.array::<1>()?;
|
||||||
Ok(arr[0])
|
Ok(arr[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn u32(&mut self) -> Result<u32> {
|
pub fn u32(&mut self) -> Result<u32> {
|
||||||
let arr = self.array()?;
|
let arr = self.array()?;
|
||||||
Ok(u32::from_be_bytes(arr))
|
Ok(u32::from_be_bytes(arr))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn array<const N: usize>(&mut self) -> Result<[u8; N]> {
|
pub fn array<const N: usize>(&mut self) -> Result<[u8; N]> {
|
||||||
if self.0.len() < N {
|
if self.0.len() < N {
|
||||||
return Err(crate::client_error!("packet too short"));
|
return Err(crate::client_error!("packet too short"));
|
||||||
}
|
}
|
||||||
|
|
@ -30,7 +30,7 @@ impl<'a> Parser<'a> {
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn slice(&mut self, len: usize) -> Result<&'a [u8]> {
|
pub fn slice(&mut self, len: usize) -> Result<&'a [u8]> {
|
||||||
if self.0.len() < len {
|
if self.0.len() < len {
|
||||||
return Err(crate::client_error!("packet too short"));
|
return Err(crate::client_error!("packet too short"));
|
||||||
}
|
}
|
||||||
|
|
@ -39,7 +39,7 @@ impl<'a> Parser<'a> {
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn bool(&mut self) -> Result<bool> {
|
pub fn bool(&mut self) -> Result<bool> {
|
||||||
let b = self.u8()?;
|
let b = self.u8()?;
|
||||||
match b {
|
match b {
|
||||||
0 => Ok(false),
|
0 => Ok(false),
|
||||||
|
|
@ -48,23 +48,23 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn name_list(&mut self) -> Result<NameList<'a>> {
|
pub fn name_list(&mut self) -> Result<NameList<'a>> {
|
||||||
let list = self.utf8_string()?;
|
let list = self.utf8_string()?;
|
||||||
Ok(NameList(list))
|
Ok(NameList(list))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn mpint(&mut self) -> Result<MpInt<'a>> {
|
pub fn mpint(&mut self) -> Result<MpInt<'a>> {
|
||||||
let data = self.string()?;
|
let data = self.string()?;
|
||||||
Ok(MpInt(data))
|
Ok(MpInt(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn string(&mut self) -> Result<&'a [u8]> {
|
pub fn string(&mut self) -> Result<&'a [u8]> {
|
||||||
let len = self.u32()?;
|
let len = self.u32()?;
|
||||||
let data = self.slice(len.try_into().unwrap())?;
|
let data = self.slice(len.try_into().unwrap())?;
|
||||||
Ok(data)
|
Ok(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn utf8_string(&mut self) -> Result<&'a str> {
|
pub fn utf8_string(&mut self) -> Result<&'a str> {
|
||||||
let s = self.string()?;
|
let s = self.string()?;
|
||||||
let Ok(s) = str::from_utf8(s) else {
|
let Ok(s) = str::from_utf8(s) else {
|
||||||
return Err(crate::client_error!("name-list is invalid UTF-8"));
|
return Err(crate::client_error!("name-list is invalid UTF-8"));
|
||||||
|
|
@ -74,43 +74,43 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A simplified `byteorder` clone that emits client errors when the data is too short.
|
/// A simplified `byteorder` clone that emits client errors when the data is too short.
|
||||||
pub(crate) struct Writer(Vec<u8>);
|
pub struct Writer(Vec<u8>);
|
||||||
|
|
||||||
impl Writer {
|
impl Writer {
|
||||||
pub(crate) fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self(Vec::new())
|
Self(Vec::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn u8(&mut self, v: u8) {
|
pub fn u8(&mut self, v: u8) {
|
||||||
self.write(&[v]);
|
self.write(&[v]);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn u32(&mut self, v: u32) {
|
pub fn u32(&mut self, v: u32) {
|
||||||
self.write(&u32::to_be_bytes(v));
|
self.write(&u32::to_be_bytes(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn write(&mut self, v: &[u8]) {
|
pub fn write(&mut self, v: &[u8]) {
|
||||||
self.0.extend_from_slice(v);
|
self.0.extend_from_slice(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn name_list(&mut self, list: NameList<'_>) {
|
pub fn name_list(&mut self, list: NameList<'_>) {
|
||||||
self.string(list.0.as_bytes());
|
self.string(list.0.as_bytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn mpint(&mut self, mpint: MpInt<'_>) {
|
pub fn mpint(&mut self, mpint: MpInt<'_>) {
|
||||||
self.string(mpint.0);
|
self.string(mpint.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn string(&mut self, data: &[u8]) {
|
pub fn string(&mut self, data: &[u8]) {
|
||||||
self.u32(data.len() as u32);
|
self.u32(data.len() as u32);
|
||||||
self.write(data);
|
self.write(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn bool(&mut self, v: bool) {
|
pub fn bool(&mut self, v: bool) {
|
||||||
self.u8(v as u8);
|
self.u8(v as u8);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn finish(self) -> Vec<u8> {
|
pub fn finish(self) -> Vec<u8> {
|
||||||
self.0
|
self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue