SCL011 contactless Card Reader and Mifare 1k(classic) authentification - mifare

I have SCL011 Card Reader and need to read/write Mifare 1k cards. But I just can't get over Authentification step....
Card Reader should handle Mifare 1k cards:
Antenna ISO/IEC 14443 compliant design
Baudrate up to 848 Kbps
Supported standards:
ISO/IEC 14443-4 Typ A & B
MIFARE: Classic 1K and 4K, DESFire, Ultralight, MIFARE Plus
FeliCa™
NFC forum tag type 1, 2, 3, 4
iCLASS UID*
I have also updated to the latest firmware (1.20)
http://support.identive-group.com/dfu_fw.php?OS=windows&readerno=85
card is connected and I can read the UID of the card with ff ca 00 00 00
I have also tried to read the sector directly without authorization ff b0 00 00 10 and I get message:
69 82 : Command not allowed. Security status not satisfied.
it means I need authorize myself, but if I try ff 82 00 00 06 ff ff ff ff ff ff or any other standard keys I always get back:
69 88 : Command not allowed. SM data objects incorrect.
funny thing is, that I can read and write this card without problems with my Nexus and Lumia phones...
What I'm doing wrong? Thanks for any help!
keys I have already tried:
* ff 82 00 00 06 ff ff ff ff ff ff
* ff 82 00 00 06 a0 b0 c0 d0 e0 f0
* ff 82 00 00 06 a1 b1 c1 d1 e1 f1
* ff 82 00 00 06 a0 a1 a2 a3 a4 a5
* ff 82 00 00 06 b0 b1 b2 b3 b4 b5
* ff 82 00 00 06 4d 3a 99 c3 51 dd
* ff 82 00 00 06 1a 98 2c 7e 45 9a
* ff 82 00 00 06 00 00 00 00 00 00
* ff 82 00 00 06 d3 f7 d3 f7 d3 f7
* ff 82 00 00 06 aa bb cc dd ee ff

Solution: Please google/search "Multiprotocol contactless mobile reader, Reference manual" or "SCL01X Multiprotocol contactless stationary reader".
It is a very nice references to start with SCL reader's APDUs. There are some examples inside.
Answer: In your case P2 value in the APDU Command incorrect and you got SW1SW2 = 0x6988 - "Key number not valid".
Where P2 can have the following values (please refer to MIFARE documentation from NXP for
further details on what is key A and Key B):
• 0x60 to use the Key A
• 0x61 to use the Key B

Related

How to catch data from SIM

I use a CardReader to communicate to a SIM-card.
For example, I need to get an IMSI from the SIM card.
To do this I send some commands (SELECT 3F00/7F20/6F07):
A0 A4 00 00 02 3F 00
A0 A4 00 00 02 7F 20
A0 A4 00 00 02 6F 07
and here I send READ BINARY command
A0 B0 00 00 09
and after that I receive 90 00 --> Ok - normal ending of the command.
Hey! And where is my IMSI stored?? How can I catch data, which were read by "A0 B0 00 00 09" command?
If I try "A0 C0 00 00 00" command (GET RESPONSE) I will get an Error.
You don't need to send Get Response Command "A0 C0 00 00 00" after Read Data.
There are 9 bytes of data in reply to your Read Data Command "A0 B0 00 00 09".

Where are files marked as assume-unchanged in Git? [duplicate]

