动手实践初步入门-学习单

1:Basic-Linux Labs

题目链接:https://buuoj.cn/challenges#Linux%20Labs

这道题目,大家需要学会一些Linux的基本命令,并使用适合的链接工具连接靶场进行攻防测试

题目提示:ssh 用户名:root 密码:123456 地址和端口为动态分配的

看到提示就发现它给了我们一个root最高权限用户的操作用户,因此猜测答案就在某个目录下

因此启动靶场后使用FinalShell连接服务器

FinalShell使用教程

  • 打开FinalShell
  • 创建连接
  • 输入主机名和端口号,以及账号密码
  • 双击连接

掌握基本命令

  • 根据主机名称提示,发现提示我们out
  • 我们尝试返回上级目录,使用命令cd ../
  • 使用ls命令列出当前目录下的所有文件
  • 发现flag.txt文件
  • 使用cat flag.txt输出文件内容

至此,成功获得flag,提交成功!

2:Crypto-一眼就解密

题目链接:https://buuoj.cn/challenges#%E4%B8%80%E7%9C%BC%E5%B0%B1%E8%A7%A3%E5%AF%86

打开题目发现提示如下:

下面的字符串解密后便能获得flag:ZmxhZ3tUSEVfRkxBR19PRl9USElTX1NUUklOR30= 注意:得到的 flag 请包上 flag{} 提交

观察以下内容ZmxhZ3tUSEVfRkxBR19PRl9USElTX1NUUklOR30=发现应该是base加密族内容,通过特征推测是base64加密,因此找到有关解密工具,例如:https://www.qqxiuzi.cn/bianma/base.php

解密后发现flag为:flag{THE_FLAG_OF_THIS_STRING}

知识点:base加密族

编码方式 特征
base16 用于编码的字符只有:1-9,A-F ,只有简单的15个字符
base32 编码字符有了明显改变,由base16的类型转变为了A-Z,2-7
base64 最完善,在base32的基础上,增加了"a-z,0,1,8,9,+,/",以及特殊填充字符"="

Base-64编码将一个8位子节序列拆散为6位的片段,并为每个6位的片短分配一个字符,这个字符是Base-64字母表中的64个字符之一。

3:Misc-金三胖

题目链接:https://buuoj.cn/challenges#%E9%87%91%E4%B8%89%E8%83%96

大家可以自行完成签到题目

题目没有给出任何提示,下载文件后解压发现一张图片,名为aaa.gif

打开图片发现中间快速闪烁有不正常的帧

因此我们把它逐帧分析,可以拖入stegsolve完成

选中frame browser,发现在第21帧、第51帧、第79帧有flag

得到flag

4:Pwn-test_your_nc

题目链接:https://buuoj.cn/challenges#test_your_nc

知识点:nc命令

nc命令使用help:

nc [-hlnruz][-g<网关...>][-G<指向器数目>][-i<延迟秒数>][-o<输出文件>][-p<通信端口>][-s<来源位址>][-v...][-w<超时秒数>][主机名称][通信端口...]

参数说明:

  • -g<网关> 设置路由器跃程通信网关,最多可设置8个。
  • -G<指向器数目> 设置来源路由指向器,其数值为4的倍数。
  • -h 在线帮助。
  • -i<延迟秒数> 设置时间间隔,以便传送信息及扫描通信端口。
  • -l 使用监听模式,管控传入的资料。
  • -n 直接使用IP地址,而不通过域名服务器。
  • -o<输出文件> 指定文件名称,把往来传输的数据以16进制字码倾倒成该文件保存。
  • -p<通信端口> 设置本地主机使用的通信端口。
  • -r 乱数指定本地与远端主机的通信端口。
  • -s<来源位址> 设置本地主机送出数据包的IP地址。
  • -u 使用UDP传输协议。
  • -v 显示指令执行过程。
  • -w<超时秒数> 设置等待连线的时间。
  • -z 使用0输入/输出模式,只在扫描通信端口时使用。

Linux nc命令的实例

TCP端口扫描

nc -v -z -w2 192.168.0.1 1-100

UDP端口扫描

nc -u -z -w2 192.168.0.1 1-1000

扫描指定端口

nc -nvv 192.168.0.1 80

监听入站连接

nc -l 8080

连接远程系统

nc 192.168.0.1 80

连接UDP端口

nc -l -u 1234

将nc作为代理

发往我们服务器8080端口的连接都会自动转发192.168.1.200上的80端口

nc -l 8080 | nc 192.168.1.200 80

使用nc拷贝文件

nc还能用来在系统间拷贝文件,虽然这么做并不推荐,因为绝大多数系统默认都安装了ssh/scp。不过如果你恰好遇见个没有ssh/scp的系统的话,你可以用nc来作最后的努力。

