Skip to content

CodeBits CTF f200 – Extracting RSA keys

In this post I will describe the process of reverse engineering a Linux 64 bit ELF binary to extract an encryption key. This challenge was presented at CodeBits CTF. The binary is available here

Prior to resolve the challenge, the following tip was shown:

"Some competitor uses encrypted email to exchange messages and we were able to recover the attached file."

Objective: get the private key!

OK, so the private key must be recovered in order to decrypt some emails. Let’s go!

This binary challenge is based on a x86-64 ELF file which prompts for a flag:

:~/CodeBits $ ./f200
Press RETURN to exit.
:~/CodeBits $ file ./f200
./f200: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.26, BuildID[sha1]=6f6b6b763c9c7f905388f04a9941ab4622577fb1, not stripped

Cool, let’s fire up GDB+PEDA to disassemble the binary. Initially the main() function will be examined in order to discover the high-level functions that are related to encryption (OpenSSL):

:~/CodeBits $ gdb -q ./f200
Reading symbols from ./f200...(no debugging symbols found)...done.
gdb-peda$ 
gdb-peda$ pdisass main
Dump of assembler code for function main:
0x0000000000401ecc <+0>:    push   rbp
0x0000000000401ecd <+1>:    mov    rbp,rsp
0x0000000000401ed0 <+4>:    sub    rsp,0x20
0x0000000000401ed4 <+8>:    mov    DWORD PTR [rbp-0x14],edi
0x0000000000401ed7 <+11>:    mov    QWORD PTR [rbp-0x20],rsi
0x0000000000401edb <+15>:    mov    eax,0x0
0x0000000000401ee0 <+20>:    call   0x401f1e new_DER_RSAKey
0x0000000000401ee5 <+25>:    mov    QWORD PTR [rbp-0x8],rax
0x0000000000401ee9 <+29>:    mov    edi,0x4a2344
0x0000000000401eee <+34>:    call   0x401980 puts@plt
0x0000000000401ef3 <+39>:    mov    rdx,QWORD PTR [rip+0x2f25a6]
0x0000000000401efa <+46>:    lea    rax,[rbp-0x10]
0x0000000000401efe <+50>:    mov    esi,0x2
0x0000000000401f03 <+55>:    mov    rdi,rax
0x0000000000401f06 <+58>:    call   0x401b10 fgets@plt
0x0000000000401f0b <+63>:    mov    rax,QWORD PTR [rbp-0x8]
0x0000000000401f0f <+67>:    mov    rdi,rax
0x0000000000401f12 <+70>:    call   0x402910 EVP_PKEY_free
0x0000000000401f17 <+75>:    mov    eax,0x0
0x0000000000401f1c <+80>:    leave  
0x0000000000401f1d <+81>:    ret    
End of assembler dump.

So far, so good. It can be seen cleary that the following function call must be followed:

0x0000000000401ee0 <+20>:	call   0x401f1e 

So let’s discover the contents of the function new_DER_RSAKey

