以下の内容はhttps://yocchin.hatenablog.com/entry/2024/09/30/192708より取得しました。


H7CTF International Writeup

この大会は2024/9/26 12:30(JST)~2024/9/27 20:30(JST)に開催されました。
今回は個人で参戦。平日開催だったので、あまり取り組めませんでしたが、
結果は1025点で527チーム中95位でした。
自分で解けた問題をWriteupとして書いておきます。

Unfair (Misc)

Instagramでh7texのアカウントを検索すると、以下が該当しそうだ。

https://www.instagram.com/h7tex_/

ヘッダ部のリンクにアクセスすると、以下のURLになり、動画にフラグが書いてあった。

https://www.instagram.com/stories/highlights/18253881865266370/

H7CTF{d1dn'7_th1nk_7h1s_w4$_p0$$1b1e}

Scrambled Pathways (Reverse)

Ghidraでデコンパイルする。

undefined8 main(void)

{
  size_t sVar1;
  size_t sVar2;
  long in_FS_OFFSET;
  int local_170;
  int local_16c;
  int local_168;
  undefined8 local_158;
  undefined8 local_150;
  undefined8 local_148;
  undefined8 local_140;
  undefined8 local_138;
  undefined8 local_130;
  undefined2 local_128;
  undefined8 local_126;
  undefined8 local_11e;
  undefined8 local_116;
  undefined8 local_10e;
  undefined8 local_106;
  undefined8 local_fe;
  undefined2 local_f6;
  undefined8 local_f4;
  undefined8 local_ec;
  undefined8 local_e4;
  undefined8 local_dc;
  undefined8 local_d4;
  undefined8 local_cc;
  undefined2 local_c4;
  undefined8 local_b8;
  undefined8 local_b0;
  undefined8 local_a8;
  undefined8 local_a0;
  undefined8 local_98;
  undefined8 local_90;
  undefined2 local_88;
  char local_78 [104];
  long local_10;
  
  local_10 = *(long *)(in_FS_OFFSET + 0x28);
  local_158 = 0;
  local_150 = 0;
  local_148 = 0;
  local_140 = 0;
  local_138 = 0;
  local_130 = 0;
  local_128 = 0;
  local_126 = 0;
  local_11e = 0;
  local_116 = 0;
  local_10e = 0;
  local_106 = 0;
  local_fe = 0;
  local_f6 = 0;
  local_f4 = 0;
  local_ec = 0;
  local_e4 = 0;
  local_dc = 0;
  local_d4 = 0;
  local_cc = 0;
  local_c4 = 0;
  printf("Input: ");
  __isoc99_scanf(&DAT_0010200c,local_78);
  sVar1 = strlen(local_78);
  for (local_170 = 0; local_170 < 3; local_170 = local_170 + 1) {
    for (local_16c = local_170; local_16c < (int)sVar1; local_16c = local_16c + 3) {
      sVar2 = strlen((char *)((long)&local_158 + (long)local_170 * 0x32));
      *(char *)((long)&local_158 + (long)(int)sVar2 + (long)local_170 * 0x32) = local_78[local_16c];
      *(undefined *)((long)&local_158 + (long)((int)sVar2 + 1) + (long)local_170 * 0x32) = 0;
    }
  }
  local_b8 = 0;
  local_b0 = 0;
  local_a8 = 0;
  local_a0 = 0;
  local_98 = 0;
  local_90 = 0;
  local_88 = 0;
  for (local_168 = 0; local_168 < 3; local_168 = local_168 + 1) {
    strcat((char *)&local_b8,(char *)((long)&local_158 + (long)local_168 * 0x32));
  }
  printf("Output: %s\n",&local_b8);
  if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) {
                    /* WARNING: Subroutine does not return */
    __stack_chk_fail();
  }
  return 0;
}

スキュタレー暗号になっている。

https://www.dcode.fr/scytale-cipherで Number of turns of the band に3を指定して、復号する。
H7CTF{8485c79f20fa97227b92a476714c8081}

Exponential Enigma (Reverse)

Ghidraでデコンパイルする。

undefined8 main(void)

