Computer Stuff

Oct 18, 2014

Blue Penguin

I recently made a new pelican theme: Blue Penguin. It's based on pelican-mockingbird. And it is of course the theme i'm using right now.

I've changed/improved some of the stylings, including:

  • A solarized theme for pygments.
  • Larger content width.
  • Better image handling.
  • Lots of small tweaks.

Aug 31, 2014

Reversing destruct_me with radare2

My friend depierre proposed me a reversing challenge. He had made a small binary, and my goal was of course to find the flag.

$ ./destruct_me
Usage: ./destruct_me password
KO

Knowing depierre, i knew it would be tricky. But still, let's search for some interesting strings:

$ r2 -A destruct_me
 -- I hope you segfault in hell.
[0x08048360]> iz
vaddr=0x08048709 paddr=0x00000709 ordinal=000 sz=8 len=6 section=.rodata type=u string=ԁ%c%c\n
vaddr=0x08048711 paddr=0x00000711 ordinal=001 sz=20 len=19 section=.rodata type=a string=Usage: %s password\n
vaddr=0x08048725 paddr=0x00000725 ordinal=002 sz=11 len=10 section=.rodata type=a string=Not_A_FLAG

Not_A_FLAG is of course a trap, it seems to hang and eat the cpu. Notice how i use the -A flag in the following r2 command. It tells r2 to do the aa command at startup, which analyzes the binary for us (xrefs, functions, ...):

