How can i deobfuscate this text? - text

I've recently found some lua code and what I found inside was some obfuscated string. That made me wonder what sort of obfuscation technique was used there. Does anybody have an idea?
240.06230.0575240.06240.06270.0675250.0625265.06625270.0675250.0625285.07125260.065260.065260.065250.0625265...
https://pastebin.com/raw/7RkxjWQw

If this string is splitted into xxx.yyyy... chunks (exactly three digits before decimal point), then multiply each number by 800/4001 (the results will be integer!), then convert these integer numbers to ASCII, the hidden sequence of 16 floating point numbers would be revealed:
0.0062562944425795
0.036286507766961
0.02127140110477
0.047547837763604
0.041291543321025
0.0025025177770318
0.011261329996643
0.018768883327738
0.017517624439223
0.042542802209541
0.037537766655477
0.016266365550707
0.0087588122196113
0.057557908871731
0.025025177770318
0.026276436658834
Is the puzzle stops here?
Or should we try to decipher it further?
Ok, we could multiply them all by 32767/41 (the results will be integer!)
5
29
17
38
33
2
9
15
14
34
30
13
7
46
20
21
Hmm, the puzzle seems to be really interesting...
Is it the end?
Just googled it.
That's the passwords encrypted, something Roblox-related
So, OP surely doesn't have decoder script :-)
Ok, finally did it.
function decode_password(encoded_password)
local result = ""
local buffer = ""
for x in encoded_password:gsub("%d%d%d%.", "\0%0"):gmatch"%Z+" do
x = math.floor(tonumber(x) / 5.00125 + 0.5)
if x ~= 95 then
buffer = buffer..string.char(x)
elseif buffer ~= "" then
x = math.floor(tonumber(buffer) * 799.195122 + 0.5)
result = result..("qazwsxedcrfjmik,o0 23456-=\\vtgbyhnul.p;;;/[']1789"):sub(x, x)
buffer = ""
end
end
return result
end
Example 1:
local p = '240.06230.0575240.06240.06270.0675250.0625265.06625270.0675250.0625285.07125260.065260.065260.065250.0625265.06625275.06875285.07125265.06625475.11875240.06230.0575240.06255.06375270.0675250.0625280.07270.0675265.06625240.06275.06875275.06875270.0675270.0675285.07125270.0675245.06125475.11875240.06230.0575240.06250.0625245.06125250.0625275.06875245.06125260.065240.06245.06125245.06125240.06260.065275.06875275.06875475.11875240.06230.0575240.06260.065275.06875265.06625260.065275.06875280.07255.06375275.06875275.06875270.0675255.06375270.0675240.06260.065475.11875240.06230.0575240.06260.065245.06125250.0625285.07125245.06125265.06625260.065255.06375255.06375250.0625245.06125240.06250.0625265.06625475.11875240.06230.0575240.06240.06250.0625265.06625240.06250.0625265.06625245.06125275.06875275.06875275.06875275.06875240.06255.06375245.06125280.07475.11875240.06230.0575240.06245.06125245.06125250.0625270.0675245.06125255.06375250.0625285.07125285.07125285.07125270.0675270.0675260.065255.06375475.11875240.06230.0575240.06245.06125280.07275.06875270.0675280.07280.07280.07255.06375255.06375250.0625275.06875275.06875255.06375280.07475.11875240.06230.0575240.06245.06125275.06875265.06625245.06125275.06875270.0675250.0625260.065260.065255.06375285.07125250.0625250.0625255.06375475.11875240.06230.0575240.06260.065250.0625265.06625260.065250.0625280.07240.06250.0625250.0625240.06285.07125265.06625260.065245.06125475.11875240.06230.0575240.06255.06375275.06875265.06625255.06375275.06875275.06875270.0675270.0675270.0675265.06625265.06625260.065275.06875275.06875475.11875240.06230.0575240.06245.06125270.0675250.0625270.0675270.0675255.06375270.0675265.06625265.06625265.06625240.06275.06875240.06275.06875475.11875240.06230.0575240.06240.06280.07275.06875265.06625280.07280.07245.06125250.0625250.0625245.06125285.07125270.0675245.06125245.06125255.06375475.11875240.06230.0575240.06265.06625275.06875265.06625265.06625275.06875285.07125240.06280.07280.07275.06875245.06125275.06875255.06375245.06125475.11875240.06230.0575240.06250.0625265.06625240.06250.0625265.06625245.06125275.06875275.06875275.06875275.06875240.06255.06375245.06125280.07475.11875240.06230.0575240.06250.0625270.0675250.0625275.06875270.0675260.065255.06375270.0675270.0675265.06625280.07280.07255.06375260.065475.11875'
print(decode_password(p)) --> stophackingme123
Example 2:
for _, info in ipairs(loginDatabase) do
print(info.username, decode_password(info.password))
end