{
  ulong uVar1;
  size_t sVar2;
  long in_FS_OFFSET;
  int local_54;
  int local_50;
  int local_4c;
  uint auStack_38 [6];
  long local_20;
  
  local_20 = *(long *)(in_FS_OFFSET + 0x28);
  for (local_54 = 1; local_54 < 5; local_54 = local_54 + 1) {
    uVar1 = tetra(2,local_54);
    auStack_38[local_54 + -1] = (int)uVar1 + (int)(uVar1 / 0x13) * -0x13;
  }
  for (local_50 = 0; local_50 < 4; local_50 = local_50 + 1) {
    printf("%d ",(ulong)auStack_38[local_50]);
  }
  local_4c = 0;
  while( true ) {
    sVar2 = strlen("REDACTED");
    if (sVar2 <= (ulong)(long)local_4c) break;
    printf("%x",(ulong)((int)"REDACTED"[local_4c] ^ auStack_38[local_4c % 4]));
    local_4c = local_4c + 1;
  }
  putchar(10);
  if (local_20 != *(long *)(in_FS_OFFSET + 0x28)) {
                    /* WARNING: Subroutine does not return */
    __stack_chk_fail();
  }
  return 0;
}
$ ./chall2
2 4 16 5 5041544441505541

auStack_38[0]~auStack_38[3]は2, 4, 16, 5であることがわかる。また、出力された16進数文字列は以下の通りである。

4a335351447f273d6461726637312164336222303b35213667302835376271343a37753530306d

2桁ごとにkeyを[2, 4, 16, 5]に指定して、XORで復号する。

>>> s = bytes.fromhex('4a335351447f273d6461726637312164336222303b35213667302835376271343a37753530306d')
>>> k = [2, 4, 16, 5]
>>> ''.join([chr(s[i] ^ k[i % 4])  for i in range(len(s))])
'H7CTF{78febc551a1f259113e4805fa183e024}'
H7CTF{78febc551a1f259113e4805fa183e024}

Bitwise Mystery (Reverse)

pycをデコンパイルする。

$ pycdc chall3.pyc            
# Source Generated with Decompyle++
# File: chall3.pyc (Python 3.6)

flag = 'REDACTED'
n = flag
c = int(input('Enter a number: '))
if len(n) % 2:
    n += '*'
m = []
for i in range(0, len(n), 2):
    a = ord(n[i])
    b = ord(n[i + 1])
    m.append((a << c) + b)

print(m)

"H7CTF{"から始まることを前提にcを求める。あとはそれを元に復号していく。

#!/usr/bin/env python3
import math

m = [322523242873603806320271688401855976049516951601789533025598430538786029449943176134846359031111424671799, 300125795451825764214697265596171533268300496629443037676598539529148110738141566681037584098395353514068, 313564263904892589478041919279582198937030369612850934885998474134930861965222532353322849058024996208763, 232933453186491637897973997179118204924651131712403551629598866500234354602736738319611259300247140040806, 223974474217780421055744228056844427812164549723464953489998910096379187118016094538087749327160711577697, 215015495249069204213514458934570650699677967734526355350398953692524019633295450756564239354074283114550, 443469458951205233690373571552551967068085808452460607910197841990830790493671867185413743667778208923745, 215015495249069204213514458934570650699677967734526355350398953692524019633295450756564239354074283114595, 219494984733424812634629343495707539255921258728995654420198931894451603375655772647325994340617497346149, 246371921639558463161318650862528870593381004695811448838998801106017105829817703991896524259876782735457, 237412942670847246319088881740255093480894422706872850699398844702161938345097060210373014286790354272312, 232933453186491637897973997179118204924651131712403551629598866500234354602736738319611259300247140040806, 246371921639558463161318650862528870593381004695811448838998801106017105829817703991896524259876782735458, 241892432155202854740203766301391982037137713701342149769198822904089522087457382101134769273333568503908, 456907927404272058953718225235962632736815681435868505119597776596613541720752832857699008627407851618352, 215015495249069204213514458934570650699677967734526355350398953692524019633295450756564239354074283114550, 250851411123914071582433535423665759149624295690280747908798779307944689572178025882658279246419996966964, 438989969466849625269258686991415078511842517457991308840397863788903206751311545294651988681234994692194, 255330900608269680003548419984802647705867586684750046978598757509872273314538347773420034232963211198513, 559936185544451052639360570142111069530411374308662383724997275240947967795040236345219373317901778944042]