[0x08048360]> pdf@main
|          ; UNKNOWN XREF from 0x080485cd (unk)
|          ; DATA XREF from 0x08048377 (entry0)
/ (fcn) main 139
|          0x080485cd    55           push ebp
|          0x080485ce    89e5         mov ebp, esp
|          0x080485d0    53           push ebx
|          0x080485d1    83e4f0       and esp, 0xfffffff0
|          0x080485d4    83ec10       sub esp, 0x10
|          0x080485d7    837d0801     cmp dword [ebp+0x8], 0x1
|      ,=< 0x080485db    7f1c         jg loc.080485f9
|      |   0x080485dd    8b450c       mov eax, [ebp+0xc]
|      |   0x080485e0    8b00         mov eax, [eax]
|      |   0x080485e2    89442404     mov [esp+0x4], eax
|      |   0x080485e6    c7042411870. mov dword [esp], str.Usage___s_password_n ; str.Usage___s_password_n
|      |   0x080485ed    e82efdffff   call sym.imp.printf
|      |      sym.imp.printf(unk, unk)
|      |   0x080485f2    b8ffffffff   mov eax, 0xffffffff ; -1
|     ,==< 0x080485f7    eb5a         jmp loc.08048653
|     ||   ; JMP XREF from 0x080485db (unk)
|- loc.080485f9 95
|     |`-> 0x080485f9    8b450c       mov eax, [ebp+0xc]
|     |    0x080485fc    83c004       add eax, 0x4
|     |    0x080485ff    8b00         mov eax, [eax]
|     |    0x08048601    c7442404258. mov dword [esp+0x4], str.Not_A_FLAG ; str.Not_A_FLAG
|     |    0x08048609    890424       mov [esp], eax
|     |    0x0804860c    e8fffcffff   call sym.imp.strcmp
|     |       sym.imp.strcmp()
|     |    0x08048611    85c0         test eax, eax
|    ,===< 0x08048613    7519         jne loc.0804862e
|    ||    0x08048615    8b450c       mov eax, [ebp+0xc]
|    ||    0x08048618    83c004       add eax, 0x4
|    ||    0x0804861b    8b18         mov ebx, [eax]
|    ||    0x0804861d    e837ffffff   call fcn.08048559
|    ||       fcn.08048559()
|    ||    0x08048622    d95c240c     fstp dword [esp+0xc]
|    ||    0x08048626    f30f2c44240c cvttss2si eax, [esp+0xc]
|    ||    0x0804862c    8803         mov [ebx], al
|    |     ; JMP XREF from 0x08048613 (unk)
|- loc.0804862e 42
|    `---> 0x0804862e    8b450c       mov eax, [ebp+0xc]
|     |    0x08048631    83c004       add eax, 0x4
|     |    0x08048634    8b00         mov eax, [eax]
|     |    0x08048636    890424       mov [esp], eax
|     |    0x08048639    e802fdffff   call sym.imp.strlen
|     |       sym.imp.strlen()
|     |    0x0804863e    a39c990408   mov [0x804999c], eax
|     |    0x08048643    8b450c       mov eax, [ebp+0xc]
|     |    0x08048646    8b4004       mov eax, [eax+0x4]
|     |    0x08048649    a398990408   mov [0x8049998], eax
|     |    0x0804864e    b800000000   mov eax, 0x0
|     |    ; JMP XREF from 0x080485f7 (unk)
|- loc.08048653 5
|     `--> 0x08048653    8b5dfc       mov ebx, [ebp-0x4]
|          0x08048656    c9           leave
\          0x08048657    c3           ret

Looks like it's the fcn.08048559 on line 36 that's hanging:

[0x08048360]> pdf @ 0x08048559
; UNKNOWN XREF from 0x08048559 (fcn.08048559)
; CALL XREF from 0x0804861d (unk)
/ (fcn) fcn.08048559 116
|          0x08048559    55           push ebp
|          0x0804855a    89e5         mov ebp, esp
|          0x0804855c    83ec20       sub esp, 0x20
|          0x0804855f    a130870408   mov eax, [0x8048730]
|          0x08048564    8945fc       mov [ebp-0x4], eax
|          0x08048567    c745f800000. mov dword [ebp-0x8], 0x0
|      ,=< 0x0804856e    eb12         jmp fcn.08048582
|          ; JMP XREF from 0x0804858b (fcn.08048559)
|          ; JMP XREF from 0x08048596 (fcn.08048559)
|- loc.08048570 93
|    ..--> 0x08048570    8345f801     add dword [ebp-0x8], 0x1
|    |||   0x08048574    d945fc       fld dword [ebp-0x4]
|    |||   0x08048577    dd0538870408 fld qword [0x8048738]
|    |||   0x0804857d    dee9         fsubp st1, st0
|    |||   0x0804857f    d95dfc       fstp dword [ebp-0x4]
|    |||   ; JMP XREF from 0x0804856e (fcn.08048559)
|- fcn.08048582 75
|    ||`-> 0x08048582    d945fc       fld dword [ebp-0x4]
|    ||    0x08048585    d9ee         fldz
|    ||    0x08048587    dfe9         fucomip st0, st1
|    ||    0x08048589    ddd8         fstp st0
|    |`==< 0x0804858b    7ae3         jp loc.08048570
|    |     0x0804858d    d945fc       fld dword [ebp-0x4]
|    |     0x08048590    d9ee         fldz
|    |     0x08048592    dfe9         fucomip st0, st1
|    |     0x08048594    ddd8         fstp st0
|    `===< 0x08048596    75d8         jne loc.08048570
|          0x08048598    660f6e45f8   movd xmm0, dword [ebp-0x8]
|          0x0804859d    660fd645e0   movq [ebp-0x20], xmm0
|          0x080485a2    df6de0       fild qword [ebp-0x20]
|          0x080485a5    d945fc       fld dword [ebp-0x4]
|          0x080485a8    dec1         faddp st1, st0
|          0x080485aa    d95dfc       fstp dword [ebp-0x4]
|          0x080485ad    660f6e4df8   movd xmm1, dword [ebp-0x8]
|          0x080485b2    660fd64de0   movq [ebp-0x20], xmm1
|          0x080485b7    df6de0       fild qword [ebp-0x20]
|          0x080485ba    d945fc       fld dword [ebp-0x4]
|          0x080485bd    def1         fdivrp st1, st0
|          0x080485bf    d95dfc       fstp dword [ebp-0x4]
|          0x080485c2    8b45fc       mov eax, [ebp-0x4]
|          0x080485c5    8945e8       mov [ebp-0x18], eax
|          0x080485c8    d945e8       fld dword [ebp-0x18]
|          0x080485cb    c9           leave
\          0x080485cc    c3           ret

