Search code examples
mysqltcppackettcpdumpamazon-aurora

Extract mysql query from tcpdump


I'm using tcpdump to capture TCP packet from port 3306 which is forwarded to MySQL server

sudo tcpdump -X -i ens5 -s 0 -tttt dst port 3306

and executed SQL select * from user_trading_volume limit 1 from MySQL client

the captured result is below

2020-05-27 07:46:44.330084 IP ip-10-0-1-33.ap-northeast-2.compute.internal.59750 > ip-10-30-1-179.ap-northeast-2.compute.internal.mysql: Flags [P.], seq 1945:2020, ack 16715, win 512, options [nop,nop,TS val 3790143765 ecr 4258512397], length 75
0x0000:  4500 007f 54fb 4000 4006 ce8c 0a00 0121  E...T.@.@......!
0x0010:  0a1e 01b3 e966 0cea 76a0 9245 c975 2466  .....f..v..E.u$f
0x0020:  8018 0200 1763 0000 0101 080a e1e9 0115  .....c..........
0x0030:  fdd3 be0d 1703 0300 46f5 525d 17c9 20ac  ........F.R]....
0x0040:  62e6 fcdc ba82 11fc 91c2 c187 7ca8 a542  b...........|..B
0x0050:  6ed8 a1fa b1d8 01bd 1240 61d9 686e 183d  [email protected].=
0x0060:  f2fc 9b9a a62d c212 8d4d e1c6 e67a 4bdc  .....-...M...zK.
0x0070:  ea2e 75dc 68cf 5c45 1721 2ced c511 ca    ..u.h.\E.!,....

2020-05-27 07:46:44.331029 IP ip-10-0-1-33.ap-northeast-2.compute.internal.59750 > ip-10-30-1-179.ap-northeast-2.compute.internal.mysql: Flags [.], ack 17677, win 505, options [nop,nop,TS val 3790143766 ecr 4258513778], length 0
0x0000:  4500 0034 54fc 4000 4006 ced6 0a00 0121  E..4T.@.@......!
0x0010:  0a1e 01b3 e966 0cea 76a0 9290 c975 2828  .....f..v....u((
0x0020:  8010 01f9 1718 0000 0101 080a e1e9 0116  ................
0x0030:  fdd3 c372        

but the captured packet was not readable (Which means not ASCII)

I'm using AWS aurora (mysql 5.7)

Does anyone knows what this packet means?

PS. I tried it in my local environment too and could retrieve matching SQL from packet as below (run mysql within docker container and executed query through mysql workbench)

16:59:46.628631 IP (tos 0x0, ttl 64, id 59587, offset 0, flags [DF], proto TCP (6), length 98)
    view-localhost.52652 > view-localhost.3318: Flags [P.], cksum 0xfe56 (incorrect -> 0x1538), seq 61:107, ack 899, win 512, options [nop,nop,TS val 632447157 ecr 632447154], length 46
E..b..@[email protected]...............@....=.....V.....
%.`.%.`.*....select * from user_trading_volume limit 1

Solution

  • Looking at the first byte, this looks like two raw IP packets (45 => IP version 4, typical 20byte header (5 * 4 bytes). Wikipedia has more info on IP headers.

    Converting to pcap

    Thus, we should be able to convert this back to a pcap. We can convert this text dump to a packet capture using text2pcap, which is a command line utility that ships with Wireshark.

    With the given text as file temp, we can convert it into a pcap

    $ cat temp | grep -v 2020 | cut -c3-49 | sed 's/ \(\w\w\)/ \1 /g' \
     | text2pcap -l 101 - temp.pcap
    Input from: Standard input
    Output to: temp.pcap
    Output format: pcap
    Wrote packet of 127 bytes.
    Wrote packet of 52 bytes.
    Read 2 potential packets, wrote 2 packets (235 bytes).
    

    Sanitizing text2pcap input

    Here, we sanitize input so that text2pcap doesn't fail:

    • grev -v 2020: remove the 2020... info lines
    • cut -c3-49: Remove the preceding 0x and ASCII representation
    • sed 's/ \(\w\w\)/ \1 /g': Convert hexdump from 2 bytes then space to 1 byte then space (09ab => 09 ab)
    • text2pcap -l 101 - temp.cap: Read from stdin and write to temp.pcap as Raw IP packets (see below)

    You can now view this capture in Wireshark to see what the fields are.

    Figuring out the linklayer number for text2pcap

    Going back to the initial byte, that byte starts the IP layer when normally a link layer like Ethernet starts the packet. That means that we can't use the typical link layer of 1 (Ethernet). The link layer for raw IP is 101, so we need to specify that with text2pcap as -l 101. - is standard input, and then we write the file as temp.pcap.

    What does the packet mean?

    When loaded in Wireshark, packet 1 has a payload of 75 bytes, and it's not ASCII. You will probably want to manually decode these bytes using the MySQL protocol reference. Because according to docs,

    The MySQL protocol is used between MySQL Clients and a MySQL Server.