flag_head = b'H7'
a = flag_head[0]
b = flag_head[1]
assert (m[0] - b) % a == 0

c = int(math.log2((m[0] - b) // a))
assert (a << c) + b == m[0]

flag = ''
for i in range(len(m)):
    b = int(hex(m[i])[-2:], 16)
    a = (m[i] - b) >> c
    flag += chr(a)
    flag += chr(b)

flag = flag.rstrip('*')
print(flag)
H7CTF{4f2a06ca0c1e7a584f7b6df00684bb91}

NewsLeaks (Web)

HTMLソースを見てみると、以下のような形式でアクセスしていることがわかる。

https://newsleaks.h7tex.com/view.php?file=newspaper1.html

https://newsleaks.h7tex.com/view.php?file=../etc/passwdにアクセスすると、以下のように表示された。

news/.etc/passwd not found

"./"が削除されるようなので、それを踏まえて指定する。
https://newsleaks.h7tex.com/view.php?file=...//...//...//...//etc/passwdにアクセスすると、以下のように表示された。

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
H7CTF{54n1t1z3_L0c4l_F1l3_1nclusi0n}
H7CTF{54n1t1z3_L0c4l_F1l3_1nclusi0n}

Khabib (Forensics)

画像を小さくして、周りにペンキを塗ると、真ん中あたりだけ色が異なることがわかる。元の画像で真ん中あたりを見てみると、フラグが書いてあった。

H7CTF{PNG_z00mz_4r3_1mp0ss1ble_t0_n0t1ce}

Ghost IP (Forensics)

IPv4の統計情報を見る。最も通信が多い192.168.1.11がターゲットと推測できる。それに対して、次に通信が多いIPアドレスが攻撃者のものと推測する。

H7CTF{192.168.1.9}

OG Fermat (Cryptography)

RSA暗号。問題タイトルからもnをFermat法で素因数分解して復号する。ただし、cの末尾4桁が不明なので、ブルートフォースする。

#!/usr/bin/env python3
from Crypto.Util.number import *

def isqrt(n):
    x = n
    y = (x + n // x) // 2
    while y < x:
        x = y
        y = (x + n // x) // 2
    return x

def fermat(n):
    x = isqrt(n) + 1
    y = isqrt(x * x - n)
    while True:
        w = x * x - n - y * y
        if w == 0:
            break
        elif w > 0:
            y += 1
        else:
            x += 1
    return x - y, x + y

def is_printable(s):
    for c in s:
        if c < 32 or c > 126:
            return False
    return True

n = 19941761574905742888287481436741891092124181365374951557784462831976463640107265018634834348445714890239773671635245721007690323617473110640838905137749040079027523456576873242576882348266023282328418714706775196352487380997352642934338999701240803315143633815388891936049690566875086476878846288179053430346474607507140036260924419560806005408849547824680623840905827643373832321736642361809029363098769822048159935628385558949380403530181068302284344450193809037352292218892697094260257903235373427839438588016417069626966199168116250816624950794879795025563625197229849548571880188149181610538268071041049047969843
e = 65537
c_base = 19884857528166034194290354901025594547806401534797199549580543708532212531494632428055499138843523751957005738044894685860481662931551960621390631298434633050540355913401713821919702972642244121105189212488383052634514542718912769480579081471731152464650132606046581540616642016627941035016241596730862645447447571127721458637731806036686864624004097100207773539304392234840729042840767039997395315211803763621246672310876625311211274710089635086349825580201804347380144554074800132708339497620161659452151212806639994177512127235920012893886522385616218483464075257945830394483951539176790009646364555199532294580000

p, q = fermat(n)
phi = (p - 1) * (q - 1)
d = inverse(e, phi)

for x in range(10000):
    c = c_base + x
    m = pow(c, d, n)
    flag = long_to_bytes(m)
    if is_printable(flag):
        flag = flag.decode()
        print(flag)
        break
H7CTF{f3rm@t_r3@lly_l2f7_@!!_7h3se_unpr0v3d!}



以上の内容はhttps://yocchin.hatenablog.com/entry/2024/09/30/192708より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14