It does floating point operations, but we don't care, since the execution flow is supposed to continue anyway. I'm taking a wild guess and suppose it's pure misleadling junk. Let's rename it, just in case we come across it again:

[0x08048360]> afn junk 0x08048559
fr fcn.08048559 junk@ 0x8048559

Let's just focus on what's next. On line 49 the password length is stored in the .bss section, meaning it's certainly a global variable and might need it later. Same thing on line 52, but with the password, Let's just rename them, so we won't miss them later.

[0x08048460]> f str.pass_len @ 0x804999c
[0x08048460]> f str.pass @ 0x8049998

What's next then? main() seems to be returning, so how is the 'KO' print? Let's try and search for xrefs of printf:

1
2
3
4
5
6
7
8
[0x080485a5]> pdf@sym.imp.printf
|          ; UNKNOWN XREF from 0x080485ed (unk)
|          ; CALL XREF from 0x08048552 (fcn.08048430)
|          ; CALL XREF from 0x08048517 (fcn.08048430)
|          ; CALL XREF from 0x08048494 (fcn.08048430)
|          ; CALL XREF from 0x080485ed (unk)
/ (fcn) sym.imp.printf 6
|          0x08048320    ff257c990408 jmp dword [0x804997c]

There is actually 4 calls to printf(). The function they're in (fcn.08048430) is in the .text section:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
[0x08048430]> iS
[Sections]
[...]
idx=12 vaddr=0x08048360 paddr=0x00000360 sz=882 vsz=882 perm=-r-x name=.text
idx=13 vaddr=0x080486d4 paddr=0x000006d4 sz=20 vsz=20 perm=-r-x name=.fini
[...]
idx=17 vaddr=0x08049870 paddr=0x00000870 sz=4 vsz=4 perm=-rw- name=.init_array
idx=18 vaddr=0x08049874 paddr=0x00000874 sz=8 vsz=8 perm=-rw- name=.fini_array
[...]

30 sections

You've certainly noticed the size of the .fini_array section is 8, meaning it contains two function pointers. You can find more information about elf sections there. This section contains pointers to functions to call after the main() returns or when calling exit(). He certainly used the gcc destructor attribute in order to do that.

Let's find the pointers .fini_array contains:

1
2
[0x08048430]> pxw 8@0x08049874
0x08049874  0x08048410 0x0804845d                      ....]...

The destructor we want to look at is @ 0x0804845d:

[0x08048430]> pdf@0x0804845d
|           0x0804845d    55           push ebp
|           0x0804845e    89e5         mov ebp, esp
|           0x08048460    83ec28       sub esp, 0x28
|           0x08048463    c645f742     mov byte [ebp-0x9], 0x42 ; 0x42 'B'
|           0x08048467    c645f600     mov byte [ebp-0xa], 0x0
|           0x0804846b    a19c990408   mov eax, [str.pass_len]
|           0x08048470    83f819       cmp eax, 0x19
|   ,=====< 0x08048473    7429         je 0x804849e
|   |       0x08048475    b84f000000   mov eax, 0x4f ; 'O'
|   |       0x0804847a    0fbed0       movsx edx, al
|   |       0x0804847d    b84b000000   mov eax, 0x4b ; 'K'
|   |       0x08048482    0fbec0       movsx eax, al
|   |       0x08048485    89542408     mov [esp+0x8], edx
|   |       0x08048489    89442404     mov [esp+0x4], eax
|   |       0x0804848d    c704240b870. mov dword [esp], 0x804870b ;  0x0804870b
|   |       0x08048494    e887feffff   call sym.imp.printf
|   |          sym.imp.printf(unk)
|  ,======< 0x08048499    e9b9000000   jmp 0x8048557 ; (fcn.08048430)
|  ||       ; JMP XREF from 0x08048473 (fcn.08048430)
|  |`-----> 0x0804849e    c645f600     mov byte [ebp-0xa], 0x0
| ,=======< 0x080484a2    eb7e         jmp 0x8048522 ; (fcn.08048430)
|           ; JMP XREF from 0x0804852d (fcn.08048430)
| --------> 0x080484a4    8b1598990408 mov edx, [str.pass]
| ||        0x080484aa    0fb645f6     movzx eax, byte [ebp-0xa]
| ||        0x080484ae    01c2         add edx, eax
| ||        0x080484b0    8b0d98990408 mov ecx, [str.pass]
| ||        0x080484b6    0fb645f6     movzx eax, byte [ebp-0xa]
| ||        0x080484ba    01c8         add eax, ecx
| ||        0x080484bc    0fb608       movzx ecx, byte [eax]
| ||        0x080484bf    0fb645f7     movzx eax, byte [ebp-0x9]
| ||        0x080484c3    31c8         xor eax, ecx
| ||        0x080484c5    8802         mov [edx], al
| ||        0x080484c7    0fb645f7     movzx eax, byte [ebp-0x9]
| ||        0x080484cb    83c042       add eax, 0x42
| ||        0x080484ce    01c0         add eax, eax
| ||        0x080484d0    89c2         mov edx, eax
| ||        0x080484d2    c1e205       shl edx, 0x5
| ||        0x080484d5    01d0         add eax, edx
| ||        0x080484d7    8845f7       mov [ebp-0x9], al
| ||        0x080484da    8b1598990408 mov edx, [str.pass]
| ||        0x080484e0    0fb645f6     movzx eax, byte [ebp-0xa]
| ||        0x080484e4    01d0         add eax, edx
| ||        0x080484e6    0fb610       movzx edx, byte [eax]
| ||        0x080484e9    0fb645f6     movzx eax, byte [ebp-0xa]
| ||        0x080484ed    0fb680f2860. movzx eax, byte [eax+0x80486f2]
| ||        0x080484f4    38c2         cmp dl, al
| ========< 0x080484f6    7426         je 0x804851e
| ||        0x080484f8    b84f000000   mov eax, 0x4f ; 'O'
| ||        0x080484fd    0fbed0       movsx edx, al
| ||        0x08048500    b84b000000   mov eax, 0x4b ; 'K'
| ||        0x08048505    0fbec0       movsx eax, al
| ||        0x08048508    89542408     mov [esp+0x8], edx
| ||        0x0804850c    89442404     mov [esp+0x4], eax
| ||        0x08048510    c704240b870. mov dword [esp], 0x804870b ;  0x0804870b
| ||        0x08048517    e804feffff   call sym.imp.printf
| ||           sym.imp.printf()
| ========< 0x0804851c    eb39         jmp 0x8048557 ; (fcn.08048430)
|           ; JMP XREF from 0x080484f6 (fcn.08048430)
| --------> 0x0804851e    8045f601     add byte [ebp-0xa], 0x1
| |         ; JMP XREF from 0x080484a2 (fcn.08048430)
| `-------> 0x08048522    0fb655f6     movzx edx, byte [ebp-0xa]
|  |        0x08048526    a19c990408   mov eax, [str.pass_len]
|  |        0x0804852b    39c2         cmp edx, eax
| ========< 0x0804852d    0f8271ffffff jb 0x80484a4
|  |        0x08048533    b84b000000   mov eax, 0x4b ; 'K'
|  |        0x08048538    0fbed0       movsx edx, al
|  |        0x0804853b    b84f000000   mov eax, 0x4f ; 'O'
|  |        0x08048540    0fbec0       movsx eax, al
|  |        0x08048543    89542408     mov [esp+0x8], edx
|  |        0x08048547    89442404     mov [esp+0x4], eax
|  |        0x0804854b    c704240b870. mov dword [esp], 0x804870b ;  0x0804870b
|  |        0x08048552    e8c9fdffff   call sym.imp.printf
|  |           sym.imp.printf()
|  |        ; JMP XREF from 0x0804851c (fcn.08048430)
|  |        ; JMP XREF from 0x08048499 (fcn.08048430)
| -`------> 0x08048557    c9           leave
\           0x08048558    c3           ret

As you can imagine only one of those printf() should print what we want. The calling convention used by gcc here tells us that on line 17 should be our printf format string:

1
2
3
4
[0x08048360]> px @ 0x804870b
- offset -   0 1  2 3  4 5  6 7  8 9  A B  C D  E F  0123456789ABCDEF
0x0804870b  2563 2563 0a00 5573 6167 653a 2025 7320  %c%c..Usage: %s
[...]

The format string is '%c%c'. That means we should find two char arguments on the stack. Look at line 10 and 12, there is our 'O' and 'K'. So the printf() we want to reach is on the line 73. Now how to reach it? On line 8 you can see the pass length is compared to 0x19 (25), if it isn't it stops the program. Next is a for loop that seems to iterate over each char of the password, xor it with what looks like a modifying key, and then compare it with the encrypted flag. Here is the same function but with helpful notations:

[0x08048430]> pdf@0x0804845d
|           0x0804845d    55           push ebp
|           0x0804845e    89e5         mov ebp, esp
|           0x08048460    83ec28       sub esp, 0x28
|           0x08048463    c645f742     mov byte [ebp-key], 0x42 ;  0x00000042   ; the initial key
|           0x08048467    c645f600     mov byte [ebp-pass_i], 0x0   ; pass counter
|           0x0804846b    a19c990408   mov eax, [str.pass_len]
|           0x08048470    83f819       cmp eax, 0x19             ; compare the pass length with 0x19
|   ,=====< 0x08048473    7429         je 0x804849e
|   |       0x08048475    b84f000000   mov eax, 0x4f ; 'O'
|   |       0x0804847a    0fbed0       movsx edx, al
|   |       0x0804847d    b84b000000   mov eax, 0x4b ; 'K'
|   |       0x08048482    0fbec0       movsx eax, al
|   |       0x08048485    89542408     mov [esp+0x8], edx
|   |       0x08048489    89442404     mov [esp+0x4], eax
|   |       0x0804848d    c704240b870. mov dword [esp], 0x804870b ;  0x0804870b
|   |       0x08048494    e887feffff   call sym.imp.printf
|   |          sym.imp.printf(unk)                               ; prints KO
|  ,======< 0x08048499    e9b9000000   jmp 0x8048557 ; (fcn.08048430)
|  ||       ; JMP XREF from 0x08048473 (fcn.08048430)
|  |`-----> 0x0804849e    c645f600     mov byte [ebp-pass_i], 0x0   ; pass_i = 0
| ,=======< 0x080484a2    eb7e         jmp 0x8048522 ; (fcn.08048430)
|           ; JMP XREF from 0x0804852d (fcn.08048430)
| --------> 0x080484a4    8b1598990408 mov edx, [str.pass]
| ||        0x080484aa    0fb645f6     movzx eax, byte [ebp-pass_i]
| ||        0x080484ae    01c2         add edx, eax              ; edx = &pass[pass_i]
| ||        0x080484b0    8b0d98990408 mov ecx, [str.pass]
| ||        0x080484b6    0fb645f6     movzx eax, byte [ebp-pass_i]
| ||        0x080484ba    01c8         add eax, ecx
| ||        0x080484bc    0fb608       movzx ecx, byte [eax]     ; ecx = pass[pass_i]
| ||        0x080484bf    0fb645f7     movzx eax, byte [ebp-key]  ; eax = key
| ||        0x080484c3    31c8         xor eax, ecx              ; eax = key ^ pass[pass_i]
| ||        0x080484c5    8802         mov [edx], al             ; pass[pass_i] = key ^ pass[pass_i]
| ||        0x080484c7    0fb645f7     movzx eax, byte [ebp-key]
| ||        0x080484cb    83c042       add eax, 0x42
| ||        0x080484ce    01c0         add eax, eax
| ||        0x080484d0    89c2         mov edx, eax
| ||        0x080484d2    c1e205       shl edx, 0x5
| ||        0x080484d5    01d0         add eax, edx
| ||        0x080484d7    8845f7       mov [ebp-key], al         ; key = (key + 42h)*22 ??
| ||        0x080484da    8b1598990408 mov edx, [str.pass]
| ||        0x080484e0    0fb645f6     movzx eax, byte [ebp-pass_i]
| ||        0x080484e4    01d0         add eax, edx
| ||        0x080484e6    0fb610       movzx edx, byte [eax]     ; edx = pass[pass_i]
| ||        0x080484e9    0fb645f6     movzx eax, byte [ebp-pass_i]
| ||        0x080484ed    0fb680f2860. movzx eax, byte [eax+str.encrypted_flag]  ; eax = encrypted_flag[pass_i]
| ||        0x080484f4    38c2         cmp dl, al
| ========< 0x080484f6    7426         je 0x804851e              ; fail if pass[pass_i] != encrypted_flag[pass_i]
| ||        0x080484f8    b84f000000   mov eax, 0x4f ; 'O'
| ||        0x080484fd    0fbed0       movsx edx, al
|   |       0x0804847d    b84b000000   mov eax, 0x4b ; 'K'
| ||        0x08048505    0fbec0       movsx eax, al
| ||        0x08048508    89542408     mov [esp+0x8], edx
| ||        0x0804850c    89442404     mov [esp+0x4], eax
| ||        0x08048510    c704240b870. mov dword [esp], 0x804870b ;  0x0804870b
| ||        0x08048517    e804feffff   call sym.imp.printf
| ||           sym.imp.printf()                                  ; prints KO
| ========< 0x0804851c    eb39         jmp 0x8048557 ; (fcn.08048430)
|           ; JMP XREF from 0x080484f6 (fcn.08048430)
| --------> 0x0804851e    8045f601     add byte [ebp-pass_i], 0x1
| |         ; JMP XREF from 0x080484a2 (fcn.08048430)
| `-------> 0x08048522    0fb655f6     movzx edx, byte [ebp-pass_i]
|  |        0x08048526    a19c990408   mov eax, [str.pass_len]
|  |        0x0804852b    39c2         cmp edx, eax
| ========< 0x0804852d    0f8271ffffff jb 0x80484a4              ; if pass_i < 25 loop again
|  |        0x08048533    b84b000000   mov eax, 0x4b ; 'K'
|  |        0x08048538    0fbed0       movsx edx, al
|  |        0x0804853b    b84f000000   mov eax, 0x4f ; 'O'
|  |        0x08048540    0fbec0       movsx eax, al
|  |        0x08048543    89542408     mov [esp+0x8], edx
|  |        0x08048547    89442404     mov [esp+0x4], eax
|  |        0x0804854b    c704240b870. mov dword [esp], 0x804870b ;  0x0804870b
|  |        0x08048552    e8c9fdffff   call sym.imp.printf
|  |           sym.imp.printf()                                  ; prints OK
|  |        ; JMP XREF from 0x0804851c (fcn.08048430)
|  |        ; JMP XREF from 0x08048499 (fcn.08048430)
| -`------> 0x08048557    c9           leave
\           0x08048558    c3           ret

