whctf-writeup-all


地址>>请猛戳<<

Web题

0x01. 信息

打开是一个代码下载链接,下载下来是wireshark抓的cap包,打开包分析发现两个http的包,get请求下载了zip的压缩包,利用wireshark导出zip包-File-Export Objects-HTTP。发现需要密码打开,官方提示华科官网,解压密码www.hust.edu.cn,flag在flag3.docx中

0x02. 窃取

测试地址存在union注入,利用sqlmap在wh_ct4_hgduyingjkhjhjg库中发现flag的提示flag is nothere,but I can tell you the flag is xor user's password.,那么到web_sqli库中,将user1和user2的password异或后解密,得到flag:hust

0x03. 忘了账户和密码

username: ' union select 1,2,3-- - , 三列

password: 任意

0x04. find

右键源代码,发现

1
css/[adwxhyz]{2}ctf[0-9]{7}.css"

前两位字符,后7位数字的正则,大胆猜测前两位是wh,后7位直到官方给了提示(),一个qq号,搜索qq的资料,发现其为1999年5月12的生日,尝试css/whctf1999512.css成功,flag就在里面whctf{Wh3tF_H@rd}

0x05. beat it

打开又是一个pcap的包下载,三个ipv4的协议包,尝试重组将中间的丢弃,把data组合hex两次转字符串,得到flagwhctf{000 here it is the flag 000}

0x06. 密码忘了怎么办?

