Strange Payload when generating raw packet with Scappy - scapy

I am having an strange problem trying to generate a raw packet with Scappy.
I am doing the following:
eee=Ether(dst='08:00:11:11:11', src='08:00:11:11:22:22', type=0x888)/Raw(load='112233445566778888776655443322110901')
But when I do a hexdump of the newly created packet:
hexdump(eee)
0000 08 00 11 11 11 00 08 00 11 11 22 22 08 88 **31 31** ..........""..11
0010 **32 32** 33 33 34 34 35 35 36 36 37 37 38 38 38 38 2233445566778888
0020 37 37 36 36 35 35 34 34 33 33 32 32 31 31 30 39 7766554433221109
0030 30 31
It look like it is appending a 3 to the hexdump version of the payload. I really do not know from where that 3 is appearing.
Thanks in advance for any hint.

The Raw layer takes the binary representation of the load argument. Since the ascii value of the character 1 is 0x31 and the ascii value of the character 2 is 0x32, the binary representation of the string 1122 is 0x31313232. That's what you see as the output of hexdump.
What you need to do is decode the string before transferring it as the load argument to the Raw layer:
In [1]: from scapy.all import *
WARNING: No route found for IPv6 destination :: (no default route?)
In [2]: eee=Ether(dst='08:00:11:11:11', src='08:00:11:11:22:22', type=0x888)/Raw(load='112233445566778888776655443322110901'.decode("HEX"))
In [3]: hexdump(eee)
0000 08 00 11 11 11 00 08 00 11 11 22 22 08 88 11 22 ..........""..."
0010 33 44 55 66 77 88 88 77 66 55 44 33 22 11 09 01 3DUfw..wfUD3"...

Related

Python: Taking input from a file and storing it as an int data type

I have an input file 'input.dat':
08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08
49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00
81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65
52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91
22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80
24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50
32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70
67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21
24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72
21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95
78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92
16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57
86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58
19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40
04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66
88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69
04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36
20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16
20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54
01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48
I store the data in a 2D array and try to process as in the given code:
if __name__ == "__main__":
dataFile = open("/Users/atulyaratanjha/Documents/Python/P11.dat")
arr = []
for line in dataFile:
arr.append(line.split())
maxMult = 0
for i in range(16):
for j in range(20):
mult = arr[i][j] * arr[i+1][j] * arr[i+2][j] * arr[i+3][j]
maxMult = max(maxMult, mult)
for i in range(20):
for j in range(16):
mult = arr[i][j] * arr[i][j+1] * arr[i][j+2] * arr[i][j+3]
maxMult = max(maxMult, mult)
for i in range(16):
for j in range(16):
mult = arr[i][j] * arr[i+1][j+1] * arr[i+2][j+2] * arr[i+2][j+3]
maxMult = max(maxMult, mult)
print(maxMult)
It gives this Error:
TypeError: can't multiply sequence by non-int of type 'str'
I know that I can change the data into 'int' from 'str' by running a for loop, but is there any way to store the data as 'int' at the input stage?
Andrej Kesely explains you might
change the arr.append(line.split()) to arr.append(list(map(int, line.split()))) and it should work.