With these informations in hand, we just need to extract the encrypted flag, and we should be able to decrypt it, thanks to the initial key value 0x42 (line 5), and its generation algorithm. Let's extract the encrypted flag:

1
2
3
4
5
6
[0x08048439]> pc 25 @ str.encrypted_flag
#define _BUFFER_SIZE 25
unsigned char buffer[25] = {
  0x11, 0x4d, 0x57, 0x79, 0x0e, 0xe8, 0x07, 0xa5, 0xcc, 0x89, 0xb8,
  0xcf, 0x8f, 0x88, 0x8e, 0xcc, 0x85, 0xcf, 0x98, 0xb1, 0xcf, 0xc6,
  0xdb, 0xd4, 0x81, };

Notice i first thought key = (key + 42h) * 22 would be the key algorithm, but turns out I couldn't make it work, so I used a safer method with fake registers. Let's just decrypt it and we should get the flag :)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
int main(){
    int i, eax, edx;
    unsigned char flag[26];
    unsigned char key = 0x42;

    unsigned char encrypted_flag[25] = {
        0x11, 0x4d, 0x57, 0x79, 0x0e, 0xe8, 0x07, 0xa5, 0xcc, 0x89, 0xb8, 0xcf,
        0x8f, 0x88, 0x8e, 0xcc, 0x85, 0xcf, 0x98, 0xb1, 0xcf, 0xc6, 0xdb,
          0xd4, 0x81, };

    for(i=0 ; i<25 ; i++) {
        flag[i] = encrypted_flag[i] ^ key;

        eax = key;
        eax += 0x42;
        eax += eax;
        edx = eax;
        edx = (unsigned int) edx << 5;
        eax += edx;
        eax = eax & 0xFF;
        key = eax;

        /*key = (unsigned char) (key + 0x42) * 22;*/
    }

    flag[25] = '\0';

    printf("flag: %s\n", flag);
}