要接受数据的机器上启动nc并让它进入监听模式:

nc -l 8080 > file.txt

现在去要被拷贝数据的机器上运行下面命令:

nc 192.168.1.100 8080 --send-only < data.txt

通过nc创建后门

nc -l 10000 -e /bin/bash

-e标志将一个bash与端口10000相连。现在客户端只要连接到服务器上的10000端口就能通过bash获取我们系统的完整访问权限:

nc 192.168.1.100 10000

通过nc进行端口转发

所有连接到80端口连接都会转发到8080端口

nc -u -l 80 -c 'ncat -u -l 8080'

解题思路

题目提示使用nc命令,则猜测只需要连接远程系统即可像Basic-Linux Labs一样直接获取Flag内容因此打开WSL下的Kali Linux,输入

nc [靶场IP] [靶场端口]

例如实践中靶场是node5.buuoj.cn:26335

则输入

nc node5.buuoj.cn 26335

然后发现在当前目录下就存在flag文件,类似于Basic-Linux Labs直接通过cat命令显示

5:Reverse-easyre

题目链接:https://buuoj.cn/challenges#easyre

下载解压得到easyre.exe文件,运行结束发现告诉我们不能得到flag,由于题目简单,我们尝试使用静态逆向工具IDA Pro

使用IDA Pro打开文件逆向分析后发现flag在一个变量中,直接复制提交即可

6:Web-[极客大挑战 2019]EasySQL

题目链接:https://buuoj.cn/challenges#[%E6%9E%81%E5%AE%A2%E5%A4%A7%E6%8C%91%E6%88%98%202019]EasySQL

题目分析

这是我们第一次接触一个网页来攻击,打开网页发现有两个地方让我们输入用户名和密码,因此,我们认为突破口在这里

尝试使用弱密码攻击admin123,提示NO,Wrong username password!!!但是请求地址变为

check.php?username=admin&password=123

又因为题目为EasySQL,所以尝试使用SQL注入攻击,payload如下内容

?username=1' and 1=1 &password=1' and 1=1

来测试有没有数据库注入漏洞,发现回显

You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' and password='1' and 1=1'' at line 1

知识点:SQL注入原理及如何判断闭合符

造成SQL注入的原因:
在没有对用户的输入进行过滤、检测的情况下,就把用户输入数据,带入到数据库中执行SQL语句。

利用SQL注入:
由于系统没有对输入的数据进行过滤、检测,就带入到数据库中执行SQL语句,那么当用户输入一条恶意的数据,使其与原SQL语句拼接、重组得到一条恶意的SQL语句,当数据库执行这条恶意的SQL语句时,就会把数据库中的信息暴露出来,从而泄露信息。

一般的代码:

id=id=_GET[‘id’];
sql=“SELECT \* FROM name WHERE id=’id’ LIMIT 0,1”;

我们可以看到,用户输入的id是被带到sql语句中进行拼接,然后执行的,而且,这个id两边是被’ ‘(两个单引号)给闭合起来的,所以在这个代码里**’(单引号)就是闭合符**

由此,若是我们想进行SQL注入,那么就可以通过给定id一些恶意的数据,让这些恶意的数据原SQL语句结合在一起,构成一个的、恶意的SQL语句,让这个恶意的SQL语句执行成功,从而达到SQL注入的目的。

防止SQL注入的措施

  1. SQL语句的执行代码使用预编译 PreparedStatement
  2. 确定每个数据的类型,比如是数字,数据库则必须使用int类型来存储
  3. 限制传入数据的长度,这能够在一定程度上防止sql注入
  4. 严格限制用户使用数据库的权限,能够在一定程度上减少sql注入的危害
  5. 避免直接响应一些 sql 语句执行异常的信息
  6. 过滤参数中含有的一些数据库关键词

因此我们发现这个网站的闭合方式为单引号

知识点:MySQL中单引号,双引号和反引号的区别

单引号

一般应使用英文单引号,如果字符串内需要包含单引号时,除了使用转义的办法外,我们可以选用一对双引号来包括字符串,这样字符串内的单引号被视作普通字符,无需特殊处理

例如 Johnson's mother

select "Johnson's mother",'Johnson''s mother','Johnson\'s mother';

双引号

与单引号对应,使用英文双引号引用的字符串内需要包含双引号时,除了使用转义的办法外,我们可以用一对单引号来包括字符串,这样字符串内的双引号被视作普通字符,无需特殊处理。

例如 He said: "Go away"

select 'He said: "Go away"' ,"He said: ""Go away""" ,"He said: \"Go away\"" ;

反引号

反引号,一般在ESC键的下方。它是为了区分MYSQL的保留字普通字符而引入的符号。