I like to modify config files directly (like .gitignore and .git/config) instead of remembering arbitrary commands, but I don't know where Git stores the file references that get passed to "git update-index --assume-unchanged file".
If you know, please do tell!
It says where in the command - git update-index
So you can't really be editing the index as it is not a text file.
Also, to give more detail on what is stored with the git update-index --assume-unchanged command, see the Using “assume unchanged” bit section in the manual
As others said, it's stored in the index, which is located at .git/index.
After some detective work, I found that it is located at the: assume valid bit of each index entry.
Therefore, before understanding what follows, you should first understand the global format of the index, as explained in my other answer.
Next, I will explain how I verified that the "assume valid" bit is the culprit:
empirically
by reading the source
Empirical
Time to hd it up.
Setup:
git init
echo a > b
git add b
Then:
hd .git/index
Gives:
00000000 44 49 52 43 00 00 00 02 00 00 00 01 54 e9 b6 f3 |DIRC........T...|
00000010 2d 4f e1 2f 54 e9 b6 f3 2d 4f e1 2f 00 00 08 05 |-O./T...-O./....|
00000020 00 de 32 ff 00 00 81 a4 00 00 03 e8 00 00 03 e8 |..2.............|
00000030 00 00 00 00 e6 9d e2 9b b2 d1 d6 43 4b 8b 29 ae |...........CK.).|
00000040 77 5a d8 c2 e4 8c 53 91 00 01 62 00 c9 a2 4b c1 |wZ....S...b...K.|
00000050 23 00 1e 32 53 3c 51 5d d5 cb 1a b4 43 18 ad 8c |#..2S<Q]....C...|
00000060
Now:
git update-index --assume-unchanged b
hd .git/index
Gives:
00000000 44 49 52 43 00 00 00 02 00 00 00 01 54 e9 b6 f3 |DIRC........T...|
00000010 2d 4f e1 2f 54 e9 b6 f3 2d 4f e1 2f 00 00 08 05 |-O./T...-O./....|
00000020 00 de 32 ff 00 00 81 a4 00 00 03 e8 00 00 03 e8 |..2.............|
00000030 00 00 00 00 e6 9d e2 9b b2 d1 d6 43 4b 8b 29 ae |...........CK.).|
00000040 77 5a d8 c2 e4 8c 53 91 80 01 62 00 17 08 a8 58 |wZ....S...b....X|
00000050 f7 c5 b3 e1 7d 47 ac a2 88 d9 66 c7 5c 2f 74 d7 |....}G....f.\/t.|
00000060
By comparing the two indexes, and looking at the global structure of the index, see that the only differences are:
byte number 0x48 (9th on line 40) changed from 00 to 80. That is our flag, the first bit of the cache entry flags.
the 20 bytes from 0x4C to 0x5F. This is expected since that is a SHA-1 over the entire index.
This has also though me that the SHA-1 of the index entry in bytes from 0x34 to 0x47 does not take into account the flags, since it did not changed between both indexes. This is probably why the flags are placed after the SHA, which only considers what comes before it.
Source code
Now let's see if that is coherent with source code of Git 2.3.
First look at the source of update-index, grep assume-unchanged.
This leads to the following line:
{OPTION_SET_INT, 0, "assume-unchanged", &mark_valid_only, NULL,
N_("mark files as \"not changing\""),
PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, MARK_FLAG},
{OPTION_SET_INT, 0, "no-assume-unchanged", &mark_valid_only, NULL,
N_("clear assumed-unchanged bit"),
PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, UNMARK_FLAG},
so the value is stored at mark_valid_only. Grep it, and find that it is only used at one place:
if (mark_valid_only) {
if (mark_ce_flags(path, CE_VALID, mark_valid_only == MARK_FLAG))
die("Unable to mark file %s", path);
return;
}
CE means Cache Entry.
By quickly inspecting mark_ce_flags, we see that:
if (mark)
active_cache[pos]->ce_flags |= flag;
else
active_cache[pos]->ce_flags &= ~flag;
So the function basically sets or unsets the CE_VALID bit, depending on mark_valid_only, which is a tri-state:
mark: --assume-unchanged
unmark: --no-assume-unchanged
do nothing: the default value 0 of the option set at {OPTION_SET_INT, 0
Next, by grepping under builtin/, we see that no other place sets the value of CE_VALID, so --assume-unchanged must be the only command that sets it.
The flag is however used in many places of the source code, which should be expected as it has many side-effects, and it is used every time like:
ce->ce_flags & CE_VALID
so we conclude that it is part of the ce_flags field of struct cache_entry.
The index is specified at cache.h because one of its functions is to be a cache for creating commits faster.
By looking at the definition of CE_VALID under cache.h and surrounding lines we have:
#define CE_STAGEMASK (0x3000)
#define CE_EXTENDED (0x4000)
#define CE_VALID (0x8000)
#define CE_STAGESHIFT 12
So we conclude that it is the very first bit of that integer (0x8000), just next to the CE_EXTENDED, which is coherent with my earlier experiment.

Midi track meta event values which do not conform to the specification

Hi I have scraped a large number of midi files off the internet.
I am using them for training material to train a generative adversarial network. I find that many midi files conform to the midi standard but then I run into issues with midi meta events with values of FF11 and FF10 . I have looked up the midi specification from several sources and have never found midi meta events defined in this way. Here is the hex of a midi track event with some of the offending values:
4D 54 72 6B 00 00 1A 8D 00 FF 03 0D 47 75 69 74
61 72 20 44 41 44 47 41 44 00 FF 10 08 00 00 3E
39 37 32 2D 26 00 C0 19 00 C1 19 00 B0 65 00 00
B0 64 00 00 B0 06 02 00 B0 65 7F 00 B0 64 7F 00
E0 00 40 00 B1 65 00 00 B1 64 00 00 B1 06 02 00
B1 65 7F 00 B1 64 7F 00 E1 00 40 00 B0 0A 3F 00
B1 0A 3F 00 B0 5D 10 00 B0 5B 1E 00 B1 5D 10 00
B1 5B 1E 81 69 FF 11 01 00 00 90 3E 51 08 FF 11
I cant seem to find any information whatsoever on these values even though these midi files play over timidity and other midi player software perfectly. Can anyone point me to some information about them and what they mean? any help would be greatly , greatly appreciated. :-) resolving this issue would be a service to the miriad of people who are trying to use the python-midi library to train tensorflow models and this I am sure is only a fraction of the people who would be effected.
The SMF specification says:
As with chunks, future meta-events may be designed which may not be known to existing programs, so programs must properly ignore meta-events which they do not recognize, and indeed, should expect to see them.
I am not aware of any published extension that defines values 10h or 11h; it's likely that some sequencer uses these for its own purposes, and violated the specification by not using type 7F for that.

