問題
reversing 05 firmware
ctf4b networks社のページからファームウェアをダウンロードしてきました。
このファイルの中からパスワードを探してください。
青い空を見上げればいつもそこに白い猫
算出サイズを無視してにチェック
検索除外対象のzlibのチェックを外す
検索実行
ボタン
ELFを選択
算出サイズを下選択で修正 4MBを指定
リスト選択項目を保存
ボタン
strings
Input password
Incorrect password
などの文字が見える
main関数の初期デコンパイル結果
undefined8 main(void)
{
int iVar1;
size_t sVar2;
socklen_t local_11e4;
int local_11e0;
int local_11dc;
int local_11d8;
FILE *local_11d4;
size_t local_11d0;
char *local_11cc;
undefined local_11c8 [4];
undefined4 local_11c4;
sockaddr sStack4536;
uint auStack4520 [61];
undefined4 local_10b4;
undefined4 uStack4272;
undefined4 uStack4268;
undefined4 uStack4264;
undefined4 local_10a4;
undefined local_10a0;
undefined4 local_109c;
undefined4 uStack4248;
undefined4 uStack4244;
undefined4 uStack4240;
undefined4 local_108c;
undefined4 uStack4232;
undefined4 uStack4228;
undefined4 uStack4224;
undefined4 local_107c;
undefined local_1078;
char acStack4212 [96];
byte abStack4116 [4096];
int local_14;
local_14 = __stack_chk_guard;
local_11dc = socket(2,1,0);
if (local_11dc < 0) {
perror("Failed to set socket.");
}
else {
local_11c8._0_2_ = 2;
local_11c8._2_2_ = htons(0x1f90);
local_11c4 = 0;
iVar1 = bind(local_11dc,(sockaddr *)local_11c8,0x10);
if (iVar1 == 0) {
iVar1 = listen(local_11dc,5);
if (iVar1 == 0) {
while( true ) {
local_11e4 = 0x10;
local_11d8 = accept(local_11dc,&sStack4536,&local_11e4);
local_11d4 = fopen("ascii.txt","r");
if (local_11d4 == (FILE *)0x0) break;
fseek(local_11d4,0,2);
local_11d0 = ftell(local_11d4);
fseek(local_11d4,0,0);
local_11cc = (char *)calloc(local_11d0,1);
if (local_11cc == (char *)0x0) {
perror("Failed to read file.");
close(local_11d8);
goto LAB_00010cf4;
}
fread(local_11cc,1,local_11d0,local_11d4);
fclose(local_11d4);
sVar2 = strlen(local_11cc);
send(local_11d8,local_11cc,sVar2,0);
free(local_11cc);
memcpy(acStack4212,
"This is a IoT device made by ctf4b networks. Password authentication is required to operate.\n"
,0x5e);
sVar2 = strlen(acStack4212);
send(local_11d8,acStack4212,sVar2,0);
local_109c = 0x75706e49;
uStack4248 = 0x61702074;
uStack4244 = 0x6f777373;
uStack4240 = 0x28206472;
local_108c = 0x73736170;
uStack4232 = 0x64726f77;
uStack4228 = 0x20736920;
uStack4224 = 0x47414c46;
local_107c = 0x203e2029;
local_1078 = 0;
sVar2 = strlen((char *)&local_109c);
send(local_11d8,&local_109c,sVar2,0);
memset(abStack4116,0,0x1000);
recv(local_11d8,abStack4116,0x1000,0);
printf("%s",abStack4116);
memcpy(auStack4520,&DAT_00010ea4,0xf4);
sVar2 = strlen((char *)abStack4116);
if (sVar2 != 0x3d) {
local_10b4 = 0x6f636e49;
uStack4272 = 0x63657272;
uStack4268 = 0x61702074;
uStack4264 = 0x6f777373;
local_10a4 = 0xa2e6472;
local_10a0 = 0;
sVar2 = strlen((char *)&local_10b4);
send(local_11d8,&local_10b4,sVar2,0);
close(local_11d8);
}
local_11e0 = 0;
while (local_11e0 < 0x3d) {
if ((uint)(abStack4116[local_11e0] ^ 0x53) != auStack4520[local_11e0]) {
local_10b4 = 0x6f636e49;
uStack4272 = 0x63657272;
uStack4268 = 0x61702074;
uStack4264 = 0x6f777373;
local_10a4 = 0xa2e6472;
local_10a0 = 0;
sVar2 = strlen((char *)&local_10b4);
send(local_11d8,&local_10b4,sVar2,0);
close(local_11d8);
}
local_11e0 = local_11e0 + 1;
}
local_10b4 = 0x72726f43;
uStack4272 = 0x20746365;
uStack4268 = 0x73736170;
uStack4264 = 0x64726f77;
local_10a4 = 0xa212121;
local_10a0 = 0;
sVar2 = strlen((char *)&local_10b4);
send(local_11d8,&local_10b4,sVar2,0);
close(local_11d8);
}
perror("Failed to read file.");
close(local_11d8);
}
else {
perror("Failed to listen.");
}
}
else {
perror("Failed to bind.");
}
}
LAB_00010cf4:
if (__stack_chk_guard != local_14) {
/* WARNING: Subroutine does not return */
__stack_chk_fail();
}
return 1;
}
if ((uint)(abStack4116[local_11e0] ^ 0x53) != auStack4520[local_11e0]) {
local_10b4 = 0x6f636e49;
uStack4272 = 0x63657272;
uStack4268 = 0x61702074;
uStack4264 = 0x6f777373;
local_10a4 = 0xa2e6472;
0x53 と xor して違ってたら Incorrect password と表示している。
変数名を変更してデコンパイル結果を見やすくする
変更前 | 変更後 |
---|---|
auStack4520 | enc_flag |
local_11e0 | i |
abStack4116 | input |
sVar2 | inputlength |
undefined8 main(void)
{
int iVar1;
size_t inputlength;
socklen_t local_11e4;
int i;
int local_11dc;
int local_11d8;
FILE *local_11d4;
size_t local_11d0;
char *local_11cc;
undefined local_11c8 [4];
undefined4 local_11c4;
sockaddr sStack4536;
uint enc_flag [61];
undefined4 local_10b4;
undefined4 uStack4272;
undefined4 uStack4268;
undefined4 uStack4264;
undefined4 local_10a4;
undefined local_10a0;
undefined4 local_109c;
undefined4 uStack4248;
undefined4 uStack4244;
undefined4 uStack4240;
undefined4 local_108c;
undefined4 uStack4232;
undefined4 uStack4228;
undefined4 uStack4224;
undefined4 local_107c;
undefined local_1078;
char acStack4212 [96];
byte input [4096];
int local_14;
local_14 = __stack_chk_guard;
local_11dc = socket(2,1,0);
if (local_11dc < 0) {
perror("Failed to set socket.");
}
else {
local_11c8._0_2_ = 2;
local_11c8._2_2_ = htons(0x1f90);
local_11c4 = 0;
iVar1 = bind(local_11dc,(sockaddr *)local_11c8,0x10);
if (iVar1 == 0) {
iVar1 = listen(local_11dc,5);
if (iVar1 == 0) {
while( true ) {
local_11e4 = 0x10;
local_11d8 = accept(local_11dc,&sStack4536,&local_11e4);
local_11d4 = fopen("ascii.txt","r");
if (local_11d4 == (FILE *)0x0) break;
fseek(local_11d4,0,2);
local_11d0 = ftell(local_11d4);
fseek(local_11d4,0,0);
local_11cc = (char *)calloc(local_11d0,1);
if (local_11cc == (char *)0x0) {
perror("Failed to read file.");
close(local_11d8);
goto LAB_00010cf4;
}
fread(local_11cc,1,local_11d0,local_11d4);
fclose(local_11d4);
inputlength = strlen(local_11cc);
send(local_11d8,local_11cc,inputlength,0);
free(local_11cc);
memcpy(acStack4212,
"This is a IoT device made by ctf4b networks. Password authentication is required to operate.\n"
,0x5e);
inputlength = strlen(acStack4212);
send(local_11d8,acStack4212,inputlength,0);
local_109c = 0x75706e49;
uStack4248 = 0x61702074;
uStack4244 = 0x6f777373;
uStack4240 = 0x28206472;
local_108c = 0x73736170;
uStack4232 = 0x64726f77;
uStack4228 = 0x20736920;
uStack4224 = 0x47414c46;
local_107c = 0x203e2029;
local_1078 = 0;
inputlength = strlen((char *)&local_109c);
send(local_11d8,&local_109c,inputlength,0);
memset(input,0,0x1000);
recv(local_11d8,input,0x1000,0);
printf("%s",input);
memcpy(enc_flag,&DAT_00010ea4,0xf4);
inputlength = strlen((char *)input);
if (inputlength != 0x3d) {
local_10b4 = 0x6f636e49;
uStack4272 = 0x63657272;
uStack4268 = 0x61702074;
uStack4264 = 0x6f777373;
local_10a4 = 0xa2e6472;
local_10a0 = 0;
inputlength = strlen((char *)&local_10b4);
send(local_11d8,&local_10b4,inputlength,0);
close(local_11d8);
}
i = 0;
while (i < 0x3d) {
if ((uint)(input[i] ^ 0x53) != enc_flag[i]) {
local_10b4 = 0x6f636e49;
uStack4272 = 0x63657272;
uStack4268 = 0x61702074;
uStack4264 = 0x6f777373;
local_10a4 = 0xa2e6472;
local_10a0 = 0;
inputlength = strlen((char *)&local_10b4);
send(local_11d8,&local_10b4,inputlength,0);
close(local_11d8);
}
i = i + 1;
}
local_10b4 = 0x72726f43;
uStack4272 = 0x20746365;
uStack4268 = 0x73736170;
uStack4264 = 0x64726f77;
local_10a4 = 0xa212121;
local_10a0 = 0;
inputlength = strlen((char *)&local_10b4);
send(local_11d8,&local_10b4,inputlength,0);
close(local_11d8);
}
perror("Failed to read file.");
close(local_11d8);
}
else {
perror("Failed to listen.");
}
}
else {
perror("Failed to bind.");
}
}
LAB_00010cf4:
if (__stack_chk_guard != local_14) {
/* WARNING: Subroutine does not return */
__stack_chk_fail();
}
return 1;
}
solver ( Ghidra Script )
#
# solver for SECCON Beginners CTF 2021 firmware
#
enc=getBytes(toAddr(0x10ea4),0x3d*4)
print(enc)
flag=[]
i = 0
while i < 0x3d:
flag.append(enc[i*4] ^ 0x53)
i = i + 1
print(''.join(map(chr,flag)))
binwalk で解析
比較対象の青い空を見上げればいつもそこに白い猫
のシグネチャ解析
シグネチャ解析
# binwalk --signature ./firmware.bin
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
127 0x7F Base64 standard index table
2343 0x927 Copyright string: "Copyright 2011-2021 The Bootstrap Authors"
2388 0x954 Copyright string: "Copyright 2011-2021 Twitter, Inc."
83503 0x1462F PNG image, 594 x 100, 8-bit grayscale, non-interlaced
83544 0x14658 Zlib compressed data, best compression
90593 0x161E1 ELF, 32-bit LSB shared object, ARM, version 1 (SYSV)
100906 0x18A2A Unix path: /usr/lib/gcc/arm-linux-gnueabihf/9/../../../arm-linux-gnueabihf/Scrt1.o
103485 0x1943D JPEG image data, JFIF standard 1.01
117167 0x1C9AF PEM certificate
117786 0x1CC1A HTML document header
118641 0x1CF71 HTML document footer
自動抽出( elf を抜くように extract.conf を編集済み)
# binwalk -e firmware.bin
/_firmware.bin.extracted# ls -al
total 132
drwxrwx--- 1 root vboxsf 0 May 27 15:28 .
drwxrwx--- 1 root vboxsf 4096 May 27 15:28 ..
-rwxrwx--- 1 root vboxsf 59500 May 27 15:28 14658
-rwxrwx--- 1 root vboxsf 36397 May 27 15:28 14658.zlib
-rwxrwx--- 1 root vboxsf 29348 May 27 15:28 161E1.elf
全部抜けない
個別抽出
# binwalk -D 'zip archive:zip:unzip %e' -D 'png image:png' firmware.bin
/_firmware.bin.extracted# ls -al
total 136
drwxrwx--- 1 root vboxsf 0 May 27 15:31 .
drwxrwx--- 1 root vboxsf 4096 May 27 15:31 ..
-rwxrwx--- 1 root vboxsf 36438 May 27 15:31 1462F.png
-rwxrwx--- 1 root vboxsf 59500 May 27 15:31 14658
-rwxrwx--- 1 root vboxsf 36397 May 27 15:31 14658.zlib
ELFの抜き方がわからんし,全部抜けん。
結論
自動抽出や個別抽出は抽出結果に拡張子がついて見やすいけど,全部抽出できない
本当に全部抜くコマンド
# binwalk -D=".*" firmware.bin
/_firmware.bin.extracted# ls -al
total 576
drwxrwx--- 1 root vboxsf 4096 May 27 15:34 .
drwxrwx--- 1 root vboxsf 4096 May 27 15:34 ..
-rwxrwx--- 1 root vboxsf 36438 May 27 15:34 1462F
-rwxrwx--- 1 root vboxsf 59500 May 27 15:34 14658
-rwxrwx--- 1 root vboxsf 36397 May 27 15:34 14658.zlib
-rwxrwx--- 1 root vboxsf 29348 May 27 15:34 161E1
-rwxrwx--- 1 root vboxsf 19035 May 27 15:34 18A2A
-rwxrwx--- 1 root vboxsf 16456 May 27 15:34 1943D
-rwxrwx--- 1 root vboxsf 2774 May 27 15:34 1C9AF
-rwxrwx--- 1 root vboxsf 2155 May 27 15:34 1CC1A
-rwxrwx--- 1 root vboxsf 1300 May 27 15:34 1CF71
-rwxrwx--- 1 root vboxsf 119814 May 27 15:34 7F
-rwxrwx--- 1 root vboxsf 117598 May 27 15:34 927
-rwxrwx--- 1 root vboxsf 117553 May 27 15:34 954
/_firmware.bin.extracted# file 161E1
161E1: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, BuildID[sha1]=d4fde2a811fccb987ffb2e075b170db18f797b8a, for GNU/Linux 3.2.0, not stripped
ちゃんと抜けてます。
なんで,公式サイトに binwalk -D=".*" firmware.bin
を書いてないんだろ?
↓↓↓本当に全部抜くコマンドが記載されていたサイト