Overall it was really nice challenge with some nice tricks. I think he also enjoyed maniacally laughing behind his screen while I was having trouble with the tricks I had to find in his binary. But be sure I'll get my revenge :)

Jul 05, 2014

How to encrypt an external disk with dm-crypt, LUKS and LVM

First of all if you are like i was, confused about dm-crypt/LUKS/cryptsetup you need to look at the man of cryptsetup. It does a very good job at what exactly LUKS is. Basically, dm-crypt is a kernel module that deals with the encryption at the disk sector level. This allows to encrypt any kind of filesystem. LUKS on the other hand is an extension to the bare dm-crypt, it adds features such as:

  • Use of PBKDF2 for key stretching
  • Multiple passphrases

Finally cryptsetup is a frontend to both dm-crypt and LUKS, it is a tool to setup encrypted partitions with their various settings, with or without LUKS.

First you’ll want to luksFormat the target partition:

cryptsetup --verbose luksFormat /dev/sd?? -h sha512

Why -h sha512? With cryptsetup --help you can see the defaults used by cryptsetup on your system. On mine it used sha1 to hash the LUKS header.

If you issue the following command you’ll be able to see the luks header:

cryptsetup luksDump /dev/sd??

Now let’s open the encrypted partition:

cryptsetup luksOpen /dev/sd?? some_name

The decrypted partition will be /dev/mapper/some_name. Now let’s prepare the LVM volume. LVM has no runtime cost and usually makes your life easier managing partitions.

pvcreate /dev/mapper/some_name
vgcreate vg_name /dev/mapper/some_name
lvcreate -n lv_name vg_name -l100%VG

These commands will in order, prepare the partition for LVM, create a volume group, create a logical volume in the just created volume. We only need to format the logical volume now:

mkfs.ext4 -L a_name -m 0 /dev/vg_name/lv_name

I used -m 0 because this is an external drive and I don’t care about root reserved blocks. Remember also to backup your LUKS header (to a secure location and outside your encrypted partition obviously) because all your data will be lost if this header is destroyed:

cryptsetup luksHeaderBackup /dev/sd?? --header-backup-file backup_file
Next → Page 1 of 2