Related

How do I extract an array of bits 2-9 from a bytearray?

I have a 100,000 long bytearray, where every 16-bit line is a 10-bit address and 6-bit counts concatenated. I want to convert the 16-by-100,000 array into two separate (address and data) arrays in an array-wise, efficient manner. A short run-time is critical to my application.
What I have so far is
read binary into a uint16 array
f = open(curfile, mode="r")
aint = np.fromfile(f, dtype=np.uint16)
read each line inside a for-loop
line = '{0:15b}'.format(aint[nn])
extract integers from binary
addr[nn] = 2**8*return0ifempty(line[0]) + return0ifempty(line[1:9])
count[nn] = line[-6:]
(return0ifempty returns 0 when ' ' is input)
The whole binary => uint16 => binary => uint16 idea is extremely inefficient. There must be a better way to do this. Are there any ways to truncate the array as in matlab, e.g., A(5:10,:)?
Assuming you want low 10 bits and high 6 bits:
low_10 = aint & 1023
high_6 = aint >> 10
If you want low 6 bits and high 10 bits:
low_6 = aint & 63
high_10 = aint >> 6
Unlike a Python loop, this is vectorised and runs much, much, much faster (also, no conversion to string).
EDIT: Looking at your example, you want 10 high for addr, and 6 low for count; so...
count = aint & 63
addr = aint >> 6
Some explanation for 63: it is 0b111111, so & 63 will preserve 6 low bits and switch off any higher ones.

block cipher in CTR mode manipulation

I have a question about block cipher using CTR mode. I think i need to find something (value) that when I do 46 XOR value = 43, I get value to be (1011 1101), then i use 0x64(0110 0100) XOR value(1011 1101) but it does not give me 0x72(0111 0010). Did I miss something here? My upstanding is that in order to do this, all i need to do is to find a value that adds counter (in this case is zero) and xor the plain text to get cipher text. Did I miss something here? Thank you in advance.
You know that the 2nd and 3rd block were created by the same key stream (created by concatenating the counter values encrypted by the block cipher).
So for the first byte of the second block you'd have 46 = 43 ^ KK and 51 = P2 ^ KK where KK is the first byte of the key stream. Now KK can be easily calculated, as KK = 46 ^ 43 (KK = 05 if I'm not mistaken). Now P2 = KK ^ 51 or P2 = 05 ^ 51 = 54.
You can simply repeat that for each index into the streams and presto. You don't have to do anything with the counter itself; knowing that the same key and counter were used is enough to generate the same key stream.

see if a string is embedded in a larger string

