Blog Advisories Writeups Tools Exploits Contact Search:  

Writeup: PCTF (21 – Key leak – 450pts)
Here is the write-up for the CTF challenge #21 organized by the team PPP. I liked this one pretty much, I think it was a very good challenge a bit tricky but still a very good one. Congrats to PPP for this original idea


Category: pwnables

We have obtained the binary for AED's internal data encryption service, running at a9.amalgamated.biz:10240.

Obtain AED's data encryption key.


We were the first team to solve this challenge, so we got some extra breakthrough points, and as far as I'm concerned we where the only ones who solved it.

first of all lets see what this little service does:

As can be seen in the image, it asks for a username and then for some input to be ciphered. After some text its supplied it returns the input encrypted, no more magic, as easy as sounds.

There are only two inputs so finding the overflow is quite easy as anyone could expect:

Lets see what is happening inside the program:

OK, we are overwriting the file descriptor pointer where the log will be written, but how can exploit this in a profitable way? Lets take a look to the code where the overflow takes place:

Well... The overflow happens at the snprintf() function, it prevents us from overwriting RET/EIP due to the 80 chars limit on it, but allows us to overwrite "int v4" and "FILE *stream" which are on the stack next to "char ptr". The variable "int v4" is set to 0 after fwrite() and not used since the BoF takes place and v4 being set to 0. So again, how could we take profit of this? We could replace the file descriptor with stdout but we will only get the logline printed to us which isn't very useful as it only prints a timestamp and the username previously supplied by us.

Lets take a look to the main code:

Just after the writelog() function where the BoF takes place, the key file is being opened. Does this suggest something to you? Lets inspect the file descriptors status just after the username has been supplied and the program asks for the text to be encrypted:

OK, now we are going to exploit the BoF to change the log file descriptor and point it to "stdin":

Weird, it says "Key length 0" and "Input length 30", but we didn't supply any more input than the username... lets inspect the file descriptors again to see what happened:

Nice!!! When replacing the logfile file descriptor pointer with the one from stdin, the program closes the logfile (in this case stdin) after writing the log, then it opens the key file which is assigned to the first free file descriptor number, in this case 0 which matches with stdin, so now the program is using the keyfile as input/stdin.

This would be a resume about what is happening:
  1. The program opens the logfile /home/keyleak/log (file descriptor 5)
  2. The overflow takes place and we replace the logfile file descriptor pointer with another one pointing to stdin
  3. The program closes the logfile descriptor which is now stdin (file descriptor 0)
  4. File descriptor 0 is now free and closed so there isn't input/stdin available
  5. The program opens /home/keyleak/key and assigns it the first free file descriptor in this case 0 which is also used for stdin (file descriptor 0)
  6. The program reads from user input (stdin) to encrypt it, but its really reading /home/keyleak/key
  7. The program reads /home/keyleak/key but as the read offset is already at the end due to the "user input read" it reads 0 bytes
  8. Now the program encrypts /home/keyleak/key with a NULL key and returns it to us

Well this sounds pretty straight forward, but now we have to do the same in the server to retrieve the key and it has ASLR enabled... Lets see what we can do about it... These are three runs checking for a stdin pointer address:

Breakpoint 1, _IO_fgets (buf=0xffb2eb28 "", n=0x80, fp=0xb74ef420) at iofgets.c:42
Breakpoint 1, _IO_fgets (buf=0xffa178a8 "", n=0x80, fp=0xb755c420) at iofgets.c:42
Breakpoint 1, _IO_fgets (buf=0xffee09f8 "", n=0x80, fp=0xb7509420) at iofgets.c:42

ASLR is randomizing 12bits of the file descriptor pointer address so we have 2^12 = 4096 possible addresses, we can bruteforce all the possible addresses or stay at one of them hoping to match on one of the runs. We tried both and the first one to success was sticking to one of the addresses. Take a look to the screenshot bellow for a successful exploitation:

We should have redirected the output to a file to be able to extract the encrypted response which includes non printable characters. But lets see what we get and what the program returns:

It returns multiple data, if you take a look to the main code in one of the screenshots you will see that those three outputs are:
  1. IV (Random data) for PKCS5_PBKDF2_HMAC to derive the key
  2. IV (Random data) for EVP_DecryptInit_ex to perform the aes 256 cbc encryption
  3. The resulting ciphertext

With all this information we can now code a program to decrypt the response and get the key to score some precious points...

Note that the code shown has no error checking to make the screenshot smaller. You can grab the original source code here.

And at last the result of the execution:

So the key was:

I grow tomatoes in my garden.

Date: April 26th, 2011 | By: NighterMan


Anonymous Says:


Jose Luis Says:

Me ha encantado!!

Muy claro y conciso.

Me alegra ver y observar de q hay gente x ahi q comparte lo q para mi es una verdadera pasion desde hace ya muchos a帽os, el verdadero Hacking(Research) q aporta un valor a帽adido a la Seguridad.

Un buen articulo!!


Feeguggisee Says:

銈掋仚銇广仸together.5銈掑彇銈婇櫎銇忥級銉偟銈ゃ偗銉� – 銉偟 銈般儍銉� 2013 銇с伅銇傘倞銇俱仜銈� 鍙炽伄90姝炽伄瑾曠敓鏃ャ伄銇婄銇勩伨銇с仺銇濄倢浠ラ檷銇嚭 銈汇偆銈炽兗 銉栥儵銈ゃ儎 銉曘偋銉嬨儍銈偣 銈儷銈掓暀銇堛倠銇熴倎銇渶鍠勩伄鏂规硶銈掑銇躲亾銇ㄣ亴銇с亶銇俱仚 銇勩亸銇ゃ亱銇� http://www.gdzqda.com/ 銇勩�佸郊銇仢銈屻倰瑷�銈忋倢銇﹂潪甯搞伀鑹亱銇c仧銆� One銇傘伨銈婄煡銈夈倢銇� TUMI 銈广兗銉勩偙銉笺偣 鍙c偝銉� 銇弸浜恒倓杩戞墍銇汉銇ㄤ竴绶掋伀鏄犵敾銈掕銇︽ソ銇椼個銇撱仺銇屻仹銇嶃伨銇欍�� 銉� 銉愩兗銉愩儶銉� 銉愩儍銈� 鏂颁綔 銈堛亸鐭ャ倝銈屻仸銇勩倠銆� 銇濄倢銇父銇汉銆呫伄鍞竴銇垢閬嬫潫鎶介伕銉椼儹銈般儵鍚屻仒銇с亗銇c仧 – 褰笺倝銇�35-40瀛愩仼銈傘仧銇′竴绶掋伀銇欍伖銇︺�佷竴

Shonginiola Says:

IBS銈掑紩銇嶈捣銇撱仐銆併偣銉堛儸銈广亴鐩存帴鑵归儴銇鑳姐伀褰遍熆銈掍笌銇堛倠銇� 銈ㄣ儷銉°偣 璨″竷 銈炽償銉� 銈撱亗銈娾�嬧�嬨伨銇椼仧銆� 锛熺銇仢鈥嬧�嬨倢銈掕▓鐢汇仐銆佺銇嚜鍒嗐伄璧ゃ仭銈� 璨″竷 銉°兂銈� 銇娿仚銇欍倎 瀹广亴out.If銈掑惛寮曘仐銇︺亜銈嬨�佸尰鑰呫伅鑳嗗殺鎽樺嚭琛撱仺鍛笺伆銈屻倠鎿� CHANEL 璨″竷 琚鑰呫伅銆佸彈淇°仐銇熷銈勭棝銇裤伄鐩存帴瑁滃劅銈掑緱銈嬪繀瑕併亴銇傘倞銇俱仚銆� 銉嬨偗銈姐兂 銉儓銉偘 銉曘偂銉炽偪銈搞兗 銉愩兗銈€兗銉堛伄娴併倢銇亗銈娿伨銇欍亱锛� 銇傘仾銇熴伅銇欍伖銇︺伄鎵嬫銇с�併仢銇� 銈炽兗銉� 璨″竷 妤藉ぉ 銈夈仐銇勩仹銇欍�� 銇傘仾銇熴亴蹇呰銇ㄣ仚銈嬨仼銇倛銇嗐仾鐭ユ�с伄銇熴倎銇敮鎵曘亞銇█钁夈伅銆佹渶楂樸伄绉侀仈銇屻儖銉笺偤銇唤鐜囥伨銇熴伅鎬犳參銇с亗銇c仧銈娿�佷粬銇�

Feeguggisee Says:

銉椼偝銉笺兂銈掕磮涓庛伅銇┿亞銇с仐銈囥亞銇嬶紵 銇傘仾銇熴亴銇炽仯銇忋倞銇欍倠銇嬨倐銇� 銉儫銉庛儍銈偣 鑵曟檪瑷� 渚℃牸 鍒ゆ焙銇儑銉笺偪銈掓彁鍑恒仐銇亼銈屻伆銇倝銇亜銆�

鐘姜鑰呫亴鑷垎銇� 銉偢銈с儑銉ャ儢銈� 涓彜 鐩蹭俊銇ㄥ父璀樸倰鐥涖倎鐗╀簨銇奖闊裤倰涓庛亪銇︺亜銈嬨伄銇с亗銈嬨�� 銇濄倢銇銇� 銉€兂銈儸銉笺儷 2014 銉�銈︺兂 銉儑銈c兗銈� 銇撱伄鏃ョ劶銇戙儥銉冦儔銇伨銇熴�佺編瀹广儓銉兗銉堛儭銉炽儓銇仧銈併伀鐭ャ倝銈屻仸銇� 銈儹銈� 銉愩儍銈� 浣电棁銇�佸濞犮仐銇﹂枊鐧恒仐銇熴亾銇ㄣ倰銆佸郊濂炽伄鍗拌薄銇儠銉┿偘銇岀珛銇︺倝銈� UGG 銉栥兗銉� 銈儵銈枫儍銈儓銉笺儷 銇ㄣ仸銈傚姽鏋滅殑銇с仚銆�


Feeguggisee Says:

銇ぇ浜恒伄銈炽儫銉ャ儖銉嗐偅銇儛銈ゃ儰銉笺伄骞冲潎骞撮舰銇�67銇嬨倝61銇�侀亷 銈汇偆銈炽兗 銉嗐偅銈� ted.There銇傘仯銇熷緦銆佸郊銇�佹绱€伄绲愭灉銈掕獚璀樸仌銈屻倠銇广亶 銈兗銉夈偙銉笺偣 銉栥儵銉炽儔 璜囥亸銇犮仌銇勩�� 鍒ャ伀銇傘仾銇熴伀褰笺伄灏傞杸瀹躲伄鍔╄█銈掍笌銇堛倠銇撱仺銇嬨倝銆� 銉愩兗銉愩儶銉� 銉愩儍銈� 銉冦偗銈€儍銉椼伄鍔┿亼銈掑�熴倞銇︾啊鍗樸伀瑙f焙銇欍倠銇撱仺銇屻仹銇嶃伨銇欍伄銇с�併仐 銉嬨儱銉笺儛銉┿兂銈� 574 銉с兂銇惈銇俱倢銈嬪悇銉°兂銉愩兗銇儑銈搞偪銉啓鐪熴倰鎻愬嚭銇欍倠蹇呰銇屻亗銈娿伨 銉偆銉淬偅銉堛兂 銉犮伄銇濄倢銇炪倢銇с�併儭銈偡銈虫咕銇с伄鎺$敤銇曘倢銇︺亜銈嬨�� 銈儷銉笺伅銈儯浜嗐仐銇︺亜銈嬪彲鑳芥�с亴銈堛倞鑹亜绲勭箶銇ㄣ�併倛銈婂嚌闆嗐仌銈屻仸銇勩仧鍫村悎銇��

dvitto Says:

Pretty cool stuff…

Nice explanation, so even dummies like me would understand :P

Great work!

Leave us a Reply















  • No categories