MySQL里使用一对反勾号“ ` ”将识别符括起来,一般情况下可以不用,单是如果识别符出现关键字冲突或标识符的写法可能产生歧义的情况下就必须使用。例如:

create table t1 (id int primary key ,desc varchar(10));   -- 这句会报错
create table t1 (id int primary key,`desc` varchar(10));  -- 这句客成功运行

举个例子:

在test表中,有个select字段,如果不用反引号,MYSQL将把select视为保留字而导致出错,所以,有MYSQL保留字作为字段的,必须加上反引号来区分。

SELECT `select` FROM `test` WHERE select='字段值'

另外:建表的时候一般都会将表名,库名都加上反引号来保证语句的执行度。反引号`,数字1左边的符号。

保留字不能用于表名,比如desc,此时需要加入反引号来区别,但使用表名时可忽略反引号

create table desc   -- 报错
create table `desc` -- 成功
create table `test` -- 成功
drop table test     -- 成功

保留字不能用于字段名,比如desc,此时也需要加入反引号,并且insert等使用时要加上反引号。

create table `test`(`desc` varchar(255))  -- 成功
insert into test(desc) values('fxf')       -- 失败
insert into test(`desc`) values('fxf')     -- 成功

使用Sql注入解题

一般来说,有账号密码登陆的题,在判断完闭合方式后,可以尝试先用万能账号密码解题

使用万能账号a' or true #登录,发现成功进入获取flag!

知识点:万能账号密码原理剖析

一个网络安全意识淡薄的网站,其登录功能的SQL语句大概是下面这个样子

select \* from user where username='user' and password='pass'
万能账号

万能账号并不是一个真正意义上的账号,它是一种【拥有不同变体的格式】

需要注意的是,以下所有万能账号中的 a 可以是自定义的数字或字母,比如 1,2,3,b,c,d

【数值型万能账号】

a or true #
a or 1 #
a or 1=1 #
a or true -- a
a or 1 -- a
a or 1=1 -- a

【单引号字符型万能密码】

a' or true #
a' or 1 #
a' or 1=1 #
a' or true --a
a' or 1 -- a
a' or 1=1 -- a

【双引号字符型万能密码】

a" or true #
a" or 1 #
a" or 1=1 #
a" or true -- a
a" or 1 -- a
a" or 1=1 -- a
万能账号原理

当我们在登录界面输入 【万能账号】比如 a’ or true # 以后,后端会将我们输入的参数拼接到SQL中,然后去数据库中查询账号和密码,SQL语句大概是下面这样

select \* from user where username='a' or true #' and password='pass'

由于 # 在SQL中是注释符,注释符后面的内容不起作用,所以真正执行的SQL语句大概是下面这样

select \* from user where username='a' or true

or true 会使SQL语句恒成立,从而查询出数据库中的所有账号和密码,从而使我们成功登录

注释符

除了 # 以外, -- 也是SQL中的注释符,但SQL的语法格式规定--和后面的注释内容必须间隔一个空格,所以这需要使用 a' or 1 -- a 而不是 a' or 1 -- 其原理和 a’ or 1 # 大同小异,拼接到SQL中大概是下面这样

select \* from user where username='a' or true -- a' and password='pass'

注释后面的内容不生效,真正执行的SQL大概是下面这样

select \* from user where username='a' or true

SQL语句恒成立,从而登录成功

换句话来说,a' or true -- a经过SQL的转化后,结果等价于 a’ or true #

比较运算符

SQL中规定,非布尔类型的数据参与比较运算时,会转化为布尔类型再参与运算。比如 or 1 或者 or 1=1 ,会转化为布尔类型true 再参与 or 的比较运算,也就是变成 or true ,同样能使条件恒成立,从而登录成功

简单来讲就是:a' or 1 # 或者 a' or 1=1 # 等价于 a' or true #

万能密码

万能密码并不是一个真正意义上的密码,而是一个【拥有不同变体的格式】

需要注意的是:万能密码中的 admin,必须是真实的用户名

【数值型万能密码】

admin #
admin -- a

【单引号字符串型万能密码】

admin' #
admin' -- a

【双引号字符串型万能密码】

admin” #
admin" -- a
万能密码原理

当我们在登录界面输入 【万能密码】 比如 admin’ # 以后,后端会将我们输入的参数拼接到SQL中,大概是下面这样

select \* from user where username='admin' #' and password='pass'

由于 # 在SQL中是注释符,注释符后面的内容不起作用,所以真正执行的SQL大概是下面这样

select \* from user where username='admin'

SQL只会在数据库中查询用户名,而不是同时查询用户名密码,这就意味着,只要用户名正确,就可以登录成功