How do you find the largest product of 4 consecutive numbers in a grid? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
Here's the problem:
Find the largest product of a horizontal or vertical line of four consecutive numbers in this grid. Here, "consecutive" means four numbers that lie next to each other in the same row or column. For example, the top row starts with the four consecutive numbers 8, 2, 22, and 97. Consecutive numbers do not "wrap around" sides of the grid.
I know that I should convert the grid into a number of lists and kind of go through each quad (pairs except 4 instead of 2). But I'm not sure how to save it as a file and how to do anything with this to code to the answer.
My SPECIFIC question is what exactly is the problem asking me to do and what would be the pseudocode? Taking 4 two-digit numbers and multiplying them does not give an 8-digit number (unless I'm crazy).
I have no code as of now.
Here is the 20x20 grid:
It should output an 8-digit number.
import numpy as np
np.random.seed(10)
a = np.random.randint(1,10,(6,7))
func = lambda arr,n:(arr[:,np.arange(arr.shape[1]-n+1)[:,None] + np.arange(n)]).prod(2).max()
np.r_[func(a,4),func(a.T,4)].max()
Now Using the GRID:
import io
grid = np.loadtxt(io.StringIO(GRID))
np.r_[func(grid,4),func(grid.T,4)].max()
Out: 51267216.0
Without using numpy, you could do:
from functools import reduce
prod = lambda lst: reduce(lambda x,y:x*y,lst)
def slice_grid_max(grid,n):
n_cols = len(list(zip(*grid)))
f = lambda grid: max([prod(j[i:i+n]) for j in grid for i in range(n_cols-n+1)])
return max((f(grid),f(zip(*grid))))
slice_grid_max(grid,4)
Out: 51267216.0
If you would like to solve this problem using Python's standard library without having to resort to any third-party modules, you can use the following program as a demonstration of how you could go about doing that:
#! /usr/bin/env python3
import enum
# The grid was converted here: https://easypdf.com/ocr-online
# After some manual cleanup of the conversion, you have this:
GRID = '''\
08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08
49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00
81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65
52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91
22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80
24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50
32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70
67 26 20 68 02 62 12 20 93 63 94 39 63 08 40 91 66 49 94 21
24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72
21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95
78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92
16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57
86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58
19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40
04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66
88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 33 69
04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36
20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 83 74 04 36 16
20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 34
01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48'''
CONSECUTIVE = 4
def main():
matrix = convert_grid_to_matrix()
products = {}
calculate_horizontal_products(matrix, products)
calculate_vertical_products(matrix, products)
largest_products = calculate_largest_products(products)
display_largest_products(matrix, largest_products)
def convert_grid_to_matrix():
return tuple(tuple(map(int, line.split())) for line in GRID.splitlines())
def calculate_horizontal_products(matrix, products):
calculate_all_products(matrix, products, Orientation.HORIZONTAL)
def calculate_all_products(matrix, products, orientation):
for row, column in generate_starting_coordinates(matrix, orientation):
products[(row, column, orientation)] = calculate_product(
get_numbers(matrix, row, column, orientation)
)
def calculate_product(numbers, start=1):
for value in numbers:
start *= value
return start
def generate_starting_coordinates(matrix, orientation):
if orientation is Orientation.HORIZONTAL:
for row in range(len(matrix)):
for column in range(len(matrix[row]) - CONSECUTIVE + 1):
yield row, column
elif orientation is Orientation.VERTICAL:
for row in range(len(matrix) - CONSECUTIVE + 1):
for column in range(len(matrix[row])):
yield row, column
else:
raise ValueError(f'{orientation!r} is not a valid orientation')
def get_numbers(matrix, row, column, orientation):
if orientation is Orientation.HORIZONTAL:
return matrix[row][column:column + CONSECUTIVE]
if orientation is Orientation.VERTICAL:
return tuple(
matrix[row + offset][column] for offset in range(CONSECUTIVE)
)
raise ValueError(f'{orientation!r} is not a valid orientation')
def calculate_vertical_products(matrix, products):
calculate_all_products(matrix, products, Orientation.VERTICAL)
def calculate_largest_products(products):
max_value = max(products.values())
for key, value in products.items():
if value == max_value:
yield key
def display_largest_products(matrix, largest_products):
print('The largest product(s) can be found here:')
for coordinate in largest_products:
print(' Row: {}, Column: {}, {}'.format(*coordinate))
display_calculation(matrix, *coordinate)
def display_calculation(matrix, *coordinate):
numbers = get_numbers(matrix, *coordinate)
operation = ' * '.join(map(str, numbers))
print(f' {operation} = {calculate_product(numbers):,}')
#enum.unique
class Orientation(enum.Enum):
HORIZONTAL = enum.auto()
VERTICAL = enum.auto()
if __name__ == '__main__':
main()

How to handle ISO8583 bitmaps with non-hex characters

I'm trying to correctly parse an ISO8583(1987) message in Python 3 using the py8583 package. After running into some issues with the parser I've realized that the bitmap in the ISO8583 message seems to not be formatted correctly.
This is the ISO8583 bitmap in question:
P8P1211661684989
This is the entire ISO8583 message. It's using trash test data so don't need to worry about sensitive info.
NP0100P8P1211661684989300000000000002004914104019041104009904SHDPf406c431Cashier_01 01301001000200491665D9832B92FD380C
From what I understand the bitmap should only contain 1-9/A-F hex characters, yet as you can see it begins with "P8P12...".
Is there something I'm missing here? These ISO8583 messages are currently being used within an enterprise-level company. Additionally, while some online parsers throw the bitmap error, I've found one that seems to be parsing it just fine (link below). I can't figure out how it's doing the parsing.
http://www.fintrnmsgtool.com/decode-iso87-bitmap.html
(Edit: It was correctly pointed out by glhr that this site doesn't allow you to type non-hex characters, only copy/paste them, so it's probably no longer relevant to the question.)
Hex dump below:
0010 08 00 45 00 00 ab 03 b1 00 00 3c 06 fa 89 c0 a8
0020 15 02 40 87 69 e1 81 1c 0b bb b7 b9 78 55 c7 86
0030 4a 2c 50 18 12 24 2f d3 00 00 4e 50 00 00 00 7d
0040 30 31 30 30 50 38 00 01 80 c0 00 50 31 32 31 31
0050 36 36 31 36 38 34 39 38 39 33 30 30 30 30 30 30
0060 30 30 30 30 30 30 30 32 30 30 34 38 31 34 30 39
0070 35 39 31 39 30 34 31 31 30 34 30 30 39 39 30 34
0080 53 48 44 50 66 34 30 36 63 34 33 31 43 61 73 68
0090 69 65 72 5f 30 31 20 20 20 20 20 30 31 33 30 31
00a0 30 30 31 30 30 30 32 30 30 34 38 31 36 36 35 44
00b0 39 38 33 32 42 39 32 46 44 33 38 30 43
Any help from ISO8583 experts would be greatly appreciated!
Something seems amiss.
From the hex dump it looks like some kind of 0800 network message. That would make the bitmap starting with 0x45. This would be a binary bitmap of 0100 0101, indicating bits 2, 6, and 8 are present. ISO 8583 bit 2 is always a PAN (card number), so that does not make much sense. Bit's 6 and 8 don't seem to make sense in the context of a network message either as the former is cardholder billing amount, and the latter is cardholder amount fee.

Linux: Extract a specified number of lines from text file based on match

I have a text file with multiple datasets. I have written a code that searches for certain values (top left 4-letter code) in a text file but, now I need to be able to have the script copy out data from a set number of lines AFTER the match ("PHHI, etc") is found. The data values are all formatted the same.
Data:
PHHI GFS MOS GUIDANCE 7/13/2015 0000 UTC
DT /JULY 13 /JULY 14 /JULY 15 /
HR 06 09 12 15 18 21 00 03 06 09 12 15 18 21 00 03 06 09 12 18 00
X/N 83 71 84 70 84
TMP 77 76 76 76 76 79 82 81 76 76 74 73 76 80 82 81 76 75 73 76 83
DPT 72 72 72 72 72 72 70 68 70 70 69 69 69 70 70 69 69 69 69 69 69
CLD BK OV BK OV OV BK FW FW CL FW BK FW SC SC FW FW FW CL FW SC FW
WDR 10 09 06 04 07 09 07 08 07 06 03 03 07 08 07 08 07 07 04 07 08
WSP 04 03 03 03 06 11 16 11 06 08 05 03 04 09 12 09 05 03 03 03 10
P06 5 27 16 0 4 2 4 15 5 6 1
P12 39 21 8 19 7
Q06 0 1 0 0 0 0 0 0 0 0 0
Q12 1 1 0 1 0
CIG 5 4 4 4 4 4 5 8 6 6 6 7 6 6 7 8 7 8 8 8 8
VIS 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7
OBV N N N N N N N N N N N N N N N N N N N N N
I am interested in pulling the data values located on the "X/N" line.
To get a specified number of line of data after the match:
grep pattern -A num file
where,
pattern is the pattern to be matched
num is the number of line of data to be taken after the match
For example, to get 3 lines after the PHHI:
grep "^PHHI" -A 3 file
Output:
PHHI GFS MOS GUIDANCE 7/13/2015 0000 UTC
DT /JULY 13 /JULY 14 /JULY 15 /
HR 06 09 12 15 18 21 00 03 06 09 12 15 18 21 00 03 06 09 12 18 00
X/N 83 71 84 70 84
To get only the X/N line:
grep "^X/N.*" file
Output:
X/N 83 71 84 70 84

How to decode the TCP buffer data

I am trying to write a tcp server to get the data from Heacent 908 GPS tracker. After establishing the connection from the tracker I am getting the following buffer output.
<Buffer 78 78 0d 01 03 87 11 31 20 86 48 42 00 06 64 be 0d 0a>
<Buffer 78 78 0d 01 03 87 11 31 20 86 48 42 00 06 64 be 0d 0a>
<Buffer 78 78 0d 01 03 87 11 31 20 86 48 42 00 06 64 be 0d 0a>
<Buffer 78 78 0d 01 03 87 11 31 20 86 48 42 00 06 64 be 0d 0a>
<Buffer 78 78 0d 01 03 87 11 31 20 86 48 42 00 06 64 be 0d 0a>
<Buffer 78 78 0d 01 03 87 11 31 20 86 48 42 00 06 64 be 0d 0a>
<Buffer 78 78 0d 01 03 87 11 31 20 86 48 42 00 06 64 be 0d 0a>
I am not sure how to decode this data into proper readable format.
Note: Off course I have tried to reach the manufacture but they are not responding at all.
What type of possible encoding formats are there for TCP protocol?
On next day I got data like this
<Buffer 78 78 0d 01 03 87 11 31 20 86 48 42 00 07 75 37 0d 0a>
<Buffer 78 78 0d 01 03 87 11 31 20 86 48 42 00 07 75 37 0d 0a>
<Buffer 78 78 0d 01 03 87 11 31 20 86 48 42 00 07 75 37 0d 0a>
<Buffer 78 78 0d 01 03 87 11 31 20 86 48 42 00 07 75 37 0d 0a>
<Buffer 78 78 0d 01 03 87 11 31 20 86 48 42 00 07 75 37 0d 0a>
<Buffer 78 78 0d 01 03 87 11 31 20 86 48 42 00 07 75 37 0d 0a>
<Buffer 78 78 0d 01 03 87 11 31 20 86 48 42 00 07 75 37 0d 0a>
<Buffer 78 78 0d 01 03 87 11 31 20 86 48 42 00 07 75 37 0d 0a>
<Buffer 78 78 0d 01 03 87 11 31 20 86 48 42 00 07 75 37 0d 0a>
<Buffer 78 78 0d 01 03 87 11 31 20 86 48 42 00 08 8d c0 0d 0a>
<Buffer 78 78 0d 01 03 87 11 31 20 86 48 42 00 08 8d c0 0d 0a>
<Buffer 78 78 0d 01 03 87 11 31 20 86 48 42 00 08 8d c0 0d 0a>
<Buffer 78 78 0d 01 03 87 11 31 20 86 48 42 00 08 8d c0 0d 0a>
<Buffer 78 78 0d 01 03 87 11 31 20 86 48 42 00 08 8d c0 0d 0a>
<Buffer 78 78 0d 01 03 87 11 31 20 86 48 42 00 08 8d c0 0d 0a>
<Buffer 78 78 0d 01 03 87 11 31 20 86 48 42 00 08 8d c0 0d 0a>
<Buffer 78 78 0d 01 03 87 11 31 20 86 48 42 00 08 8d c0 0d 0a>
<Buffer 78 78 0d 01 03 87 11 31 20 86 48 42 00 08 8d c0 0d 0a>
<Buffer 78 78 0d 01 03 87 11 31 20 86 48 42 00 08 8d c0 0d 0a>
<Buffer 78 78 0d 01 03 87 11 31 20 86 48 42 00 08 8d c0 0d 0a>
<Buffer 78 78 0d 01 03 87 11 31 20 86 48 42 00 08 8d c0 0d 0a>
<Buffer 78 78 1f 12 0e 02 14 13 01 14 c8 03 5f a6 50 07 f7 f8 c1 32 35 39 01 9a 04 0f a2 00 b0 5a 00 1a 9b 7a 0d 0a>
<Buffer 78 78 1f 12 0e 02 14 13 01 1e c8 03 5f ad bc 07 f7 f0 76 41 35 40 01 9a 04 0f a2 00 b0 5a 00 1b b6 31 0d 0a>
Something is being changed but not sure what is it...
You ask what possible encoding formats there are for TCP. That's a bit of an odd question: there are an unbounded number of encoding formats using TCP as the underlying protocol. But no matter, we can try to figure out this one!
You've posted some sample messages. Let's see if we can translate them:
byte 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
rev 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
----------------------------------------------------------
hex 78 78 0d 01 03 87 11 31 20 86 48 42 00 06 64 be 0d 0a
text x x \r -- -- -- -- 1 -- H B -- -- d -- \r \n
dec 13 1 3 17 0 6 100 13 10
be32 [218170247] [288432262] [ 419006]
----------------------------------------------------------
hex 78 78 0d 01 03 87 11 31 20 86 48 42 00 07 75 37 0d 0a
text -- u 7
dec 7 117 55
be32 [ 488759]
----------------------------------------------------------
hex 78 78 0d 01 03 87 11 31 20 86 48 42 00 08 8d c0 0d 0a
text -- -- --
dec 8 141
be32 [ 560576]
----------------------------------------------------- byte 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
hex 78 78 1f 12 0e 02 14 13 01 14 c8 03 5f a6 50 07 f7 f8 c1 32 35 39 01 9a 04 0f a2 00 b0 5a 00 1a 9b 7a 0d 0a
text -- -- -- -- -- -- -- -- -- -- _ -- P -- -- -- -- 2 5 9 -- -- -- -- -- -- -- -- -- xx -- z \r \n
----------------------------------------------------------
hex 78 78 1f 12 0e 02 14 13 01 1e c8 03 5f ad bc 07 f7 f0 76 41 35 40 01 9a 04 0f a2 00 b0 5a 00 1b b6 31 0d 0a
text -- -- -- A 5 # -- xx -- 1
Some potentially interesting facts:
Starts with "xx\r\01" which more or less seems like a possible header. But later messages start with "xx" and something else. Anyway, given that NMEA has a prefix of "GP" I wouldn't be shocked if these devices used "xx" for "something that's not NMEA."
Has "HB" in the middle, which could mean "heartbeat" since this is repeating, perhaps waiting for a reply from the server.
Ends with "\r\n" which is a common line ending (on Windows in particular), though the rest doesn't appear to be entirely textual.
The earlier messages are 18 bytes long and the later ones 36 bytes. A guess would be the short ones are status updates or heartbeats and the long ones are actual location information. 36 bytes is enough if we figure:
4 byte latitude: 24 bits if you pinch (see), 25-32 bits more likely
4 byte longitude: same as latitude
6 byte timestamp: 39 bits if using epoch time with centiseconds, 32/48/64 bits more likely
2 byte altitude: I suspect this device doesn't publish altitude at all, given some of the docs
So I think what is going on is that these messages you see are just the device "pinging" the server and waiting for a response. What sort of response? Well, you could try to brute force it, but far, far easier would be to set up a bridge in your program that takes whatever it receives from the device, sends it to the manufacturer's server, and does the same thing in reverse for the responses to the device. This way you will quickly be able to gather a corpus of valid messages which will be very helpful if we really do need to reverse engineer this thing. Or if you're lucky it will turn out to use some standard protocol like NMEA after negotiating the initial session.
Edit: now that you've given us more messages from the device, we can see that it does seem to send something else with variable content. Maybe that's the location data, but I don't have time to try to reverse engineer it right now. One idea is to physically move the unit from west to east or north to south and capture the messages it sends during that time, to try to isolate which parts of the messages are the longitude and which are the latitude (and perhaps timestamp too).
I think it's fairly clear that the first two bytes are "xx" as a header, and the last two are "\r\n" as a terminator. That leaves 32 bytes of payload in the longer messages, all of which appears to be binary data.
It's the GT06 protocol and you can find it's specs here:
http://www.traccar.org/devices/
http://www.traccar.org/docs/protocol.jsp
https://dl.dropboxusercontent.com/s/sqtkulcj51zkria/GT06_GPS_Tracker_Communication_Protocol_v1.8.1.pdf
You can do it this way:
client.on('data', (buffer) => {
const decodedData = buffer.toString('utf8')
console.log(decodedData)
})

Resources