[{"data":1,"prerenderedAt":259},["ShallowReactive",2],{"content:\u002Fhackthebox":3,"surround:\u002Fhackthebox":248},{"id":4,"title":5,"body":6,"categories":223,"date":225,"description":226,"draft":227,"extension":228,"image":229,"meta":230,"navigation":232,"path":233,"permalink":233,"published":229,"readingTime":234,"recommend":229,"references":229,"seo":239,"sitemap":240,"stem":241,"tags":242,"type":246,"updated":225,"__hash__":247},"content\u002Fposts\u002F2026\u002Fhackthebox.md","Hack The Box · Misc 两题速记",{"type":7,"value":8,"toc":213},"minimark",[9,13,18,26,57,60,70,76,84,97,101,104,108,164,171,177,180,186,189,195,198,201],[10,11,12],"p",{},"最近顺手做了两道很适合拿来练自动化思路的 Misc 题。题本身不算特别绕，但都很适合提醒自己一句话：能脚本化的事情，尽量不要手点。",[14,15,17],"h2",{"id":16},"_1-character","1. Character",[10,19,20,21,25],{},"这题的交互非常直接：服务端一次只返回 ",[22,23,24],"code",{"code":24},"flag"," 的一个字符。思路可以拆成三步：",[27,28,29,40,51],"ol",{},[30,31,32,33,36,37,39],"li",{},"先不断递增 ",[22,34,35],{"code":35},"index","，确认 ",[22,38,24],{"code":24}," 的总长度。",[30,41,42,43,46,47,50],{},"再从 ",[22,44,45],{"code":45},"0"," 遍历到 ",[22,48,49],{"code":49},"len - 1","，逐个拿字符。",[30,52,53,54,56],{},"最后把字符拼起来，得到完整 ",[22,55,24],{"code":24},"。",[10,58,59],{},"手动一个个输当然也能做，但实在太慢，所以直接写脚本自动化。",[61,62,68],"pre",{"className":63,"code":65,"language":66,"meta":67},[64],"language-python","import socket\nimport re\n\nHOST = \"154.57.164.81\"\nPORT = 31853\n\ndef get_char(index):\n    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n    s.settimeout(5)\n    s.connect((HOST, PORT))\n    s.recv(4096)  # 吞掉提示\n    s.sendall(f\"{index}\\n\".encode())\n    data = s.recv(4096)\n    s.close()\n    return data.decode(errors='ignore')\n\ndef main():\n    flag = \"\"\n    for i in range(200):\n        resp = get_char(i)\n\n        if \"Index out of range\" in resp:\n            print(f\"[!] 终止于 index={i}\")\n            break\n\n        m = re.search(r\"Character at Index \\d+: (.)\", resp)\n        if m:\n            flag += m.group(1)\n            print(f\"[{i:03d}] {m.group(1)}  -> {flag}\")\n\n    print(f\"\\n{'=' * 50}\")\n    print(f\"FLAG: {flag}\")\n    print(f\"{'=' * 50}\")\n\nif __name__ == \"__main__\":\n    main()\n","python","",[22,69,65],{"__ignoreMap":67},[10,71,72,73,75],{},"最后拿到的 ",[22,74,24],{"code":24},"：",[61,77,82],{"className":78,"code":80,"language":81,"meta":67},[79],"language-text","HTB{tH1s_1s_4_r3aLly_l0nG_fL4g_i_h0p3_f0r_y0Ur_s4k3_tH4t_y0U_sCr1pTEd_tH1s_oR_elS3_iT_t0oK_qU1t3_l0ng!!}\n","text",[22,83,80],{"__ignoreMap":67},[10,85,86,88,89,93,94,56],{},[22,87,24],{"code":24}," 长度一共是 ",[90,91,92],"strong",{},"104 个字符","，对应 ",[22,95,96],{"code":96},"index 0 ~ 103",[14,98,100],{"id":99},"_2-stop-drop-and-roll","2. Stop Drop and Roll",[10,102,103],{},"这题更像一个文字小游戏，本质还是 socket 自动化。",[105,106,107],"h3",{"id":107},"游戏规则",[109,110,111,124],"table",{},[112,113,114],"thead",{},[115,116,117,121],"tr",{},[118,119,120],"th",{},"输入",[118,122,123],{},"输出",[125,126,127,140,152],"tbody",{},[115,128,129,135],{},[130,131,132],"td",{},[22,133,134],{"code":134},"GORGE",[130,136,137],{},[22,138,139],{"code":139},"STOP",[115,141,142,147],{},[130,143,144],{},[22,145,146],{"code":146},"PHREAK",[130,148,149],{},[22,150,151],{"code":151},"DROP",[115,153,154,159],{},[130,155,156],{},[22,157,158],{"code":158},"FIRE",[130,160,161],{},[22,162,163],{"code":163},"ROLL",[10,165,166,167,170],{},"如果一轮里出现多个词，就按顺序映射后用 ",[22,168,169],{"code":169},"-"," 连接。比如：",[61,172,175],{"className":173,"code":174,"language":81,"meta":67},[79],"GORGE, FIRE, PHREAK -> STOP-ROLL-DROP\n",[22,176,174],{"__ignoreMap":67},[10,178,179],{},"同样直接写脚本自动打。",[61,181,184],{"className":182,"code":183,"language":66,"meta":67},[64],"import socket\nimport re\nimport time\n\nHOST = \"154.57.164.77\"\nPORT = 30123\n\nMAP = {\n    \"GORGE\": \"STOP\",\n    \"PHREAK\": \"DROP\",\n    \"FIRE\": \"ROLL\",\n}\n\ndef recv_until(s, marker, timeout=10):\n    \"\"\"接收数据直到出现 marker\"\"\"\n    s.settimeout(timeout)\n    buf = \"\"\n    while marker not in buf:\n        try:\n            chunk = s.recv(4096).decode(errors='ignore')\n            if not chunk:\n                break\n            buf += chunk\n        except socket.timeout:\n            break\n    return buf\n\ndef main():\n    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n    s.connect((HOST, PORT))\n\n    data = recv_until(s, \"ready? (y\u002Fn)\")\n    print(data, end='')\n\n    s.sendall(b\"y\\n\")\n\n    time.sleep(0.3)\n    data = recv_until(s, \"What do you do?\", timeout=5)\n    print(data, end='')\n\n    round_count = 0\n    while True:\n        if re.search(r'HTB\\{|htb\\{', data):\n            print(\"\\n🎀 FLAG FOUND!\")\n            break\n\n        if \"What do you do?\" not in data:\n            extra = recv_until(s, \"What do you do?\", timeout=3)\n            data += extra\n            print(extra, end='')\n            if \"What do you do?\" not in data:\n                print(\"[!] 意外数据:\", data)\n                break\n\n        for line in data.split('\\n'):\n            if any(k in line for k in MAP):\n                scenarios = [w.strip() for w in line.split(',')]\n                answer = '-'.join(MAP[s] for s in scenarios if s in MAP)\n                print(f\" -> {answer}\")\n                s.sendall(f\"{answer}\\n\".encode())\n                round_count += 1\n                break\n\n        time.sleep(0.2)\n        data = recv_until(s, \"What do you do?\", timeout=5)\n        print(data, end='')\n\n    try:\n        s.settimeout(2)\n        remaining = s.recv(4096).decode(errors='ignore')\n        print(remaining)\n    except:\n        pass\n\n    s.close()\n    print(f\"\\n完成 {round_count} 轮\")\n\nif __name__ == \"__main__\":\n    main()\n",[22,185,183],{"__ignoreMap":67},[10,187,188],{},"脚本大概跑了两分钟，最后成功打完 500 轮：",[61,190,193],{"className":191,"code":192,"language":81,"meta":67},[79],"Fantastic work! The flag is HTB{1_wiLl_sT0p_dR0p_4nD_r0Ll_mY_w4Y_oUt!}\n🎀 FLAG FOUND!\n完成 500 轮\n",[22,194,192],{"__ignoreMap":67},[14,196,197],{"id":197},"小结",[10,199,200],{},"这两题都不复杂，但都很适合练一个意识：",[202,203,204,207,210],"ul",{},[30,205,206],{},"面对重复交互，先想能不能脚本化。",[30,208,209],{},"先把规则抽象出来，再去写自动化。",[30,211,212],{},"自动化不只是为了省时间，也能减少手动操作带来的低级失误。",{"title":67,"searchDepth":214,"depth":214,"links":215},4,[216,218,222],{"id":16,"depth":217,"text":17},2,{"id":99,"depth":217,"text":100,"children":219},[220],{"id":107,"depth":221,"text":107},3,{"id":197,"depth":217,"text":197},[224],"Practice","2026-05-27","两道适合练自动化思路的 Misc 小题，重点在把重复交互脚本化。",false,"md",null,{"slots":231},{},true,"\u002Fhackthebox",{"text":235,"minutes":236,"time":237,"words":238},"4 min read",3.13,187800,626,{"title":5,"description":226},{"loc":233},"posts\u002F2026\u002Fhackthebox",[243,244,245],"HTB","Misc","Automation","tech","90FihvNtCW63oSBFg4YsOCIoPnV0gTW3b0Iq8nFGDKs",[249,254],{"title":250,"path":251,"stem":252,"date":253,"type":246,"children":-1},"LitCTF 2026 · 部分题解","\u002Flitctf2026-partial-wp","posts\u002F2026\u002Flitctf2026-partial-wp","2026-05-23",{"title":255,"path":256,"stem":257,"date":258,"type":246,"children":-1},"Obsidian + AI 知识库工作流搭建","\u002Fobsidian-ai-知识库工作流搭建","posts\u002F2026\u002Fobsidian-ai-知识库工作流搭建","2026-05-29",1786294717517]