Open minkhantkyaw336 opened 3 years ago
Hola te saluda Cesar Hack Gray
Esos archivos no son los que manejan socialsploit las puse ahi por error, y no son escritas por mi
Att... Cesar
El mar., 19 de enero de 2021 12:43 a. m., Casparlay < notifications@github.com> escribió:
!/usr/bin/python
import sys
class BashFileIterator: class _Delimiter(object): def init(self, character, _type=''): self.character = character
type may be 'AP' or 'AS' (Arithmetic Expansion delimited by (()) or []
respectively),
'S' (Command Substitution) or 'P' (Parameter Expansion)
type is set only for parenthesis or curly brace and square brace that
opens group
e.g. in this statement $((1+2)) only the 1st '(' will have type ('AP')
self.type = _type
def is_group_opening(self): return bool(self.type or self.character in ("'", '"', '`')) def __eq__(self, other): if isinstance(other, BashFileIterator._Delimiter): return other.character == self.character elif isinstance(other, basestring): return other == self.character return False def __ne__(self, other): return not self.__eq__(other) def __str__(self): return self.character __repr__ = __str__
def init(self, src): self.src = src self.reset()
def reset(self): self.pos = 0 self.insideComment = False self.insideHereDoc = False
# possible characters in stack: # (, ) -- means Arithmetic Expansion or Command Substitution # {, } -- means Parameter Expansion # [, ] -- means Arithmetic Expansion # ` -- means Command Substitution # ' -- means single-quoted string # " -- means double-quoted string self._delimiters_stack = [] self._indices_of_escaped_characters = set()
def getLastGroupOpeningDelimiter(self): return next((d for d in reversed(self._delimiters_stack) if d.is_group_opening()), BashFileIterator._Delimiter(''))
def pushDelimiter(self, character, _type=''): d = BashFileIterator._Delimiter(character, _type=_type) last_opening = self.getLastGroupOpeningDelimiter() last = self._delimiters_stack[-1] if len(self._delimiters_stack) > 0 else BashFileIterator._Delimiter('')
if d in ('{', '}'): if _type != '': # delimiter that opens group self._delimiters_stack.append(d) elif d == '}' and last == '{': self._delimiters_stack.pop() elif d in ('(', ')'): if _type != '': # delimiter that opens group self._delimiters_stack.append(d) elif last_opening == '(': if last == '(' and d == ')': self._delimiters_stack.pop() else: self._delimiters_stack.append(d) elif d in ('[', ']'): if _type != '': # delimiter that opens group self._delimiters_stack.append(d) elif last_opening == '[': if last == '[' and d == ']': self._delimiters_stack.pop() else: self._delimiters_stack.append(d) elif d == "'" and last_opening != '"' or d == '"' and last_opening != "'" or d == '`': if d == last_opening: self._delimiters_stack.pop() else: self._delimiters_stack.append(d)
def isInsideGroup(self): return len(self._delimiters_stack) != 0
def getPreviousCharacters(self, n, should_not_start_with_escaped=True): """ 'should_not_start_with_escaped' means return empty string if the first character is escaped """ first_character_index = max(0, self.pos - n) if first_character_index in self._indices_of_escaped_characters: return '' else: return self.src[max(0, self.pos - n):self.pos]
def getPreviousCharacter(self, should_not_start_with_escaped=True): return self.getPreviousCharacters(1, should_not_start_with_escaped=should_not_start_with_escaped)
def getNextCharacters(self, n): return self.src[self.pos + 1:self.pos + n + 1]
def getNextCharacter(self): return self.getNextCharacters(1)
def getPreviousWord(self): word = '' i = 1 while i <= self.pos: newWord = self.getPreviousCharacters(i) if not newWord.isalpha(): break word = newWord i += 1 return word
def getNextWord(self): word = '' i = 1 while self.pos + i < len(self.src): newWord = self.getNextCharacters(i) if not newWord.isalpha(): break word = newWord i += 1 return word
def getPartOfLineAfterPos(self, skip=0): result = '' i = self.pos + 1 + skip while i < len(self.src) and self.src[i] != '\n': result += self.src[i] i += 1 return result
def getPartOfLineBeforePos(self, skip=0): result = '' i = self.pos - 1 - skip while i >= 0 and self.src[i] != '\n': result = self.src[i] + result i -= 1 return result
def charactersGenerator(self): hereDocWord = '' _yieldNextNCharactersAsIs = 0
def close_heredoc(): self.insideHereDoc = False callbacks_after_yield = [] while self.pos < len(self.src): ch = self.src[self.pos] if _yieldNextNCharactersAsIs > 0: _yieldNextNCharactersAsIs -= 1 elif ch == "\\" and not self.isEscaped(): self._indices_of_escaped_characters.add(self.pos + 1) else: if ch == "\n" and not self.isInsideSingleQuotedString() and not self.isInsideDoubleQuotedString(): # handle end of comments and heredocs if self.insideComment: self.insideComment = False elif self.insideHereDoc and self.getPartOfLineBeforePos() == hereDocWord: callbacks_after_yield.append(close_heredoc) elif not self.isInsideComment() and not self.isInsideHereDoc(): if ch in ('"', "'"): # single quote can't be escaped inside single-quoted string if not self.isEscaped() or ch == "'" and self.isInsideSingleQuotedString(): self.pushDelimiter(ch) elif not self.isInsideSingleQuotedString(): if not self.isEscaped(): if ch == "#" and not self.isInsideGroup() and \ (self.getPreviousCharacter() in ('\n', '\t', ' ', ';') or self.pos == 0): # handle comments self.insideComment = True elif ch == '`': self.pushDelimiter(ch) elif ch == '$': next_char = self.getNextCharacter() if next_char in ('{', '(', '['): next_2_chars = self.getNextCharacters(2) _type = 'AP' if next_2_chars == '((' else {'{': 'P', '(': 'S', '[': 'AS'}[next_char] self.pushDelimiter(next_char, _type=_type) _yieldNextNCharactersAsIs = 1 elif ch in ('{', '}', '(', ')', '[', ']'): self.pushDelimiter(ch) elif ch == '<' and self.getNextCharacter() == '<' and not self.isInsideGroup(): _yieldNextNCharactersAsIs = 1 # we should handle correctly heredocs and herestrings like this one: # echo <<< one if self.getNextCharacters(2) != '<<': # heredoc self.insideHereDoc = True hereDocWord = self.getPartOfLineAfterPos(skip=1) if hereDocWord[0] == '-': hereDocWord = hereDocWord[1:] hereDocWord = hereDocWord.strip().replace('"', '').replace("'", '') yield ch while len(callbacks_after_yield) > 0: callbacks_after_yield.pop()() self.pos += 1 assert not self.isInsideGroup(), 'Invalid syntax' raise StopIteration
def isEscaped(self): return self.pos in self._indices_of_escaped_characters
def isInsideDoubleQuotedString(self): return self.getLastGroupOpeningDelimiter() == '"'
def isInsideSingleQuotedString(self): return self.getLastGroupOpeningDelimiter() == "'"
def isInsideComment(self): return self.insideComment
def isInsideHereDoc(self): return self.insideHereDoc
def isInsideParameterExpansion(self): return self.getLastGroupOpeningDelimiter() == '{'
def isInsideArithmeticExpansion(self): return self.getLastGroupOpeningDelimiter().type in ('AP', 'AS')
def isInsideCommandSubstitution(self): last_opening_delimiter = self.getLastGroupOpeningDelimiter() return last_opening_delimiter == '`' or last_opening_delimiter.type == 'S'
def isInsideAnything(self): return self.isInsideGroup() or self.insideHereDoc or self.insideComment
def isInsideGroupWhereWhitespacesCannotBeTruncated(self): return self.isInsideComment() or self.isInsideDoubleQuotedString() or self.isInsideDoubleQuotedString() or \ self.isInsideHereDoc() or self.isInsideParameterExpansion()
def minify(src):
first: remove all comments
it = BashFileIterator(src) src = "" # result for ch in it.charactersGenerator(): if not it.isInsideComment(): src += ch
secondly: remove empty strings, strip lines and truncate spaces (replace groups of whitespaces by single space)
it = BashFileIterator(src) src = "" # result emptyLine = True # means that no characters has been printed in current line so far previousSpacePrinted = True for ch in it.charactersGenerator(): if it.isInsideSingleQuotedString():
first of all check single quoted string because line continuation does not work inside
src += ch elif ch == "\\" and not it.isEscaped() and it.getNextCharacter() == "\n": # then check line continuation # line continuation will occur on the next iteration. just skip this backslash continue elif ch == "\n" and it.isEscaped(): # line continuation occurred # backslash at the very end of line means line continuation # so remove previous backslash and skip current newline character ch continue elif it.isInsideGroupWhereWhitespacesCannotBeTruncated() or it.isEscaped(): src += ch elif ch in (' ', '\t') and not previousSpacePrinted and not emptyLine and \ not it.getNextCharacter() in (' ', '\t', '\n'): src += " " previousSpacePrinted = True elif ch == "\n" and it.getPreviousCharacter() != "\n" and not emptyLine: src += ch previousSpacePrinted = True emptyLine = True elif ch not in (' ', '\t', '\n'): src += ch previousSpacePrinted = False emptyLine = False
thirdly: get rid of newlines
it = BashFileIterator(src) src = "" # result for ch in it.charactersGenerator(): if it.isInsideAnything() or ch != "\n": src += ch else: prevWord = it.getPreviousWord() nextWord = it.getNextWord() if it.getNextCharacter() == '{': # functions declaration, see test t8.sh if it.getPreviousCharacter() == ')': continue else: src += ' ' elif prevWord in ("until", "while", "then", "do", "else", "in", "elif", "if") or \ nextWord in ("in",) or \ it.getPreviousCharacter() in ("{", "(") or \ it.getPreviousCharacters(2) in ("&&", "||"): src += " " elif nextWord in ("esac",) and it.getPreviousCharacters(2) != ';;': if it.getPreviousCharacter() == ';': src += ';' else: src += ';;' elif it.getNextCharacter() != "" and it.getPreviousCharacter() not in (";", '|'): src += ";"
finally: remove spaces around semicolons and pipes and other delimiters
it = BashFileIterator(src) src = "" # result other_delimiters = ('|', '&', ';', '<', '>', '(', ')') # characters that may not be surrounded by whitespaces for ch in it.charactersGenerator(): if it.isInsideGroupWhereWhitespacesCannotBeTruncated(): src += ch elif ch in (' ', '\t') \ and (it.getPreviousCharacter() in other_delimiters or it.getNextCharacter() in other_delimiters) \ and it.getNextCharacters(2) not in ('<(', '>('): # process substitution
see test t_process_substitution.sh for details
continue else: src += ch
return src
if name == "main": # https://www.gnu.org/software/bash/manual/html_node/Reserved-Word-Index.html
http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html
http://pubs.opengroup.org/onlinepubs/9699919799/
get bash source from file or from stdin
src = "" if len(sys.argv) > 1: with open(sys.argv[1], "r") as ifile: src = ifile.read() else: src = sys.stdin.read()
use stdout.write instead of print to avoid newline at the end (print with comma at the end does not work)
sys.stdout.write(minify(src))
important rules: 1. A single-quote cannot occur within single-quotes. 2. The input characters within the double-quoted string that are also enclosed between "$(" and the matching ')' shall not be affected by the double-quotes, but rather shall define that command whose output replaces the "$(...)" when the word is expanded. 3. Within the double-quoted string of characters from an enclosed "${" to the matching '}', an even number of unescaped double-quotes or single-quotes, if any, shall occur. A preceding character shall be used to escape a literal '{' or '}' 4.
You can view, comment on, or merge this pull request online at:
https://github.com/Cesar-Hack-Gray/SocialSploit/pull/14 Commit Summary
- Update .CesarHackGray
File Changes
- M .CesarHackGray https://github.com/Cesar-Hack-Gray/SocialSploit/pull/14/files#diff-6c90cf0720e8da08b628a260e3c9ef3ab3470755e03040e23f125965a05ea48c (363)
Patch Links:
- https://github.com/Cesar-Hack-Gray/SocialSploit/pull/14.patch
- https://github.com/Cesar-Hack-Gray/SocialSploit/pull/14.diff
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/Cesar-Hack-Gray/SocialSploit/pull/14, or unsubscribe https://github.com/notifications/unsubscribe-auth/ALARNQRNJUCIQ6HAVMDRRS3S2USZRANCNFSM4WIJTPVA .
!/usr/bin/python
import sys
class BashFileIterator: class _Delimiter(object): def init(self, character, _type=''): self.character = character
type may be 'AP' or 'AS' (Arithmetic Expansion delimited by (()) or [] respectively),
def minify(src):
first: remove all comments
if name == "main":
https://www.gnu.org/software/bash/manual/html_node/Reserved-Word-Index.html
important rules:
1. A single-quote cannot occur within single-quotes.
2. The input characters within the double-quoted string that are also enclosed between "$(" and the matching ')'
shall not be affected by the double-quotes, but rather shall define that command whose output replaces the "$(...)"
when the word is expanded.
3. Within the double-quoted string of characters from an enclosed "${" to the matching '}', an even number of
unescaped double-quotes or single-quotes, if any, shall occur. A preceding character shall be used
to escape a literal '{' or '}'
4.