Mifare Desfire Wrapped Mode: How to calculate CMAC?

When using Desfire native wrapped APDUs to communicate with the card, which parts of the command and response must be used to calculate CMAC?
After successful authentication, I have the following session key:
Session Key: 7CCEBF73356F21C9191E87472F9D0EA2
Then when I send a GetKeyVersion command, card returns the following CMAC which I'm trying to verify:
<< 90 64 00 00 01 00 00
>> 00 3376289145DA8C27 9100
I have implemented CMAC algorithm according to "NIST special publication 800-38B" and made sure it is correct. But I don't know which parts of command and response APDUs must be used to calculate CMAC.
I am using TDES, so MAC is 8 bytes.
I have been looking at the exact same issue for the last few days and I think I can at least give you some pointers. Getting everything 'just so' has taken some time and the documentation from NXP (assuming you have access) is a little difficult to interpret in some cases.
So, as you probably know, you need to calculate the CMAC (and update your init vec) on transmit as well as receive. You need to save the CMAC each time you calculate it as the init vec for the next crypto operation (whether CMAC or encryption etc).
When calculating the CMAC for your example the data to feed into your CMAC algorithm is the INS byte (0x64) and the command data (0x00). Of course this will be padded etc as specified by CMAC. Note, however, that you do not calculate the CMAC across the entire APDU wrapping (i.e. 90 64 00 00 01 00 00) just the INS byte and data payload is used.
On receive you need to take the data (0x00) and the second status byte (also 0x00) and calculate the CMAC over that. It's not important in this example but order is important here. You use the response body (excluding the CMAC) then SW2.
Note that only half of the CMAC is actually sent - CMAC should yield 16 bytes and the card is sending the first 8 bytes.
There were a few other things that held me up including:
I was calculating the session key incorrectly - it is worth double checking this if things are not coming out as you'd expect
I interpreted the documentation to say that the entire APDU structure is used to calculate the CMAC (hard to read them any other way tbh)
I am still working on calculating the response from a Write Data command correctly. The command succeeds but I can't validate the CMAC. I do know that Write Data is not padded with CMAC padding but just zeros - not yet sure what else I've missed.
Finally, here is a real example from communicating with a card from my logs:
Authentication is complete (AES) and the session key is determined to be F92E48F9A6C34722A90EA29CFA0C3D12; init vec is zeros
I'm going to send the Get Key Version command (as in your example) so I calculate CMAC over 6400 and get 1200551CA7E2F49514A1324B7E3428F1 (which is now my init vec for the next calculation)
Send 90640000010000 to the card and receive 00C929939C467434A8 (status is 9100).
Calculate CMAC over 00 00 and get C929939C467434A8A29AB2C40B977B83 (and update init vec for next calculation)
The first half of our CMAC from step #4 matches the 8 byte received from the card in step #3
Sry for my English,- its terrible :) but it's not my native language. I'm Russian.
Check first MSB (7 - bit) of array[0] and then shiffting this to the left. And then XOR if MSB 7 bit was == 1;
Or save first MSB bit of array[0] and after shiffting put this bit at the end of array[15] at the end (LSB bit).
Just proof it's here:
https://www.nxp.com/docs/en/application-note/AN10922.pdf
Try this way:
Zeros <- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
SessionKey <- 00 01 02 03 E3 27 64 0C 0C 0D 0E 0F 5C 5D B9 D5
Data <- 6F 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00
First u have to encrypt 16 bytes (zeros) with SesionKey;
enc_aes_128_ecb(Zeros);
And u get EncryptedData.
EncryptedData <- 3D 08 A2 49 D9 71 58 EA 75 73 18 F2 FA 6A 27 AC
Check bit 7 [MSB - LSB] of EncryptedData[0] == 1? switch i to true;
bool i = false;
if (EncryptedData[0] & 0x80){
i = true;
}
Then do Shiffting of all EncryptedData to 1 bit <<.
ShiftLeft(EncryptedData,16);
And now, when i == true - XOR the last byte [15] with 0x87
if (i){
ShiftedEncryptedData[15] ^= 0x87;
}
7A 11 44 93 B2 E2 B1 D4 EA E6 31 E5 F4 D4 4F 58
Save it as KEY_1.
Try bit 7 [MSB - LSB] of ShiftedEncryptedData[0] == 1?
i = false;
if (ShiftedEncryptedData[0] & 0x80){
i = true;
}
Then do Shiffting of all ShiftedEncryptedData to 1 bit <<.
ShiftLeft(ShiftedEncryptedData,16);
And now, when i == true - XOR the last byte [15] with 0x87
if (i){
ShiftedEncryptedData[15] ^= 0x87;
}
F4 22 89 27 65 C5 63 A9 D5 CC 63 CB E9 A8 9E B0
Save it as KEY_2.
Now we take our Data (6F 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00)
As Michael say's - pad command with 0x80 0x00...
XOR Data with KEY_2 - if command was padded, or KEY_1 if don't.
If we have more like 16 bytes (32 for example) u have to XOR just last 16 bytes.
Then encrypt it:
enc_aes_128_ecb(Data);
Now u have a CMAC.
CD C0 52 62 6D F6 60 CA 9B C1 09 FF EF 64 1A E3
Zeros <- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
SessionKey <- 00 01 02 03 E3 27 64 0C 0C 0D 0E 0F 5C 5D B9 D5
Key_1 <- 7A 11 44 93 B2 E2 B1 D4 EA E6 31 E5 F4 D4 4F 58
Key_2 <- F4 22 89 27 65 C5 63 A9 D5 CC 63 CB E9 A8 9E B0
Data <- 6F 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00
CMAC <- CD C0 52 62 6D F6 60 CA 9B C1 09 FF EF 64 1A E3
C/C++ function:
void ShiftLeft(byte *data, byte dataLen){
for (int n = 0; n < dataLen - 1; n++) {
data[n] = ((data[n] << 1) | ((data[n+1] >> 7)&0x01));
}
data[dataLen - 1] <<= 1;
}
Have a nice day :)