gdb-peda$ pdisass new_DER_RSAKey
Dump of assembler code for function new_DER_RSAKey:
   0x0000000000401f1e <+0>:	push   rbp
   0x0000000000401f1f <+1>:	mov    rbp,rsp
   0x0000000000401f22 <+4>:	push   rbx
   0x0000000000401f23 <+5>:	sub    rsp,0x28
   0x0000000000401f27 <+9>:	mov    DWORD PTR [rbp-0x14],0x0
   0x0000000000401f2e <+16>:	mov    DWORD PTR [rbp-0x14],0x0
   0x0000000000401f35 <+23>:	jmp    0x402039 
   0x0000000000401f3a <+28>:	cmp    DWORD PTR [rbp-0x14],0x0
   0x0000000000401f3e <+32>:	jne    0x401f61 
   0x0000000000401f40 <+34>:	movzx  eax,BYTE PTR [rip+0x2f0599] # 0x6f24e0 
   0x0000000000401f47 <+41>:	mov    BYTE PTR [rbp-0x15],al
   0x0000000000401f4a <+44>:	movzx  eax,BYTE PTR [rip+0x2f07f0] # 0x6f2741 
   0x0000000000401f51 <+51>:	mov    BYTE PTR [rip+0x2f0589],al  # 0x6f24e0 
   0x0000000000401f57 <+57>:	movzx  eax,BYTE PTR [rbp-0x15]
   0x0000000000401f5b <+61>:	mov    BYTE PTR [rip+0x2f07e0],al  # 0x6f2741 
   0x0000000000401f61 <+67>:	mov    eax,DWORD PTR [rbp-0x14]
   0x0000000000401f64 <+70>:	lea    ecx,[rax+0x5]
   0x0000000000401f67 <+73>:	mov    edx,0xb21642c9
   0x0000000000401f6c <+78>:	mov    eax,ecx
   0x0000000000401f6e <+80>:	imul   edx
   0x0000000000401f70 <+82>:	lea    eax,[rdx+rcx*1]
   0x0000000000401f73 <+85>:	mov    edx,eax
   0x0000000000401f75 <+87>:	sar    edx,0x4
   0x0000000000401f78 <+90>:	mov    eax,ecx
   0x0000000000401f7a <+92>:	sar    eax,0x1f
   0x0000000000401f7d <+95>:	mov    ebx,edx
   0x0000000000401f7f <+97>:	sub    ebx,eax
   0x0000000000401f81 <+99>:	mov    eax,ebx
   0x0000000000401f83 <+101>:	imul   eax,eax,0x17
   0x0000000000401f86 <+104>:	mov    edx,ecx
   0x0000000000401f88 <+106>:	sub    edx,eax
   0x0000000000401f8a <+108>:	mov    eax,edx
   0x0000000000401f8c <+110>:	test   eax,eax
   0x0000000000401f8e <+112>:	jne    0x401fcc 
   0x0000000000401f90 <+114>:	mov    eax,DWORD PTR [rbp-0x14]
   0x0000000000401f93 <+117>:	add    eax,0x4
   0x0000000000401f96 <+120>:	cdqe   
   0x0000000000401f98 <+122>:	movzx  eax,BYTE PTR [rax+0x6f24e0]
   0x0000000000401f9f <+129>:	mov    BYTE PTR [rbp-0x15],al
   0x0000000000401fa2 <+132>:	mov    eax,DWORD PTR [rbp-0x14]
   0x0000000000401fa5 <+135>:	lea    ecx,[rax+0x4]
   0x0000000000401fa8 <+138>:	mov    eax,DWORD PTR [rbp-0x14]
   0x0000000000401fab <+141>:	cdqe   
   0x0000000000401fad <+143>:	movzx  edx,BYTE PTR [rax+0x6f24e0]
   0x0000000000401fb4 <+150>:	movsxd rax,ecx
   0x0000000000401fb7 <+153>:	mov    BYTE PTR [rax+0x6f24e0],dl
   0x0000000000401fbd <+159>:	mov    eax,DWORD PTR [rbp-0x14]
   0x0000000000401fc0 <+162>:	cdqe   
   0x0000000000401fc2 <+164>:	movzx  edx,BYTE PTR [rbp-0x15]
   0x0000000000401fc6 <+168>:	mov    BYTE PTR [rax+0x6f24e0],dl
   0x0000000000401fcc <+174>:	mov    eax,DWORD PTR [rbp-0x14]
   0x0000000000401fcf <+177>:	lea    ecx,[rax+0x1]
   0x0000000000401fd2 <+180>:	mov    edx,0x78787879
   0x0000000000401fd7 <+185>:	mov    eax,ecx
   0x0000000000401fd9 <+187>:	imul   edx
   0x0000000000401fdb <+189>:	sar    edx,0x3
   0x0000000000401fde <+192>:	mov    eax,ecx
   0x0000000000401fe0 <+194>:	sar    eax,0x1f
   0x0000000000401fe3 <+197>:	sub    edx,eax
   0x0000000000401fe5 <+199>:	mov    eax,edx
   0x0000000000401fe7 <+201>:	shl    eax,0x4
   0x0000000000401fea <+204>:	add    eax,edx
   0x0000000000401fec <+206>:	mov    edx,ecx
   0x0000000000401fee <+208>:	sub    edx,eax
   0x0000000000401ff0 <+210>:	test   edx,edx
   0x0000000000401ff2 <+212>:	jne    0x402010 
   0x0000000000401ff4 <+214>:	mov    eax,DWORD PTR [rbp-0x14]
   0x0000000000401ff7 <+217>:	cdqe   
   0x0000000000401ff9 <+219>:	movzx  eax,BYTE PTR [rax+0x6f24e0]
   0x0000000000402000 <+226>:	mov    edx,eax
   0x0000000000402002 <+228>:	xor    edx,0x77
   0x0000000000402005 <+231>:	mov    eax,DWORD PTR [rbp-0x14]
   0x0000000000402008 <+234>:	cdqe   
   0x000000000040200a <+236>:	mov    BYTE PTR [rax+0x6f24e0],dl
   0x0000000000402010 <+242>:	mov    eax,DWORD PTR [rbp-0x14]
   0x0000000000402013 <+245>:	cdqe   
   0x0000000000402015 <+247>:	movzx  edx,BYTE PTR [rax+0x6f2760]
   0x000000000040201c <+254>:	mov    eax,DWORD PTR [rbp-0x14]
   0x000000000040201f <+257>:	cdqe   
   0x0000000000402021 <+259>:	movzx  eax,BYTE PTR [rax+0x6f24e0]
   0x0000000000402028 <+266>:	xor    edx,eax
   0x000000000040202a <+268>:	mov    eax,DWORD PTR [rbp-0x14]
   0x000000000040202d <+271>:	cdqe   
   0x000000000040202f <+273>:	mov    BYTE PTR [rax+0x6f44c0],dl
   0x0000000000402035 <+279>:	add    DWORD PTR [rbp-0x14],0x1
   0x0000000000402039 <+283>:	cmp    DWORD PTR [rbp-0x14],0x261
   0x0000000000402040 <+290>:	jle    0x401f3a 