I have data that looks like this using R.
> hits
Views on a 51-letter DNAString subject
subject: TCAGAAACAAAACCCAAAATCAGTAAGGAGGAGAAAGAAACCTAGGGAGAA
views:
start end width
[1] 1 10 10 [TCAGAAACAA]
[2] 14 23 10 [CCAAAATCAG]
[3] 19 28 10 [ATCAGTAAGG]
[4] 20 29 10 [TCAGTAAGGA]
[5] 21 30 10 [CAGTAAGGAG]
So I have a 51 length string called
subject = TCAGAAACAAAACCCAAAATCAGTAAGGAGGAGAAAGAAACCTAGGGAGAA.
5 substrings are extracted from this subject. You can see them above. I'd like to see if the 5 substrings are in my area of interest. This area of interest is from position 14 - 27.
subject = TCAGAAACAAAAC |-> CCAAAATCAGTAAG <-| GAGGAGAAAGAAACCTAGGGAGAA.
In other words, I have 5 substrings from the subject string. Out of these 5 strings, I am only looking for strings that lie between position 14 - 27 of the subject string. This is my area of interest.
The first [1] substring [TCAGAAACAA] is not that important since it is embedded right at the start (given by the coordinates 1 - 10) and is outside my area of interest.
The second [2] string given by the coordinates 14 - 23 tells me that it in entirely embedded in my area of interest (which again is 14 - 27).
The third [3] string is given by the coordinates 19 - 28. This is important to me as the majority of the string is embedded in my area of interest.
The fourth [4] string is given by the coordinates 20 - 29. Again this is important to me since the majority of the string is embedded in my area of interest except the last the characters.
The story is the same for the fifth substring.
Basically if 60% of the string is embedded in my area of interest I'd like to count it.
Can someone give me an algorithm in pseudocode that can do this? I have been thinking about this for a while drawing diagrams but I can't seem to implement it. I am doing this in R so I will convert the pseudocode to R. Also the number 60% is arbritrary. I'll have to confirm this with my supervisor but I am sure this is irrelevant.
If I understood well, you need to
Define an 'area of interest' given by a start position and an end position.
Find a string or an accepted portion of a string in the area of interest of the larger string.
So this is what I would do in javascript
var fractionIsInString = function (areaOfInterest, stringToBeFound, acceptedFraction) {
var fractionLength = Math.floor(stringToBeFound.length*acceptedFraction),
startPosition = 0,
endPosition = fractionLength,
fraction,
keepSearching = true;
do {
fraction = stringToBeFound.substring(startPosition, endPosition);
if (areaOfInterest.indexOf(fraction) > -1) {
return true;
}
startPosition++;
endPosition++;
keepSearching = endPosition < stringToBeFound.length;
} while (keepSearching);
return false;
};
To call it you simply say
fractionIsInString('CCAAAATCAGTAAG', 'TCAGAAACAA', 0.6);
The first parameter is your area of interest, which can be obtained like this
subject.substring(14, 27);
The second parameter is the first of the strings you get from your subject. The one that goes from 0 to 10.
The third parameter is the portion of the second parameter that you want to be found. 60% in this case.
How the function works is that it looks for the fraction of the string in the larger string and if the fraction is not found, it moves to the next fraction of the string and so on until it finds a fraction that is found or it reaches the end of the string.
def substring_index(longstring, substring):
"""Return the index of the substring in longstring."""
# Python has a built in function for this.
def is_interesting(index, length, interesting_start, interesting_end, percentage):
"""Return true if the substring is interesting."""
interesting = 0
uninteresting = 0
# check if the character at each position from index to index + length
# is in the interesting range.
for x in range(index, index + length + 1):
if interesting_start < x < interesting_end:
interesting += 1
else:
uninteresting += 1
# Do some math to see if interesting / (interesting + uninteresting)
# is bigger than percentage
Use the substring_index function to see if and where the index lies in the longstring.
Use the is_interesting function to return a boolean based on whether the substring is interesting.
So, for the first substring, you could call it this like:
longstring = "TCAGAAACAAAACCCAAAATCAGTAAGGAGGAGAAAGAAACCTAGGGAGAA"
substring = "TCAGAAACAA"
is_interesting(substring_index(longstring, substring), len(substring), 14, 27, 0.6)

How to compute word scores in Scrabble using MATLAB