登录口sql注入,还是union的,注入发现user表有flag字段,将12,13,14,15行的flag字段组合
whctf{hello$$##itisme&---&&&}

0x07. 看图说话

给的提示里ctf页面脚本,猜测存在ctf.php,打开是302跳转,返回包里有张图片链接
templates/images/xxx/ctf.jpg
,将图片下载下载利用notepad++打开,flag在最后whctf{today@@isnot09#$tomorrow}

CRYPTO

0x01 我叫李二狗(一)
直接base64解密,然后李二狗是近视,将l换成1,x换成1,md5解密

0x02 李二狗的梦中情人
将隐藏在图片末尾的链接中的图片提取出来,然后convert转换成png格式,diff下得到一个二维码,二维码黑白反转下,得到正确的二维码,扫一下,bingo

0x03 我叫李二狗(二)
给了两个RSA加密,由于其弱密钥,N太小,直接分解大数,破解

0x04 李二狗的LOL战歌
听音乐,感觉音频右声道像电报,然后翻译成摩斯编码,直接得到13位字符,然后用ROT13编码转换下,得到flag

Reverse

0x01 直接爆破

相关代码

1
#include "stdafx.h"
#include "stdio.h"
#include <string.h>

int main(int argc, char* argv[])
{
  __int64 seeda=1;
  __int64 lenKey=38;
  __int64 count;
  __int64 k;
  __int64 j;


  char key[]="Just try your best and enjoy yourself!";

  __int64 result[]={157,2400,2215,1971,1732,1527,2053,1878,1988,787,1584,1856,1717,2187,1971,34,1732,1259,1669,1726,1946,1967,1369};
  for ( count = 0; count < 23; ++count )
  {
    k = key[seeda];
	for ( j = 0; j < 512; ++j )
	{
		//char s[1];
	//	sprintf(s, "%x", j);
		if(strchr(key,j)!=0)
		{
			if(result[count] == (0x10 * j + k) % 0x9C4)
			{
				printf("flag %I64d count-InStr %c\n",count,j);
				//printf("%c",j);
				break;
			}
		}
		else
		{
			if(result[count] == (j ^ (k << seeda)) % 0x9C4)
			{
				printf("flag %I64d count-OutStr %c\n",count,j);
				break;
				//printf("%c",j);
			}
		}

	}
	seeda = (seeda + 5) % lenKey;
  }
 return 0;
}

flag whctf{you_are_the_best}

revserse

0x03. 定位坐标

安装Crackme_3.apk运行,发现与之前阿里的比赛题很像,任意输入后查看Log日志,打印出了table信息和pw:亡丸凡亡丸凡义义凡么么门凡广义凡之,利用这两个信息,调用apk中的解密函数aliCodeToBytes(String paramString1, String paramString2),即可直接打印出结果:30-30-55-114-25-6,加上whctf{}就是flag了。

0x06 我讨厌数学
拿到题目首先用IDA得到反汇编代码,通过一系列的分析得出是一个纯粹的矩阵运算,矩阵为6×6的矩阵,其中有9个1,其余的26个为我们输入的FLAG。该算法就是A×AT=P(P在程序中硬编码的,可以直接得到),然后反求A矩阵,P矩阵为:
12027h, 0F296h, 0BF0Eh, 0D84Ch, 91D8h, 297h,
0F296h, 0D830h, 0A326h, 0B010h, 7627h, 230h,
0BF0Eh, 0A326h, 8FEBh, 879Dh, 70C3h, 1BDh,
0D84Ch, 0B010h, 879Dh, 0B00Dh, 6E4Fh, 1F7h,
91D8h, 7627h, 70C3h, 6E4Fh, 9BDCh, 15Ch
297h, 230h, 1BDh, 1F7h, 15Ch, 6
然后由“6”可得A中的最后一行全为“1”,再把whctf{xxx}格式转成10进制带进去可得第一行就为“whctf{”,并且根据最终的P矩阵验证正确。然后还有3个1的位置不确定,根据FLAG猜想它们就放在第五行的后三个,然后计算第五行的前两个数字为“114”,“104”。然后根据第一行和第五行的乘积的和来确定它们两个的位置就为“114”,“104”。字母为“t”,”h”。那么现在就还有三行不知道了,所以就爆破。
爆破的关键是利用已知的三行去求未知的三行,下面两行来求这三行的可能值,于是写了个脚本试了一下发现求出的结果实在太多了,想了想之后就加上第一行来验证。下面为爆破的java代码:

1
public class whctf{
	public static void main(String[] args ){
		for(int i1=32; i1<129; i1++){
			System.out.printf("new i1 is: %d\n",i1);
			for(int i2=32; i2<129; i2++){
				for(int i3=32; i3<129; i3++){
					for(int i4=32; i4<129; i4++){
						for(int i5=32; i5<129; i5++){
							for(int i6=32; i6<129; i6++){
								int i7=i1+i2+i3+i4+i5+i6;
								int i8=i1*116+i2*104+i3*125+i4+i5+i6;
								int i9=i1*119+i2*104+i3*99+i4*116+i5*102+i6*123;
								if(i7==560 && i8==30247 && i9==62102){
									System.out.printf("THE TWO LINE i1,i2,i3,i4,i5,i6: %d,%d,%d,%d,%d,%d\n",i1,i2,i3,i4,i5,i6);
								}
								if(i7==445 && i8==28867 && i9==48910){
									System.out.printf("THE THREE LINE i1,i2,i3,i4,i5,i6: %d,%d,%d,%d,%d,%d\n",i1,i2,i3,i4,i5,i6);
								}
								if(i7==503 && i8==28239 && i9==55372){
									System.out.printf("THE FOUR LINE i1,i2,i3,i4,i5,i6: %d,%d,%d,%d,%d,%d\n",i1,i2,i3,i4,i5,i6);
								}
							}
						}
					}
				}
			}
		}

	}
}

但是跑了半小时之后发现解出的结果每一行都有很多解,于是就想着人工过滤这些字符串,判断每一组的前三个字符是否可能为FLAG,于是就每一组列出一个字符串,之后发现一个字符串可能是FLAG,前三个字符为“3_g”,于是就把这组解的所有字符串列出来,得到“3_g00d”字符串,就是我们A矩阵的第三行了,然后同样的原理来过滤第四行和第二行。就得到了FLAG为:whctf{Y0u_ar3_g00d_a7_m4th}