0x0000000000402046 <+296>:	call   0x402570 EVP_PKEY_new
   0x000000000040204b <+301>:	mov    QWORD PTR [rbp-0x20],rax
   0x000000000040204f <+305>:	mov    QWORD PTR [rbp-0x30],0x6f44c0
   0x0000000000402057 <+313>:	lea    rax,[rbp-0x30]
   0x000000000040205b <+317>:	mov    edx,0x262
   0x0000000000402060 <+322>:	mov    rsi,rax
   0x0000000000402063 <+325>:	mov    edi,0x0
0x0000000000402068 <+330>:	call   0x402130 d2i_RSAPrivateKey
   0x000000000040206d <+335>:	mov    QWORD PTR [rbp-0x28],rax
   0x0000000000402071 <+339>:	mov    rdx,QWORD PTR [rbp-0x28]
   0x0000000000402075 <+343>:	mov    rax,QWORD PTR [rbp-0x20]
   0x0000000000402079 <+347>:	mov    esi,0x6
   0x000000000040207e <+352>:	mov    rdi,rax
0x0000000000402081 <+355>:	call   0x402620 EVP_PKEY_assign
   0x0000000000402086 <+360>:	mov    rax,QWORD PTR [rbp-0x20]
   0x000000000040208a <+364>:	add    rsp,0x28
   0x000000000040208e <+368>:	pop    rbx
   0x000000000040208f <+369>:	pop    rbp
   0x0000000000402090 <+370>:	ret    
End of assembler dump.

Let’s set a breakpoint at 0x0000000000402068 and run the program. In the address 0x0000000000402068 is located the function we will examine in the next step: d2i_RSAPrivateKey.

gdb-peda$ break *0x0000000000402068
Breakpoint 1 at 0x402068
gdb-peda$ 

To digger about this function the Linux manual pages can be examined:

d2i_RSAPublicKey(3)                         OpenSSL                         d2i_RSAPublicKey(3)



NAME
       d2i_RSAPublicKey, i2d_RSAPublicKey, d2i_RSAPrivateKey, i2d_RSAPrivateKey,
       d2i_RSA_PUBKEY, i2d_RSA_PUBKEY, i2d_Netscape_RSA, d2i_Netscape_RSA - RSA public and
       private key encoding functions.

SYNOPSIS
        #include 
        #include 

        RSA * d2i_RSAPublicKey(RSA **a, const unsigned char **pp, long length);

        int i2d_RSAPublicKey(RSA *a, unsigned char **pp);

        RSA * d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length);

        int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp);

        RSA * d2i_RSAPrivateKey(RSA **a, const unsigned char **pp, long length);

        int i2d_RSAPrivateKey(RSA *a, unsigned char **pp);

        int i2d_Netscape_RSA(RSA *a, unsigned char **pp, int (*cb)());

        RSA * d2i_Netscape_RSA(RSA **a, const unsigned char **pp, long length, int (*cb)());

DESCRIPTION
       d2i_RSAPublicKey() and i2d_RSAPublicKey() decode and encode a PKCS#1 RSAPublicKey
       structure.

       d2i_RSA_PUBKEY() and i2d_RSA_PUBKEY() decode and encode an RSA public key using a
       SubjectPublicKeyInfo (certificate public key) structure.

       d2i_RSAPrivateKey(), i2d_RSAPrivateKey() decode and encode a PKCS#1 RSAPrivateKey
       structure.

       d2i_Netscape_RSA(), i2d_Netscape_RSA() decode and encode an RSA private key in NET
       format.

       The usage of all of these functions is similar to the d2i_X509() and i2d_X509()
       described in the d2i_X509(3) manual page.

So far so good, let’s run GDB again:

gdb-peda$ run
Starting program: /home/user/CodeBits/f200 
warning: Could not load shared library symbols for linux-vdso.so.1.
Do you need "set solib-search-path" or "set sysroot"?
[----------------------------------registers-----------------------------------]
RAX: 0x7fffffffe180 --> 0x6f44c0 --> 0x20001025e028230 
RBX: 0x1a 
RCX: 0x7ffff79bc620 --> 0x100000000 
RDX: 0x262 
RSI: 0x7fffffffe180 --> 0x6f44c0 --> 0x20001025e028230 
RDI: 0x0 
RBP: 0x7fffffffe1b0 --> 0x7fffffffe1e0 --> 0x0 
RSP: 0x7fffffffe180 --> 0x6f44c0 --> 0x20001025e028230 
RIP: 0x402068 (:	call   0x402130 )
R8 : 0x0 
R9 : 0x0 
R10: 0x21000 
R11: 0x206 
R12: 0x401dc0 (<_start>:	xor    ebp,ebp)
R13: 0x7fffffffe2c0 --> 0x1 
R14: 0x0 
R15: 0x0
EFLAGS: 0x206 (carry PARITY adjust zero sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x40205b :	mov    edx,0x262
   0x402060 :	mov    rsi,rax
   0x402063 :	mov    edi,0x0
=> 0x402068 :	call   0x402130     
   0x40206d :	mov    QWORD PTR [rbp-0x28],rax
   0x402071 :	mov    rdx,QWORD PTR [rbp-0x28]
   0x402075 :	mov    rax,QWORD PTR [rbp-0x20]
   0x402079 :	mov    esi,0x6
Guessed arguments:
arg[0]: 0x0 
arg[1]: 0x7fffffffe180 --> 0x6f44c0 --> 0x20001025e028230 
arg[2]: 0x262 
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffe180 --> 0x6f44c0 --> 0x20001025e028230 
0008| 0x7fffffffe188 --> 0x0 
0016| 0x7fffffffe190 --> 0x6f8010 --> 0x0 
0024| 0x7fffffffe198 --> 0x262fa40189e 
0032| 0x7fffffffe1a0 --> 0x1 
0040| 0x7fffffffe1a8 --> 0x0 
0048| 0x7fffffffe1b0 --> 0x7fffffffe1e0 --> 0x0 
0056| 0x7fffffffe1b8 --> 0x401ee5 (:	mov    QWORD PTR [rbp-0x8],rax)
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value

Breakpoint 1, 0x0000000000402068 in new_DER_RSAKey ()
gdb-peda$ 

So, the function call to d2i_RSAPrivateKey which returns the pointer to the RSA structure is as follows:

RSA * ptr = d2i_RSAPrivateKey(NULL, *0x7fffffffe190, 0x262)

If we take a look at the value of the register rsi, it shoud contain a pointer. This pointer will point to the location of the RSA key. Let’s see:

gdb-peda$ # RSA * ptr = d2i_RSAPrivateKey(NULL, *0x7fffffffe190, 0x262)
gdb-peda$ 
gdb-peda$ x/x $rsi
0x7fffffffe180:	0x00000000006f44c0
gdb-peda$ 
gdb-peda$ # *0x7fffffffe190 = 0x00000000006f44c0
gdb-peda$ 
gdb-peda$ # RSA * ptr = d2i_RSAPrivateKey(NULL, 0x00000000006f44c0, 0x262)
gdb-peda$ 

So the key should be located at 0x00000000006f44c0 and should have 610 bytes long. Let’s try:

gdb-peda$ x/610bx 0x00000000006f44c0
0x6f44c0 :      0x30    0x82    0x02    0x5e    0x02    0x01    0x00    0x02
0x6f44c8 :    0x81    0x81    0x00    0xc4    0x5e    0x27    0xd9    0x66
0x6f44d0 :   0x8e    0x0f    0x25    0x66    0xa9    0x45    0xd6    0xdf
0x6f44d8 :   0x29    0xca    0x5d    0x84    0x19    0x92    0xaa    0x87
0x6f44e0 :   0x98    0xbc    0xd0    0x88    0x52    0xd6    0x61    0xb0
0x6f44e8 :   0x3b    0x9a    0xc8    0x49    0x36    0x49    0x7c    0x68
0x6f44f0 :   0xbc    0x48    0x22    0x18    0x1d    0xcd    0x5f    0x62
0x6f44f8 :   0x41    0xac    0xec    0xcb    0x47    0xa7    0xfa    0x75
0x6f4500 :   0xb3    0xcf    0xf2    0xda    0xe3    0xa1    0x77    0xa5
0x6f4508 :   0x03    0x98    0xe8    0x93    0xa5    0xc7    0x18    0x63
0x6f4510 :   0xca    0xcf    0xe5    0x3d    0x33    0xba    0x4e    0x68
0x6f4518 :   0x75    0x41    0x09    0x63    0x78    0x9a    0x37    0x58
0x6f4520 :   0x52    0x54    0xf8    0x39    0x19    0x16    0xf5    0xb9
0x6f4528 :  0xa6    0xa5    0xdb    0xc0    0x2e    0xdf    0x06    0x8d
0x6f4530 :  0xc2    0xd9    0x32    0x23    0x43    0xef    0x96    0xca
0x6f4538 :  0x1c    0x42    0x46    0x4a    0x4c    0xc5    0x26    0x5c
0x6f4540 :  0xc8    0xaa    0x21    0x0b    0x01    0x94    0x60    0x92
0x6f4548 :  0x43    0xba    0x51    0x02    0x03    0x01    0x00    0x01
0x6f4550 :  0x02    0x81    0x80    0x51    0x75    0xc9    0xcc    0x2a
0x6f4558 :  0xfa    0x15    0x98    0x6b    0x5d    0x1f    0x46    0xc2
0x6f4560 :  0xef    0x00    0x2f    0x09    0x24    0xde    0xad    0xf5
0x6f4568 :  0x70    0x4c    0x2b    0xa9    0xd1    0xcb    0x73    0x5c
0x6f4570 :  0xfb    0x6c    0xfb    0x57    0x3b    0xb9    0x02    0x6e
0x6f4578 :  0x24    0x65    0x3c    0x17    0x8b    0x0d    0x6e    0x5b
0x6f4580 :  0x41    0x69    0x6e    0x15    0xea    0x14    0xea    0x16
0x6f4588 :  0xb7    0xd0    0x35    0x2b    0xce    0xb0    0x66    0x04
0x6f4590 :  0xc3    0x58    0x43    0xb0    0x5c    0x83    0xc2    0x5f
0x6f4598 :  0xde    0xd6    0x37    0xbb    0xa1    0xfc    0xed    0x96
0x6f45a0 :  0x38    0xd4    0xc1    0xb0    0xa6    0xb1    0xf9    0x55
0x6f45a8 :  0x60    0x75    0x1f    0xa2    0x15    0x29    0x67    0x6d
0x6f45b0 :  0x88    0x7a    0x1e    0x45    0xea    0x5e    0x36    0xef
0x6f45b8 :  0x26    0x7b    0x86    0xf8    0xcb    0x6e    0x0a    0xf7
0x6f45c0 :  0x36    0x83    0x1d    0x66    0x27    0x22    0x53    0xed
0x6f45c8 :  0x30    0x91    0x5b    0x6d    0xd2    0xc6    0x96    0x2f
0x6f45d0 :  0xc0    0xc8    0xd1    0x02    0x41    0x00    0xf6    0x46
0x6f45d8 :  0xf3    0x0f    0xa7    0xce    0x79    0x25    0x95    0x3a
0x6f45e0 :  0x16    0x37    0x6a    0x63    0x62    0x3b    0x73    0x17
0x6f45e8 :  0xe5    0xca    0xf9    0x9f    0xb4    0x57    0x3c    0x8e
0x6f45f0 :  0x95    0x3b    0x17    0x8c    0xe9    0x36    0x21    0x58
0x6f45f8 :  0x23    0xbc    0x5c    0x08    0x00    0xf0    0x62    0x41
0x6f4600 :  0x1c    0x21    0x12    0xd9    0x72    0xd1    0x6c    0x18
0x6f4608 :  0xc1    0xf6    0x56    0xda    0xa2    0xba    0xc9    0x1a
0x6f4610 :  0xa1    0xae    0x1d    0x6f    0x93    0x55    0x02    0x41
0x6f4618 :  0x00    0xcc    0x1e    0xc9    0x7f    0x94    0x9a    0xd9
0x6f4620 :  0xf7    0xe6    0xa2    0x34    0xa6    0xfe    0x76    0x1b
0x6f4628 :  0x4e    0xf7    0x5a    0x01    0x01    0x6a    0xaa    0xf5
0x6f4630 :  0x39    0x46    0x17    0xea    0x67    0x73    0x54    0xb2
0x6f4638 :  0x07    0x1b    0x53    0x40    0x45    0xdb    0xfd    0xa7
0x6f4640 :  0xfc    0x1b    0xb4    0x68    0xac    0xf7    0xd5    0x4e
0x6f4648 :  0x38    0x17    0xc7    0x53    0x4c    0xf4    0x58    0x50
0x6f4650 :  0x86    0xb4    0x45    0x29    0xcf    0x93    0xe2    0x43
0x6f4658 :  0x0d    0x02    0x41    0x00    0xea    0x49    0x30    0xad
0x6f4660 :  0xb2    0x0b    0xc0    0x40    0x3a    0xa8    0x59    0xbe
0x6f4668 :  0x3a    0x1d    0x75    0xb3    0xec    0x97    0xcd    0x69
0x6f4670 :  0xbc    0xf3    0x6b    0x52    0x9a    0x2f    0x62    0x54
0x6f4678 :  0x26    0xe1    0x4c    0x72    0xcc    0x61    0xd7    0x0d
0x6f4680 :  0x37    0xd7    0xfd    0x5c    0xb1    0x7c    0x13    0x50
0x6f4688 :  0x7b    0x68    0x15    0xcc    0x98    0xb3    0x2c    0xc2
0x6f4690 :  0x36    0x7a    0x23    0xd8    0xe1    0xbb    0xce    0x17
0x6f4698 :  0x9f    0xb5    0x27    0x49    0x02    0x41    0x00    0xaf
0x6f46a0 :  0x8d    0xa7    0x05    0x68    0x1c    0xca    0x6c    0x90
0x6f46a8 :  0x5a    0x5f    0x68    0x64    0x9f    0xd5    0x9a    0xd3
0x6f46b0 :  0xd7    0xff    0xd7    0x65    0x13    0x45    0xb7    0x0d
0x6f46b8 :  0x96    0xd2    0x0e    0x49    0x3d    0xc5    0xa3    0xa1
0x6f46c0 :  0x17    0xb7    0xc6    0x9d    0x8f    0x0a    0x64    0x24
0x6f46c8 :  0xbb    0xc3    0xef    0x47    0x73    0x98    0x43    0x5c
0x6f46d0 :  0x08    0x1d    0x97    0xa8    0xeb    0x2f    0xce    0xba
0x6f46d8 :  0xca    0x65    0x4c    0x57    0x47    0x19    0x1d    0x02
0x6f46e0 :  0x41    0x00    0xb6    0xc8    0x04    0x0f    0x66    0x19
0x6f46e8 :  0x9c    0x70    0x01    0xbc    0x91    0x9d    0xd0    0xb7
0x6f46f0 :  0xa1    0x4c    0xf1    0x2a    0xb8    0xd6    0x06    0x44
0x6f46f8 :  0x19    0x3c    0x45    0x6a    0x64    0x87    0x8f    0x3c
0x6f4700 :  0xdf    0xa3    0x9f    0xb2    0x44    0x5a    0x12    0xf7
0x6f4708 :  0x81    0x2d    0x70    0x8c    0x72    0xb1    0xf2    0x55
0x6f4710 :  0x4f    0xfa    0x3b    0xb8    0xe1    0x1c    0xfc    0xd0
0x6f4718 :  0xe9    0xc5    0x9c    0xe8    0xd8    0xd6    0x9a    0xe9
0x6f4720 :  0x07    0xd3
gdb-peda$ 

Bingo! Let’s dump the memory contents using the command dumpmem:

gdb-peda$ dumpmem rsa.der 0x00000000006f44c0 0x00000000006f44c0+0x262
Dumped 610 bytes to 'rsa.der'

Below you can find the PoC to resolve the challengue. If you prefer a the standalone source version, you can find it here

/*
 * borja@libcrack.so
 * sรกb may 10 03:58:59 CEST 2014
 *
 * Codebits f200 
 *   gcc -o dumpkey dumpkey.c -lcrypto
 *
 */

#include 

const char key[] = {
        0x30,0x82,0x02,0x5e,0x02,0x01,0x00,0x02,
        0x81,0x81,0x00,0xc4,0x5e,0x27,0xd9,0x66,
        0x8e,0x0f,0x25,0x66,0xa9,0x45,0xd6,0xdf,
        0x29,0xca,0x5d,0x84,0x19,0x92,0xaa,0x87,
        0x98,0xbc,0xd0,0x88,0x52,0xd6,0x61,0xb0,
        0x3b,0x9a,0xc8,0x49,0x36,0x49,0x7c,0x68,
        0xbc,0x48,0x22,0x18,0x1d,0xcd,0x5f,0x62,
        0x41,0xac,0xec,0xcb,0x47,0xa7,0xfa,0x75,
        0xb3,0xcf,0xf2,0xda,0xe3,0xa1,0x77,0xa5,
        0x03,0x98,0xe8,0x93,0xa5,0xc7,0x18,0x63,
        0xca,0xcf,0xe5,0x3d,0x33,0xba,0x4e,0x68,
        0x75,0x41,0x09,0x63,0x78,0x9a,0x37,0x58,
        0x52,0x54,0xf8,0x39,0x19,0x16,0xf5,0xb9,
        0xa6,0xa5,0xdb,0xc0,0x2e,0xdf,0x06,0x8d,
        0xc2,0xd9,0x32,0x23,0x43,0xef,0x96,0xca,
        0x1c,0x42,0x46,0x4a,0x4c,0xc5,0x26,0x5c,
        0xc8,0xaa,0x21,0x0b,0x01,0x94,0x60,0x92,
        0x43,0xba,0x51,0x02,0x03,0x01,0x00,0x01,
        0x02,0x81,0x80,0x51,0x75,0xc9,0xcc,0x2a,
        0xfa,0x15,0x98,0x6b,0x5d,0x1f,0x46,0xc2,
        0xef,0x00,0x2f,0x09,0x24,0xde,0xad,0xf5,
        0x70,0x4c,0x2b,0xa9,0xd1,0xcb,0x73,0x5c,
        0xfb,0x6c,0xfb,0x57,0x3b,0xb9,0x02,0x6e,
        0x24,0x65,0x3c,0x17,0x8b,0x0d,0x6e,0x5b,
        0x41,0x69,0x6e,0x15,0xea,0x14,0xea,0x16,
        0xb7,0xd0,0x35,0x2b,0xce,0xb0,0x66,0x04,
        0xc3,0x58,0x43,0xb0,0x5c,0x83,0xc2,0x5f,
        0xde,0xd6,0x37,0xbb,0xa1,0xfc,0xed,0x96,
        0x38,0xd4,0xc1,0xb0,0xa6,0xb1,0xf9,0x55,
        0x60,0x75,0x1f,0xa2,0x15,0x29,0x67,0x6d,
        0x88,0x7a,0x1e,0x45,0xea,0x5e,0x36,0xef,
        0x26,0x7b,0x86,0xf8,0xcb,0x6e,0x0a,0xf7,
        0x36,0x83,0x1d,0x66,0x27,0x22,0x53,0xed,
        0x30,0x91,0x5b,0x6d,0xd2,0xc6,0x96,0x2f,
        0xc0,0xc8,0xd1,0x02,0x41,0x00,0xf6,0x46,
        0xf3,0x0f,0xa7,0xce,0x79,0x25,0x95,0x3a,
        0x16,0x37,0x6a,0x63,0x62,0x3b,0x73,0x17,
        0xe5,0xca,0xf9,0x9f,0xb4,0x57,0x3c,0x8e,
        0x95,0x3b,0x17,0x8c,0xe9,0x36,0x21,0x58,
        0x23,0xbc,0x5c,0x08,0x00,0xf0,0x62,0x41,
        0x1c,0x21,0x12,0xd9,0x72,0xd1,0x6c,0x18,
        0xc1,0xf6,0x56,0xda,0xa2,0xba,0xc9,0x1a,
        0xa1,0xae,0x1d,0x6f,0x93,0x55,0x02,0x41,
        0x00,0xcc,0x1e,0xc9,0x7f,0x94,0x9a,0xd9,
        0xf7,0xe6,0xa2,0x34,0xa6,0xfe,0x76,0x1b,
        0x4e,0xf7,0x5a,0x01,0x01,0x6a,0xaa,0xf5,
        0x39,0x46,0x17,0xea,0x67,0x73,0x54,0xb2,
        0x07,0x1b,0x53,0x40,0x45,0xdb,0xfd,0xa7,
        0xfc,0x1b,0xb4,0x68,0xac,0xf7,0xd5,0x4e,
        0x38,0x17,0xc7,0x53,0x4c,0xf4,0x58,0x50,
        0x86,0xb4,0x45,0x29,0xcf,0x93,0xe2,0x43,
        0x0d,0x02,0x41,0x00,0xea,0x49,0x30,0xad,
        0xb2,0x0b,0xc0,0x40,0x3a,0xa8,0x59,0xbe,
        0x3a,0x1d,0x75,0xb3,0xec,0x97,0xcd,0x69,
        0xbc,0xf3,0x6b,0x52,0x9a,0x2f,0x62,0x54,
        0x26,0xe1,0x4c,0x72,0xcc,0x61,0xd7,0x0d,
        0x37,0xd7,0xfd,0x5c,0xb1,0x7c,0x13,0x50,
        0x7b,0x68,0x15,0xcc,0x98,0xb3,0x2c,0xc2,
        0x36,0x7a,0x23,0xd8,0xe1,0xbb,0xce,0x17,
        0x9f,0xb5,0x27,0x49,0x02,0x41,0x00,0xaf,
        0x8d,0xa7,0x05,0x68,0x1c,0xca,0x6c,0x90,
        0x5a,0x5f,0x68,0x64,0x9f,0xd5,0x9a,0xd3,
        0xd7,0xff,0xd7,0x65,0x13,0x45,0xb7,0x0d,
        0x96,0xd2,0x0e,0x49,0x3d,0xc5,0xa3,0xa1,
        0x17,0xb7,0xc6,0x9d,0x8f,0x0a,0x64,0x24,
        0xbb,0xc3,0xef,0x47,0x73,0x98,0x43,0x5c,
        0x08,0x1d,0x97,0xa8,0xeb,0x2f,0xce,0xba,
        0xca,0x65,0x4c,0x57,0x47,0x19,0x1d,0x02,
        0x41,0x00,0xb6,0xc8,0x04,0x0f,0x66,0x19,
        0x9c,0x70,0x01,0xbc,0x91,0x9d,0xd0,0xb7,
        0xa1,0x4c,0xf1,0x2a,0xb8,0xd6,0x06,0x44,
        0x19,0x3c,0x45,0x6a,0x64,0x87,0x8f,0x3c,
        0xdf,0xa3,0x9f,0xb2,0x44,0x5a,0x12,0xf7,
        0x81,0x2d,0x70,0x8c,0x72,0xb1,0xf2,0x55,
        0x4f,0xfa,0x3b,0xb8,0xe1,0x1c,0xfc,0xd0,
        0xe9,0xc5,0x9c,0xe8,0xd8,0xd6,0x9a,0xe9,
        0x07,0xd3};

int main()
{   

  const unsigned char *p = key;
  RSA *r = d2i_RSAPrivateKey(NULL, &p, sizeof(key));

  /**
   * int PEM_write_RSAPrivateKey(FILE *fp, RSA *x, const EVP_CIPHER *enc,
   *                                        unsigned char *kstr, int klen,
   *                                        pem_password_cb *cb, void *u);
   * int PEM_write_RSAPublicKey(FILE *fp, RSA *x);
   **/ 

  PEM_write_RSAPrivateKey(stdout, r, NULL, 0, 0, NULL, NULL);
  PEM_write_RSAPublicKey(stdout, r);

  return 0;
 
}

It can be seen that the code works quite well ๐Ÿ˜€

:~/CodeBits $ ./dumpkey 
------BEGIN RSA PRIVATE KEY-----
MIICXgIBAAKBgQDEXifZZo4PJWapRdbfKcpdhBmSqoeYvNCIUtZhsDuayEk2SXxo
vEgiGB3NX2JBrOzLR6f6dbPP8trjoXelA5jok6XHGGPKz+U9M7pOaHVBCWN4mjdY
UlT4ORkW9bmmpdvALt8GjcLZMiND75bKHEJGSkzFJlzIqiELAZRgkkO6UQIDAQAB
AoGAUXXJzCr6FZhrXR9Gwu8ALwkk3q31cEwrqdHLc1z7bPtXO7kCbiRlPBeLDW5b
QWluFeoU6ha30DUrzrBmBMNYQ7Bcg8Jf3tY3u6H87ZY41MGwprH5VWB1H6IVKWdt
iHoeRepeNu8me4b4y24K9zaDHWYnIlPtMJFbbdLGli/AyNECQQD2RvMPp855JZU6
FjdqY2I7cxflyvmftFc8jpU7F4zpNiFYI7xcCADwYkEcIRLZctFsGMH2Vtqiuska
oa4db5NVAkEAzB7Jf5Sa2ffmojSm/nYbTvdaAQFqqvU5RhfqZ3NUsgcbU0BF2/2n
/Bu0aKz31U44F8dTTPRYUIa0RSnPk+JDDQJBAOpJMK2yC8BAOqhZvjoddbPsl81p
vPNrUpovYlQm4UxyzGHXDTfX/VyxfBNQe2gVzJizLMI2eiPY4bvOF5+1J0kCQQCv
jacFaBzKbJBaX2hkn9Wa09f/12UTRbcNltIOST3Fo6EXt8adjwpkJLvD70dzmENc
CB2XqOsvzrrKZUxXRxkdAkEAtsgED2YZnHABvJGd0LehTPEquNYGRBk8RWpkh488
36OfskRaEveBLXCMcrHyVU/6O7jhHPzQ6cWc6NjWmukH0w==
------END RSA PRIVATE KEY-----
------BEGIN RSA PUBLIC KEY-----
MIGJAoGBAMReJ9lmjg8lZqlF1t8pyl2EGZKqh5i80IhS1mGwO5rISTZJfGi8SCIY
Hc1fYkGs7MtHp/p1s8/y2uOhd6UDmOiTpccYY8rP5T0zuk5odUEJY3iaN1hSVPg5
GRb1uaal28Au3waNwtkyI0PvlsocQkZKTMUmXMiqIQsBlGCSQ7pRAgMBAAE=
------END RSA PUBLIC KEY-----

That’s it! ๐Ÿ™‚

It’s worth to mention the existence of passe-partout which could really help in a number of situations. I encourage to visit the passe-partout website as It contains interesting information related to encryption data structures.

Cheers!

Published inctfdebugginghackinglinux