第二届vecctf-wp

misc

zip-guessing

打开压缩包发现提示password=.......py

进行6位密码爆破,得到密码3a1b6c

解压得到flag

flag{fa8d910600a5467d9d2f433f2bba4c80}

Spiderman

修改高度,发现字符串README:HAHAyoufoundIT

binwalk分离出一个带密码的压缩包

压缩包中含有一个名为README.txt的文件
HAHAyoufoundIT写入README.txt并压缩成zip文件后发现两个README.txt的crc一致

采用明文爆破出密码!g^c*0

解压后得到一张png

stegsolve分析图片,发现0通道中藏有flag

flag{Z1p_1maGE_lSB_1nterestiNG}

crypto

baby rsa

因为两组数据的N相同,尝试共模攻击

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import random
import gmpy2
n,e1 = (18278250860121129714191417969518671565676609370438974713591911937173608105906651505337301762681939894104610580889645217298111784819358890536088923234106589063389221021186473430580352803412280849862104635302801082728967968107748121682339447067731887326087497520544915737621714860811217331095698945949486830528216492874665673677441699322439459330337628648399309373351992766984612437555092804129107438390294123179182945321411199463748963590901018595492869891970965012682196059824464339830536600021131729277503225240822584625293463254992623570796895110736563514265569133338477447460712899749955523316083254492005199917987, 76831)
c1 = 14068017239200053057485191549313171235040341952680207740172042657952395329165768631549600187463451884623632792268314205814005668826033658861436424617991125160661381291003863394279707111450435808077534541510943745285958554921154542813613390731768463465972495263609910077893559813685204864361223917445770159726623708768996447642959844639282015350260298045019617026128700143368357847147111693153254268063490280666808714031170237337721534721243540077707555520501582047389390048200750092516532861791678414405037042484148584170396597267139826760931348123330503380212299827883145622326471261247290265669559897644089748984204
n,e2 = (18278250860121129714191417969518671565676609370438974713591911937173608105906651505337301762681939894104610580889645217298111784819358890536088923234106589063389221021186473430580352803412280849862104635302801082728967968107748121682339447067731887326087497520544915737621714860811217331095698945949486830528216492874665673677441699322439459330337628648399309373351992766984612437555092804129107438390294123179182945321411199463748963590901018595492869891970965012682196059824464339830536600021131729277503225240822584625293463254992623570796895110736563514265569133338477447460712899749955523316083254492005199917987, 65537)
c2 = 17120091052055468753592285548832983539343349280048150965811042901415659935929189229298761316319784219958366772027986939749507760509991462838561325114714990126772560070483939658678703332135866293838146121312972251030190756953273311362066029287803984179301942229948301600814847050270084193184210232673652417884727838290706970298245205101865234726242081382680212621541249662659284218079172180588507736208257188130972936994297239579885142233896240153633237886314935309710560434501987121687537279749951910677771351212584805615709915168729977338949858374823750316083595198620089092891606394712323216539675547753350603350269
s=gmpy2.gcdext(e1,e2)
s1=s[1]
s2=s[2]
if s1<0:
s1=-s1
c1=gmpy2.invert(c1,n)
else:
s2=-s2
c2=gmpy2.invert(c2,n)

c1=gmpy2.powmod(c1,s1,n)
c2=gmpy2.powmod(c2,s2,n)
c=(c1*c2)%n
print(bytes.fromhex(hex(c)[2:]))

flag{423c35691377ea18d35b97b7b6f13590}

web

ezfilter

抓包,在密码处尝试sql注入,回显了mysql的报错

fuzz后发现过滤了空格,可以用/**/代替空格

sqlmap跑一下得到flag
sqlmap -r 1.txt --batch --tamper "space2comment.py" --dump

flag{30b08224ed436c8c690ae623a89466f3}

upload

在源码中发现hint: TUhnd2VEQjRiRzluYVc0dWNHaHc=

两层base64得到0x0x0xlogin.php

通过弱口令爆破进入后台 admin,admin123456

在项目管理处发现一个文件上传点

通过将文件名置空,报错得到上传路径uploaded

fuzz后发现允许上传.htaccess

再上传一个图片马即可

蚁剑连接得到flag

flag{063a5bda0b5a2a5d7b700d989f73902b}

WEB2

查看源码:/index.php?source

关键代码如下

1
2
3
4
5
6
7
if (isset($_POST['session_id'])) {
$query = "SELECT * FROM secrets WHERE session_id = '" . $_POST['session_id'] . "'";
$result = $conn->query($query);
} else {
$query = "SELECT * FROM secrets WHERE session_id = '" . session_id() . "'";
$result = $conn->query($query);
}

where后面为true就行了

payload:1' or '1'='1

EzCas

Apereo Cas反序列化

题目不出网,公开的普通exp没有回显
在github上找到一个带回显的项目

生成payload

构造命令

Mobile

findme

模拟器先安装一下,有个查询按钮

apk文件,使用jadx分析

先全局搜索找到onClick函数,查看点击查询按钮时执行的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class OooO0O0 implements View.OnClickListener {

/* renamed from: OooO0o0 reason: collision with root package name */
public final /* synthetic */ EditText f1853OooO0o0;

public OooO0O0(EditText editText) {
this.f1853OooO0o0 = editText;
}

public void onClick(View v) {
try {
LoginActivity.this.OooOo0o.OooO0Oo(this.f1853OooO0o0.getText().toString());
} catch (Exception e) {
e.printStackTrace();
}
}
}

发现调用了LoginActivity.this.OooOo0o.OooO0Oo,查看函数声明

发现存在数据库