I have a homework program I have run into a problem with. We basically have to take a word (such as MATLAB) and have the function give us the correct score value for it using the rules of Scrabble. There are other things involved such as double word and double point values, but what I'm struggling with is converting to ASCII. I need to get my string into ASCII form and then sum up those values. We only know the bare basics of strings and our teacher is pretty useless. I've tried converting the string into numbers, but that's not exactly working out. Any suggestions?
function[score] = scrabble(word, letterPoints)
doubleword = '#';
doubleletter = '!';
doublew = [findstr(word, doubleword)]
trouble = [findstr(word, doubleletter)]
word = char(word)
gameplay = word;
ASCII = double(gameplay)
score = lower(sum(ASCII));
Building on Francis's post, what I would recommend you do is create a lookup array. You can certainly convert each character into its ASCII equivalent, but then what I would do is have an array where the input is the ASCII code of the character you want (with a bit of modification), and the output will be the point value of the character. Once you find this, you can sum over the points to get your final point score.
I'm going to leave out double points, double letters, blank tiles and that whole gamut of fun stuff in Scrabble for now in order to get what you want working. By consulting Wikipedia, this is the point distribution for each letter encountered in Scrabble.
1 point: A, E, I, O, N, R, T, L, S, U
2 points: D, G
3 points: B, C, M, P
4 points: F, H, V, W, Y
5 points: K
8 points: J, X
10 points: Q, Z
What we're going to do is convert your word into lower case to ensure consistency. Now, if you take a look at the letter a, this corresponds to ASCII code 97. You can verify that by using the double function we talked about earlier:
>> double('a')
97
As there are 26 letters in the alphabet, this means that going from a to z should go from 97 to 122. Because MATLAB starts indexing arrays at 1, what we can do is subtract each of our characters by 96 so that we'll be able to figure out the numerical position of these characters from 1 to 26.
Let's start by building our lookup table. First, I'm going to define a whole bunch of strings. Each string denotes the letters that are associated with each point in Scrabble:
string1point = 'aeionrtlsu';
string2point = 'dg';
string3point = 'bcmp';
string4point = 'fhvwy';
string5point = 'k';
string8point = 'jx';
string10point = 'qz';
Now, we can use each of the strings, convert to double, subtract by 96 then assign each of the corresponding locations to the points for each letter. Let's create our lookup table like so:
lookup = zeros(1,26);
lookup(double(string1point) - 96) = 1;
lookup(double(string2point) - 96) = 2;
lookup(double(string3point) - 96) = 3;
lookup(double(string4point) - 96) = 4;
lookup(double(string5point) - 96) = 5;
lookup(double(string8point) - 96) = 8;
lookup(double(string10point) - 96) = 10;
I first create an array of length 26 through the zeros function. I then figure out where each letter goes and assign to each letter their point values.
Now, the last thing you need to do is take a string, take the lower case to be sure, then convert each character into its ASCII equivalent, subtract by 96, then sum up the values. If we are given... say... MATLAB:
stringToConvert = 'MATLAB';
stringToConvert = lower(stringToConvert);
ASCII = double(stringToConvert) - 96;
value = sum(lookup(ASCII));
Lo and behold... we get:
value =
10
The last line of the above code is crucial. Basically, ASCII will contain a bunch of indexing locations where each number corresponds to the numerical position of where the letter occurs in the alphabet. We use these positions to look up what point / score each letter gives us, and we sum over all of these values.
Part #2
The next part where double point values and double words come to play can be found in my other StackOverflow post here:
Calculate Scrabble word scores for double letters and double words MATLAB
Convert from string to ASCII:
>> myString = 'hello, world';
>> ASCII = double(myString)
ASCII =
104 101 108 108 111 44 32 119 111 114 108 100
Sum up the values:
>> total = sum(ASCII)
total =
1160
The MATLAB help for char() says (emphasis added):
S = char(X) converts array X of nonnegative integer codes into a character array. Valid codes range from 0 to 65535, where codes 0 through 127 correspond to 7-bit ASCII characters. The characters that MATLABĀ® can process (other than 7-bit ASCII characters) depend upon your current locale setting. To convert characters into a numeric array, use the double function.
ASCII chart here.

Mapping unique combinations to numbers

I am trying to come up with a solution to a problem I thought of. I have the number of permutations of 26 characters with 6 possible spots as 26^6 = 308 915 776. I was trying to make a way so that I could map each number to a unique combination and be able to go back and forth from combination to number.
An example:
1 = aaaaaa
2 = aaaaab
27 = aaaaba
Is it possible to write a polynomial time algorithm that would convert between the two and/or are there any efficient examples of what I am trying to do.
This is just base conversion my friend.
Since you didn't specify a language, the following is pseudo-code with array indexing and string indexing starting at 0 and assignment is :=.
if you let 'a' be 0, and 'z' be 25, then to convert from base 26 to base 10:
total:= 0
loop index from 0 to 5
temp:= 'z' - input[index] // Left to right. Single base 26 digit to base 10
total:= 26 * total + temp // Shift left and add the converted digit
increment index and goto loop start
To go back to letters (base 26) is also easy:
result:= ''
loop index from 0 to 5
temp:= 'a' + input mod 26 // Input modulus 26 is the base 26 digit to add next
result:= temp + result // Append current result to the new base 26 digit
input:= input div 26 // Divide input by 26, throw away the remainder
increment index and goto loop start
If you want all a's to be 1, then add one after converting from base 26 to base 10 and subtract 1 before converting from base 10 to base 26. Personally, I'd let all a's be 0.
You could map it via pointers into a double:
char *example = "abcdef";
double d = 0;
char *p = (char *)&d;
for (int i=0; i<6; i++)
p[i] = example[i];
// d is your code
It's not so beautiful and not 100% allowed, but it works.

Resources