sed extract data from dos text file convert to csv

I need to pull RAM information from several cpuz reports and put them into a csv for reporting reasons.
below is an example text file (snipped) which contains the text i want to extract.
I want to extract all the text following the lines beginning with DIMM but only where the next line begins with tab and SMBus address, and going down to nominal voltage. I'd then like to split them into columns (although I only really care about the type, size and max bandwidth)
the resultant csv would have the following columns (and 2 rows in this example)
computer name (from file name), Dimm #, smbus address, memory type, manufacturer, etc.
However I have fallen at the first, extraction phase. I was using sed but fell over at this multiline command:
sed -n -e 'N;/DIMM #\t*[0-9]\r\n\t/,/Nominal/p' cpuz-FHD505.txt
for some reason it only picks up the DIMM #2 block.
what sed statement should I use to just give me the two dimm blocks up to the line including Nominal voltage?
to be honest I'm probably going to give up and write this in python anyway as I'm more familiar, but I'd love to know where I've screwed up on this multiline sed statement.
cpuz output:-
Chipset
-------------------------------------------------------------------------
Northbridge Intel i845G rev. A1
Southbridge Intel 82801DB (ICH4) rev. 01
Memory Type DDR
Memory Size 1024 MBytes
Memory Frequency 132.9 MHz (1:1)
CAS# latency (CL) 2.0
RAS# to CAS# delay (tRCD) 3
RAS# Precharge (tRP) 3
Cycle Time (tRAS) 6
DRAM Idle Timer 16
Memory SPD
-------------------------------------------------------------------------
DIMM # 1
SMBus address 0x50
Memory type DDR
Manufacturer (ID) Infineon (C1494E46494E454F)
Size 512 MBytes
Max bandwidth PC2700 (166 MHz)
Part number 64D64320GU6B
Serial number 075ADD21
Manufacturing date Week 56/Year 03
Number of banks 2
Data width 64 bits
Correction None
Registered no
Buffered no
Nominal Voltage 2.50 Volts
EPP no
XMP no
JEDEC timings table CL-tRCD-tRP-tRAS-tRC # frequency
JEDEC #1 2.0-3-3-6-n.a. # 133 MHz
JEDEC #2 2.5-3-3-7-n.a. # 166 MHz
DIMM # 2
SMBus address 0x51
Memory type DDR
Manufacturer (ID) Samsung (CE00000000000000)
Size 512 MBytes
Max bandwidth PC2700 (166 MHz)
Part number M3 68L6423ETN-CB3
Serial number 060EFC37
Manufacturing date Week 54/Year 04
Number of banks 2
Data width 64 bits
Correction None
Registered no
Buffered no
Nominal Voltage 2.50 Volts
EPP no
XMP no
JEDEC timings table CL-tRCD-tRP-tRAS-tRC # frequency
JEDEC #1 2.0-3-3-6-n.a. # 133 MHz
JEDEC #2 2.5-3-3-7-n.a. # 166 MHz
DIMM # 1
SPD registers
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
00 80 08 07 0D 0A 02 40 00 04 60 70 00 82 08 00 01
10 0E 04 0C 01 02 20 C0 75 70 00 00 48 30 48 2A 40
20 75 75 45 45 00 00 00 00 00 3C 48 30 2D 55 00 00
30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
40 C1 49 4E 46 49 4E 45 4F 08 36 34 44 36 34 33 32
50 30 47 55 36 42 20 20 20 20 20 20 01 4A 03 38 07
60 5A DD 21 00 00 00 00 00 00 00 00 00 00 00 00 00
70 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
90 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
A0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
B0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
C0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
D0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
E0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
F0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
DIMM # 2
SPD registers
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
00 80 08 07 0D 0A 02 40 00 04 60 70 00 82 08 00 01
10 0E 04 0C 01 02 20 C0 75 70 00 00 48 30 48 2A 40
20 80 80 45 45 00 00 00 00 00 3C 48 30 2D 55 00 00
30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 10 27
40 CE 00 00 00 00 00 00 00 01 4D 33 20 36 38 4C 36
50 34 32 33 45 54 4E 2D 43 42 33 20 4E 45 04 36 06
60 0E FC 37 00 58 39 42 36 37 30 30 00 00 00 00 00
70 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80 00 03 B2 10 09 19 FF FF FF FF FF 05 12 05 FF FF
90 00 03 B2 10 09 39 FF FF FF FF FF 02 20 18 FF FF
A0 00 03 B2 10 09 19 FF FF FF FF FF 04 23 54 FF FF
B0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
C0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
D0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
E0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
F0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
Monitoring
-------------------------------------------------------------------------
Mainboard Model 07E4h (0x00000148 - 0x00024680)
LPCIO
-------------------------------------------------------------------------
LPCIO Vendor SMSC
LPCIO Vendor ID 0x55
LPCIO Chip ID 0x6D
Config Mode I/O address 0x2E
Config Mode LDN 0x8
Config Mode registers
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
00 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00 00
10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
20 6D 01 09 00 04 00 2E 00 00 00 00 00 00 00 00 00
30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
70 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Hardware Monitors
-------------------------------------------------------------------------
Hardware monitor SMSC EMC6D10X
Voltage 0 0.00 Volts [0x0] (+1.5V)
Voltage 1 1.47 Volts [0x7D] (CPU VCORE)
Voltage 2 3.26 Volts [0xBE] (ATX +3.3V)
Voltage 3 5.10 Volts [0xC4] (ATX +5V)
Voltage 4 11.98 Volts [0xBF] (ATX +12V)
Temperature 0 0°C (32°F) [0x0] (Diode 1)
Temperature 1 24°C (75°F) [0x18] (Internal)
Temperature 2 33°C (91°F) [0x21] (Diode 2)
Fan 0 1455 RPM [0xE7F] (FANIN0)
Register space SMBus, base address = 0x0FC00
SMBus request channel 0x0, address 0x2E
output:
DIMM # 2
SMBus address 0x51
Memory type DDR
Manufacturer (ID) Samsung (CE00000000000000)
Size 512 MBytes
Max bandwidth PC2700 (166 MHz)
Part number M3 68L6423ETN-CB3
Serial number 060EFC37
Manufacturing date Week 54/Year 04
Number of banks 2
Data width 64 bits
Correction None
Registered no
Buffered no
Nominal Voltage 2.50 Volts
EPP no
Give this a try:
sed -n ':a; /^DIMM/,/^[[:blank:]]*Nominal Voltage/ N; /^DIMM/,/[[:blank:]]*Nominal Voltage/ ! d ;/[[:blank:]]*Nominal Voltage/ {/[[:blank:]]*Nominal Voltage/p;d}; ba' cpuz-FHD505.txt
awk -vRS="" -F"\n" '/DIMM/&&$2~/SMBus/{
for(i=1;i<=NF;i++) {
print $i
# from here, you process the columns you need
}
}' file