getWritableDatabase函数用来连接数据库
OooO0OO函数用来获取数据库密码
this.f1221OooO0oOooO0OO的对象

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
public void OooO0O0(String t) {
this.OooO0oO = t;
SQLiteDatabase.loadLibs(this.f1222OooO0o0);
this.f1221OooO0o = new OooO0OO(this.f1222OooO0o0);
String OooO0OO2 = OooO0OO();
this.f1220OooO0Oo = OooO0OO2;
this.f1219OooO0OO = this.f1221OooO0o.getWritableDatabase(OooO0OO2);
new OooO0O0();
for (int g = 0; g < 100; g++) {
ContentValues values = new ContentValues();
values.put("flag", OooO0O0.OooO00o("" + g));
values.put("num", Integer.valueOf(g));
this.f1219OooO0OO.insert("test", null, values);
}
}


public void OooO0Oo(String i) {
SQLiteDatabase.loadLibs(this.f1222OooO0o0);
this.f1221OooO0o = new OooO0OO(this.f1222OooO0o0);
String OooO0OO2 = OooO0OO();
this.f1220OooO0Oo = OooO0OO2;
this.f1219OooO0OO = this.f1221OooO0o.getWritableDatabase(OooO0OO2);
Cursor cursor = this.f1219OooO0OO.rawQuery("select * from test where num = '" + i + "'", null);
this.OooO0oo = "";
if (cursor == null || !cursor.moveToFirst()) {
Toast.makeText(this.f1222OooO0o0, this.OooO0oo, 0).show();
cursor.close();
this.f1219OooO0OO.close();
}
do {
this.OooO0oo += cursor.getString(cursor.getColumnIndex("flag")) + "\n";
} while (cursor.moveToNext());
Toast.makeText(this.f1222OooO0o0, this.OooO0oo, 0).show();
cursor.close();
this.f1219OooO0OO.close();
}

通过OooO0OO类的声明获得数据库文件的名称data.db

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class OooO0OO extends SQLiteOpenHelper {
public OooO0OO(Context context) {
super(context, "data.db", null, 1);
}

@Override // net.sqlcipher.database.SQLiteOpenHelper
public void onCreate(SQLiteDatabase sqLiteDatabase) {
sqLiteDatabase.execSQL("create table test(flag text, num text)");
}

@Override // net.sqlcipher.database.SQLiteOpenHelper
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
onCreate(sqLiteDatabase);
}
}

改apk的后缀名然后解压文件,找到data.db文件

使用DB4S打开db文件,发现需要密码

获取OooO0OO函数的代码,发现先对this.OooO0oO中储存的数据进行base64解密
然后将返回值作为参数执行OooO00o.OooO00o函数
并将OooO00o.OooO00o函数的返回值作为参数调用OooO00o

1
2
3
public String OooO0OO() {
return OooO00o(new String(OooO00o.OooO00o(Base64.decode(this.OooO0oO, 0))));
}

this.OooO0oO查找用例,找到获取资源的代码

1
2
3
4
5
6
public String Oooo0o0() {
String flag = getSharedPreferences("secret", 0).getString("flag", null);
Log.i("secret", "读取信息");
Log.i("secret", "flag:" + flag);
return flag;
}

搜索资源secret,获取到加密后的密码mkrPETW43g1796lzN2dtiC5qgsC+ybJIWHR8GEzhsI4=

查看OooO00o.OooO00o函数的代码,发现是aes解密,密钥通过OooO0O0函数获取

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class OooO00o {
public static byte[] OooO00o(byte[] plainText) {
SecretKeySpec secretKey = new SecretKeySpec(OooO0O0("xGP_UACWNcWO]WNP".getBytes(), "123456".getBytes()), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(2, secretKey);
return cipher.doFinal(plainText);
}

public static byte[] OooO0O0(byte[] data, byte[] key) {
if (data == null || data.length == 0 || key == null || key.length == 0) {
return data;
}
byte[] result = new byte[data.length];
for (int i = 0; i < data.length; i++) {
result[i] = (byte) ((data[i] ^ key[i % key.length]) ^ (i & 255));
}
return result;
}
}

通过脚本得到密钥Itahdrtbu^hr`hsk

1
2
3
4
5
6
7
a=b'xGP_UACWNcWO]WNP'
b=b'123456'
e=''
for i in range(len(a)):
e+=chr(a[i]^b[i%len(b)]^i)

print(e)

aes解密得到OooO00o函数的参数2>=9:92m;<in=?3n

f1218OooO0O0变量的所有成员与参数的每一位异或FECanfOI()*&<MNCXZPKL

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
static {
Charset forName = Charset.forName("UTF-8");
OooO00o = forName;
f1218OooO0O0 = "FECanfOI()*&<MNCXZPKL".getBytes(forName);
}

public static String OooO00o(String enc) {
byte[] b = enc.getBytes(OooO00o);
int size = b.length;
for (int i = 0; i < size; i++) {
for (byte keyBytes0 : f1218OooO0O0) {
b[i] = (byte) (b[i] ^ keyBytes0);
}
}
return new String(b);
}

通过脚本解出数据库的密码9562129f07be648e

1
2
3
4
5
6
7
8
9
key=b"FECanfOI()*&<MNCXZPKL"
data="2>=9:92m;<in=?3n"
flag=''
for i in data:
c=i
for j in key:
c=c^j
flag+=chr(c)
print(flag)

进入数据库后发现表test中有一条特别的数据(与其他数据长度不一样),fee0b212f413f8a0

根据长度猜测flag是密码加最后一条数据

flag{9562129f07be648efee0b212f413f8a0}


第二届vecctf-wp
https://www.dr0n.top/posts/e6acd4f1/
作者
dr0n
发布于
2022年5月21日
更新于
2024年3月22日
许可协议